diff --git a/404.html b/404.html index 3e581a815..c156cc25e 100644 --- a/404.html +++ b/404.html @@ -15,7 +15,7 @@ - + @@ -43,7 +43,7 @@ GitHub (opens new window) GitHub - (opens new window)

404 - Not Found

That's a Four-Oh-Four.
+ (opens new window)

404 - Not Found

How did we get here?
Take me home.
- + diff --git a/assets/js/11.572b67e6.js b/assets/js/11.cdd16637.js similarity index 99% rename from assets/js/11.572b67e6.js rename to assets/js/11.cdd16637.js index 487df1ba8..a6125eb31 100644 --- a/assets/js/11.572b67e6.js +++ b/assets/js/11.cdd16637.js @@ -1 +1 @@ -(window.webpackJsonp=window.webpackJsonp||[]).push([[11],{279:function(A,I){A.exports="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAIIAAACCCAYAAACKAxD9AAAAAXNSR0IArs4c6QAAABplWElmTU0AKgAAAAgAAQESAAMAAAABAAEAAAAAAAATwHXnAAAACXBIWXMAAA7EAAAOxAGVKw4bAAAFdWlUWHRYTUw6Y29tLmFkb2JlLnhtcAAAAAAAPHg6eG1wbWV0YSB4bWxuczp4PSJhZG9iZTpuczptZXRhLyIgeDp4bXB0az0iWE1QIENvcmUgNi4wLjAiPgogICA8cmRmOlJERiB4bWxuczpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiPgogICAgICA8cmRmOkRlc2NyaXB0aW9uIHJkZjphYm91dD0iIgogICAgICAgICAgICB4bWxuczp0aWZmPSJodHRwOi8vbnMuYWRvYmUuY29tL3RpZmYvMS4wLyIKICAgICAgICAgICAgeG1sbnM6ZGM9Imh0dHA6Ly9wdXJsLm9yZy9kYy9lbGVtZW50cy8xLjEvIgogICAgICAgICAgICB4bWxuczpBdHRyaWI9Imh0dHA6Ly9ucy5hdHRyaWJ1dGlvbi5jb20vYWRzLzEuMC8iCiAgICAgICAgICAgIHhtbG5zOnhtcD0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wLyI+CiAgICAgICAgIDx0aWZmOllSZXNvbHV0aW9uPjk2PC90aWZmOllSZXNvbHV0aW9uPgogICAgICAgICA8dGlmZjpYUmVzb2x1dGlvbj45NjwvdGlmZjpYUmVzb2x1dGlvbj4KICAgICAgICAgPHRpZmY6T3JpZW50YXRpb24+MTwvdGlmZjpPcmllbnRhdGlvbj4KICAgICAgICAgPGRjOmNyZWF0b3I+CiAgICAgICAgICAgIDxyZGY6U2VxPgogICAgICAgICAgICAgICA8cmRmOmxpPkhhbGV5IEJlcmtvZTwvcmRmOmxpPgogICAgICAgICAgICA8L3JkZjpTZXE+CiAgICAgICAgIDwvZGM6Y3JlYXRvcj4KICAgICAgICAgPGRjOnRpdGxlPgogICAgICAgICAgICA8cmRmOkFsdD4KICAgICAgICAgICAgICAgPHJkZjpsaSB4bWw6bGFuZz0ieC1kZWZhdWx0Ij5VbnRpdGxlZCBkZXNpZ24gLSAxPC9yZGY6bGk+CiAgICAgICAgICAgIDwvcmRmOkFsdD4KICAgICAgICAgPC9kYzp0aXRsZT4KICAgICAgICAgPEF0dHJpYjpBZHM+CiAgICAgICAgICAgIDxyZGY6U2VxPgogICAgICAgICAgICAgICA8cmRmOmxpIHJkZjpwYXJzZVR5cGU9IlJlc291cmNlIj4KICAgICAgICAgICAgICAgICAgPEF0dHJpYjpUb3VjaFR5cGU+MjwvQXR0cmliOlRvdWNoVHlwZT4KICAgICAgICAgICAgICAgICAgPEF0dHJpYjpDcmVhdGVkPjIwMjQtMDQtMjM8L0F0dHJpYjpDcmVhdGVkPgogICAgICAgICAgICAgICAgICA8QXR0cmliOkV4dElkPmZmOGY1MDgxLTQ2YjEtNGVmYy1iZWUyLWY0NjIzZjA5Njc2NDwvQXR0cmliOkV4dElkPgogICAgICAgICAgICAgICAgICA8QXR0cmliOkZiSWQ+NTI1MjY1OTE0MTc5NTgwPC9BdHRyaWI6RmJJZD4KICAgICAgICAgICAgICAgPC9yZGY6bGk+CiAgICAgICAgICAgIDwvcmRmOlNlcT4KICAgICAgICAgPC9BdHRyaWI6QWRzPgogICAgICAgICA8eG1wOkNyZWF0b3JUb29sPkNhbnZhIChSZW5kZXJlcik8L3htcDpDcmVhdG9yVG9vbD4KICAgICAgPC9yZGY6RGVzY3JpcHRpb24+CiAgIDwvcmRmOlJERj4KPC94OnhtcG1ldGE+CsmoN4cAAAwZSURBVHgB7Z1pqFZVF8e3ppbmUGZaaE45pEhJihma84QhpIRanzREUXP4YKSIKZSUoIGEA44oigNqmTaoDZZSlJbmPM9j5Zxlme7Wb73uw/G+5vtyn+e5zzmwFtx7ztnTWvu//nvttbdazpkYAoaAIWAIGAKGgCFgCBgChoAhYAgYAoaAIWAIGAKGgCFgCBgChoAhYAgYAoaAIWAIGAKGgCFgCBgChoAhYAgYAoaAIWAIGAKGgCFgCBgChoAhYAgYAoaAIWAIGAKGgCFgCBgChoAhkEQEiolRJZNomNlkCBgCeUCAiDA2D3pNZcIQgAg+YTaZOXlAoITovJ4HvaYyYQhYREiYQ/JlTvF8KTa9yULAiJAsf+TNGiNC3qBPlmIjQrL8kTdrjAh5gz5Zio0IyfJH3qwxIuQN+mQpNiIkyx95s8aIkDfok6XYiJAsf+TNGiNC3qBPlmIjQrL8kTdrjAh5gz5Zio0IyfJH3qwxIuQN+mQpNiIkyx95s8aIkDfok6U4b0QoWbKkK1aMvyBlkgQEipQIwfFVqlRx169fd957V7x4kZqQBMwTaUOReQES4PjatWu7s2fPurp167rq1au7mzdvWmRICDX46+xF8vPEE0+ontdff93Pnz9f3ytVqlQkuotqjinWk3sS3Hvvvf7xxx9Xh0+YMMFfvnzZDx48WL9lmzAiFNFC/B8kzQ0RZCtQBz/00EO+cuXK+j5v3jwvuYHftGmTfterV89IkAwSeP6BS9Yl5APVqlVzJ06c0PE3bNigieGOHTvcihUrtOzSpUt31V2qVCn3999/ax5RsCF1Emm0joTzr7/+cn/++WfUjDraUEf5tWvXtA7bKC/YluSVfKVEiRKudOnSms/QgfY3btxwv//+e9S/TJkyUZL7xx9/qI1UBpt4pw915EVBGIu+COPF6+h73333aR12XL169bZ6Tlm0Bw+E+fGOnmxJVlelTFbHC1uBGOm3b9/uP/roI//aa6/5H3/8UeuFJHfVKw6M6sOYjMWPgBLVhTKeAqaW32m7CXXx9rzHx/63NvF2dxpbyHPbOEHHI4884uPziOdDDz/8cDSHeJvQN66nYL0QNeqL7tAnk2dWIwKMh7WSFLo9e/a4Dh06uBkzZrjNmze7nj17OqLC559/LvY69+CDDzpYLpN0Fy5ccOfPn9fVR3/GYVXUqVNH686dOxfV0YfV++yzz7rHHnvMnT592glo7ueff3Zff/21E7D1VCLbjmvSpImOf+rUKffll1/qamfsWrVquf3796ut6IvrefLJJ9V+VvNvv/3mxGH6/Pjjj9VeTjydOnVyFSpU0HkwztatW/WdE1GjRo10ZTOndevWaTm/HnjgAffrr7+6Ll26aNmnn36qZRcvXtS5YlPjxo3d/fffr1ig75577lEbwSKcsIiw2EZ7Isju3bu1XTYiQ1YYJbPTcRo0aKDPoUOH+qNHj/qJEyf+X+OXL18+aheiBVFkxIgRWh5WU9WqVfX73Xff9Vu2bPFHjhzx27Zt89OmTYv6v/32237nzp3+m2++8T/99JOfPn261gkJfLNmzfxnn33m69ev7wVMLReH+SFDhuj7qFGjNIehH2N/9913/pNPPonGXrhwod+1a5eOjf7Ro0dHdR9++KHft2+fF0KqTXyDC7p4zpo1S+2i/8yZM7VMnK/P5cuXK170xfalS5dqecOGDfU5Z86caB7g8+233/ru3btrXbly5fQZfFDIZ3aSRU4GYcLvvfeeF+b6YcOGqYGy4vzUqVM9wLz//vv+gw8+0J8FCxb41atX+5EjR2o7iRL6FPbrE1DGjBmj74TSRx99VLcFWQlaxoR/+OEH36pVK/0O2xEgjR07NmpDO5JWns8995w6MQ7Wxo0bI8KhgzpskggWjQGJKD906JB/6qmnonLKJBLot0Q7z6mIMuyVfMi/8sor+o1+Wb3++eef9127dvUSMT0OrFmzptavX7/eL168WN+feeYZf/DgQd+xY0f9ZrwlS5YokXhnEXz11VdaV6NGjagNdYX9ycrWQIgiGdu7d68T5rqnn37akSgGOXDggCMxJAkjhBGOCfd9+/bVpOidd97RpiERCv1oS1hESOLYBhC2B8ImdbQhnCIhASRxDG3ZPo4fP676aHPlyhW1Y9KkSbrFEGYJ2zwRbETC+LwT8gn1/MjR140fP95JNHBCOEcIJ9FDsIWtA/nll1/UHiGAfgsxnURIJ1FOvwcNGuQkWroBAwboN32DCEEUT4kujv5gBTZCdNevXz/34osvOrYWJN4v9C/MM2MiAAJ7NsIe3aJFCyer3i1atEhBxVk4XrYKd/LkychGWQFOQroT1mtZxYoVdW+MGsgL+zkEQNCB81atWuXoS14QcozgCG1461fIznHcG2+84WTVuy+++EKJB3Fk1emY2Ee+AnmQQLyQq1CG7lD/5ptvqiMkCrnevXvrfGV7oJnai6OYE2MiYIGQhzC2bHWatzCmRAOt4xffLVu2dGvXrnVgQf+XX37ZyTanbehLnkCuJVFJ25J/9e/fX3MlyJ6JZHzFzDEGVr7wwgvq6Llz5+qkWFHh2MZRScKp2tm8eXNN1DgeAZjcMWiCF5JFGuEEhMmHlU2iRYIYwGPlkTjhoJUrV2r7cPyCPCSICJFIQnGkn0h15swZBbJt27auffv2jpXHKiwogRSUYy8ie7l76aWXXOvWrZ3s465du3ZaHn4RNbCZ6Pjqq686oiECHjgSZ7NYmAdED4LN33//vSai3bp1c7Nnz3Y9evQI1dpfchWtb9OmjZOtQpNaGrAgMpWMI0IItbLvO37uJn369HHjxo1zTGjgwIEacgEthOVAAEBDcCyromnTpnpu5kQQ2rKyOBUQ+tFLmJb9WftBGuohGmMRPcI9ADoI/xATEpF1ly1bNroX4BSD4JgQaUJU4jTEuLRn3myB9A+CQ5jbW2+9FYqiExRjUSdHaK2Ta3bXuXPnqB19w9YIJkTPgAeNqA9Rhu84ceOEoq4wkjERUIpzCMUAjgDc4cOH1RGTJ092HOUggCROTpJGR04gp4vbQNSOt35xpEJwMEcqog5jSrave/OtZrqi2CtxTFgVAN6rVy8NqRAHkDjGQRTk2LFjuqoJryGnWLZsmZP7Da1nP0ZYneESKlx8BcBxGPPlODx8+PDoGEhkCpGIrYD3ENGog6AIZCNSBP2UcckGuYJw/MauIGvWrImIQhlbXdAVbA5tC/ssdKYpCu/YN2TRnBI4GZDlcpQMx53wh0//1p/y+HGyYDvZQ++o9259GENI8l/9xKFRWTiNxMuEZFovRIzaxe3htFTQXslBbmsrdw7RN3VBD/3QFbebdyF11B6bOV0EndgTv1CK9w1tCvNkk0JJ1oTVC9O5WBES6GUMly/sazCXP37mEobVFQ99cQNCHRGGlcdeHcrIC8hJWO2ER8agjj2cSyWE6EDfENIpI9SSkLEayUvIMYJ+2rLqiQBBD3oZn3ahjG1G7jGibYTIwIoPmTvjEh1Z2aFPeHIxxVYUogtRjC2K0wVCPeORYyDgyGkmnEJIILE31NMfG5lz0KEdM/gVsU3GyPg9nOW5PEG4rAnjhvsBMTwqC3X2zBz7DDHMngHxkCf7l14aYRzhMPwJpJEge3hn6PiCizF7hgVnS2Lop0yZooq4xo3vaVk2vuBk7LvwUT17RMDJso96yQPUIXK0M8cU3jFFil3Wk0UhgwoJWEh0Qpk9k4tATohAth4uR5I7dbMsjkBOiBBXYO/pQOA/96npsNWszCECRoQcgpumoY0IafJWDm01IuQQ3DQNbURIk7dyaKsRIYfgpmloI0KavJVDW40IOQQ3TUMbEdLkrRzaakTIIbhpGtqIkCZv5dBWI0IOwU3T0EaENHkrh7YaEXIIbpqGNiKkyVs5tNWIkENw0zS0ESFN3sqhrfyTN/ufhOcQ4LQMbX9VLS2eyrGdEGFsjnXY8IaAIZAWBIgImf9XFtIyW7PTEDAEDAFDwBAwBAwBQ8AQMAQMAUPAEDAEDAFDwBAwBAwBQ8AQMAQMAUPAEDAEDAFDwBAwBAwBQ8AQMAQMAUPAEDAEDAFDwBAwBAwBQ8AQMAQMAUPAEDAEDAFDwBAwBAwBQ8AQMAQMAUMgZQj8A1nFO753Z6pvAAAAAElFTkSuQmCC"},363:function(A,I,g){A.exports=g.p+"assets/img/bitkit.6eacba41.svg"},364:function(A,I,g){A.exports=g.p+"assets/img/mutiny.5939a956.svg"},365:function(A,I,g){A.exports=g.p+"assets/img/cashapp.db7a02f3.svg"},366:function(A,I,g){A.exports=g.p+"assets/img/bdk-logo.ea5ab41d.svg"},420:function(A,I,g){"use strict";g.r(I);var C=g(7),t=Object(C.a)({},(function(){var A=this,I=A._self._c;return I("ContentSlotsDistributor",{attrs:{"slot-key":A.$parent.slotKey}},[I("div",{staticClass:"case-studies"},[I("div",{staticClass:"case-studies-inner"},[I("div",{staticClass:"logo-wrapper"},[I("img",{attrs:{src:g(363)}}),A._v(" "),I("img",{attrs:{src:g(364)}}),A._v(" "),I("img",{attrs:{src:g(365)}}),A._v(" "),I("img",{attrs:{src:g(279)}})]),A._v(" "),I("div",{staticClass:"case-studies-inner-content"},[I("h1",[A._v("Trusted by the best")]),A._v(" "),I("p",{staticClass:"description"},[A._v("Innovative projects are building with LDK")]),A._v(" "),I("a",{attrs:{href:"/case-studies/"}},[A._v("All case studies ->")])])])]),A._v(" "),I("div",{staticClass:"cross-promo"},[I("a",{attrs:{href:"https://bitcoindevkit.org/"}},[I("div",{staticClass:"cross-promo-inner"},[I("img",{attrs:{src:g(366)}}),A._v(" "),I("div",{staticClass:"divider"}),A._v(" "),I("p",{staticClass:"cross-promo-description"},[A._v("The on-chain companion to LDK")])])])])])}),[],!1,null,null,null);I.default=t.exports}}]); \ No newline at end of file +(window.webpackJsonp=window.webpackJsonp||[]).push([[11],{279:function(A,I){A.exports="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAIIAAACCCAYAAACKAxD9AAAAAXNSR0IArs4c6QAAABplWElmTU0AKgAAAAgAAQESAAMAAAABAAEAAAAAAAATwHXnAAAACXBIWXMAAA7EAAAOxAGVKw4bAAAFdWlUWHRYTUw6Y29tLmFkb2JlLnhtcAAAAAAAPHg6eG1wbWV0YSB4bWxuczp4PSJhZG9iZTpuczptZXRhLyIgeDp4bXB0az0iWE1QIENvcmUgNi4wLjAiPgogICA8cmRmOlJERiB4bWxuczpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiPgogICAgICA8cmRmOkRlc2NyaXB0aW9uIHJkZjphYm91dD0iIgogICAgICAgICAgICB4bWxuczp0aWZmPSJodHRwOi8vbnMuYWRvYmUuY29tL3RpZmYvMS4wLyIKICAgICAgICAgICAgeG1sbnM6ZGM9Imh0dHA6Ly9wdXJsLm9yZy9kYy9lbGVtZW50cy8xLjEvIgogICAgICAgICAgICB4bWxuczpBdHRyaWI9Imh0dHA6Ly9ucy5hdHRyaWJ1dGlvbi5jb20vYWRzLzEuMC8iCiAgICAgICAgICAgIHhtbG5zOnhtcD0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wLyI+CiAgICAgICAgIDx0aWZmOllSZXNvbHV0aW9uPjk2PC90aWZmOllSZXNvbHV0aW9uPgogICAgICAgICA8dGlmZjpYUmVzb2x1dGlvbj45NjwvdGlmZjpYUmVzb2x1dGlvbj4KICAgICAgICAgPHRpZmY6T3JpZW50YXRpb24+MTwvdGlmZjpPcmllbnRhdGlvbj4KICAgICAgICAgPGRjOmNyZWF0b3I+CiAgICAgICAgICAgIDxyZGY6U2VxPgogICAgICAgICAgICAgICA8cmRmOmxpPkhhbGV5IEJlcmtvZTwvcmRmOmxpPgogICAgICAgICAgICA8L3JkZjpTZXE+CiAgICAgICAgIDwvZGM6Y3JlYXRvcj4KICAgICAgICAgPGRjOnRpdGxlPgogICAgICAgICAgICA8cmRmOkFsdD4KICAgICAgICAgICAgICAgPHJkZjpsaSB4bWw6bGFuZz0ieC1kZWZhdWx0Ij5VbnRpdGxlZCBkZXNpZ24gLSAxPC9yZGY6bGk+CiAgICAgICAgICAgIDwvcmRmOkFsdD4KICAgICAgICAgPC9kYzp0aXRsZT4KICAgICAgICAgPEF0dHJpYjpBZHM+CiAgICAgICAgICAgIDxyZGY6U2VxPgogICAgICAgICAgICAgICA8cmRmOmxpIHJkZjpwYXJzZVR5cGU9IlJlc291cmNlIj4KICAgICAgICAgICAgICAgICAgPEF0dHJpYjpUb3VjaFR5cGU+MjwvQXR0cmliOlRvdWNoVHlwZT4KICAgICAgICAgICAgICAgICAgPEF0dHJpYjpDcmVhdGVkPjIwMjQtMDQtMjM8L0F0dHJpYjpDcmVhdGVkPgogICAgICAgICAgICAgICAgICA8QXR0cmliOkV4dElkPmZmOGY1MDgxLTQ2YjEtNGVmYy1iZWUyLWY0NjIzZjA5Njc2NDwvQXR0cmliOkV4dElkPgogICAgICAgICAgICAgICAgICA8QXR0cmliOkZiSWQ+NTI1MjY1OTE0MTc5NTgwPC9BdHRyaWI6RmJJZD4KICAgICAgICAgICAgICAgPC9yZGY6bGk+CiAgICAgICAgICAgIDwvcmRmOlNlcT4KICAgICAgICAgPC9BdHRyaWI6QWRzPgogICAgICAgICA8eG1wOkNyZWF0b3JUb29sPkNhbnZhIChSZW5kZXJlcik8L3htcDpDcmVhdG9yVG9vbD4KICAgICAgPC9yZGY6RGVzY3JpcHRpb24+CiAgIDwvcmRmOlJERj4KPC94OnhtcG1ldGE+CsmoN4cAAAwZSURBVHgB7Z1pqFZVF8e3ppbmUGZaaE45pEhJihma84QhpIRanzREUXP4YKSIKZSUoIGEA44oigNqmTaoDZZSlJbmPM9j5Zxlme7Wb73uw/G+5vtyn+e5zzmwFtx7ztnTWvu//nvttbdazpkYAoaAIWAIGAKGgCFgCBgChoAhYAgYAoaAIWAIGAKGgCFgCBgChoAhYAgYAoaAIWAIGAKGgCFgCBgChoAhYAgYAoaAIWAIGAKGgCFgCBgChoAhYAgYAoaAIWAIGAKGgCFgCBgChoAhkEQEiolRJZNomNlkCBgCeUCAiDA2D3pNZcIQgAg+YTaZOXlAoITovJ4HvaYyYQhYREiYQ/JlTvF8KTa9yULAiJAsf+TNGiNC3qBPlmIjQrL8kTdrjAh5gz5Zio0IyfJH3qwxIuQN+mQpNiIkyx95s8aIkDfok6XYiJAsf+TNGiNC3qBPlmIjQrL8kTdrjAh5gz5Zio0IyfJH3qwxIuQN+mQpNiIkyx95s8aIkDfok6U4b0QoWbKkK1aMvyBlkgQEipQIwfFVqlRx169fd957V7x4kZqQBMwTaUOReQES4PjatWu7s2fPurp167rq1au7mzdvWmRICDX46+xF8vPEE0+ontdff93Pnz9f3ytVqlQkuotqjinWk3sS3Hvvvf7xxx9Xh0+YMMFfvnzZDx48WL9lmzAiFNFC/B8kzQ0RZCtQBz/00EO+cuXK+j5v3jwvuYHftGmTfterV89IkAwSeP6BS9Yl5APVqlVzJ06c0PE3bNigieGOHTvcihUrtOzSpUt31V2qVCn3999/ax5RsCF1Emm0joTzr7/+cn/++WfUjDraUEf5tWvXtA7bKC/YluSVfKVEiRKudOnSms/QgfY3btxwv//+e9S/TJkyUZL7xx9/qI1UBpt4pw915EVBGIu+COPF6+h73333aR12XL169bZ6Tlm0Bw+E+fGOnmxJVlelTFbHC1uBGOm3b9/uP/roI//aa6/5H3/8UeuFJHfVKw6M6sOYjMWPgBLVhTKeAqaW32m7CXXx9rzHx/63NvF2dxpbyHPbOEHHI4884uPziOdDDz/8cDSHeJvQN66nYL0QNeqL7tAnk2dWIwKMh7WSFLo9e/a4Dh06uBkzZrjNmze7nj17OqLC559/LvY69+CDDzpYLpN0Fy5ccOfPn9fVR3/GYVXUqVNH686dOxfV0YfV++yzz7rHHnvMnT592glo7ueff3Zff/21E7D1VCLbjmvSpImOf+rUKffll1/qamfsWrVquf3796ut6IvrefLJJ9V+VvNvv/3mxGH6/Pjjj9VeTjydOnVyFSpU0HkwztatW/WdE1GjRo10ZTOndevWaTm/HnjgAffrr7+6Ll26aNmnn36qZRcvXtS5YlPjxo3d/fffr1ig75577lEbwSKcsIiw2EZ7Isju3bu1XTYiQ1YYJbPTcRo0aKDPoUOH+qNHj/qJEyf+X+OXL18+aheiBVFkxIgRWh5WU9WqVfX73Xff9Vu2bPFHjhzx27Zt89OmTYv6v/32237nzp3+m2++8T/99JOfPn261gkJfLNmzfxnn33m69ev7wVMLReH+SFDhuj7qFGjNIehH2N/9913/pNPPonGXrhwod+1a5eOjf7Ro0dHdR9++KHft2+fF0KqTXyDC7p4zpo1S+2i/8yZM7VMnK/P5cuXK170xfalS5dqecOGDfU5Z86caB7g8+233/ru3btrXbly5fQZfFDIZ3aSRU4GYcLvvfeeF+b6YcOGqYGy4vzUqVM9wLz//vv+gw8+0J8FCxb41atX+5EjR2o7iRL6FPbrE1DGjBmj74TSRx99VLcFWQlaxoR/+OEH36pVK/0O2xEgjR07NmpDO5JWns8995w6MQ7Wxo0bI8KhgzpskggWjQGJKD906JB/6qmnonLKJBLot0Q7z6mIMuyVfMi/8sor+o1+Wb3++eef9127dvUSMT0OrFmzptavX7/eL168WN+feeYZf/DgQd+xY0f9ZrwlS5YokXhnEXz11VdaV6NGjagNdYX9ycrWQIgiGdu7d68T5rqnn37akSgGOXDggCMxJAkjhBGOCfd9+/bVpOidd97RpiERCv1oS1hESOLYBhC2B8ImdbQhnCIhASRxDG3ZPo4fP676aHPlyhW1Y9KkSbrFEGYJ2zwRbETC+LwT8gn1/MjR140fP95JNHBCOEcIJ9FDsIWtA/nll1/UHiGAfgsxnURIJ1FOvwcNGuQkWroBAwboN32DCEEUT4kujv5gBTZCdNevXz/34osvOrYWJN4v9C/MM2MiAAJ7NsIe3aJFCyer3i1atEhBxVk4XrYKd/LkychGWQFOQroT1mtZxYoVdW+MGsgL+zkEQNCB81atWuXoS14QcozgCG1461fIznHcG2+84WTVuy+++EKJB3Fk1emY2Ee+AnmQQLyQq1CG7lD/5ptvqiMkCrnevXvrfGV7oJnai6OYE2MiYIGQhzC2bHWatzCmRAOt4xffLVu2dGvXrnVgQf+XX37ZyTanbehLnkCuJVFJ25J/9e/fX3MlyJ6JZHzFzDEGVr7wwgvq6Llz5+qkWFHh2MZRScKp2tm8eXNN1DgeAZjcMWiCF5JFGuEEhMmHlU2iRYIYwGPlkTjhoJUrV2r7cPyCPCSICJFIQnGkn0h15swZBbJt27auffv2jpXHKiwogRSUYy8ie7l76aWXXOvWrZ3s465du3ZaHn4RNbCZ6Pjqq686oiECHjgSZ7NYmAdED4LN33//vSai3bp1c7Nnz3Y9evQI1dpfchWtb9OmjZOtQpNaGrAgMpWMI0IItbLvO37uJn369HHjxo1zTGjgwIEacgEthOVAAEBDcCyromnTpnpu5kQQ2rKyOBUQ+tFLmJb9WftBGuohGmMRPcI9ADoI/xATEpF1ly1bNroX4BSD4JgQaUJU4jTEuLRn3myB9A+CQ5jbW2+9FYqiExRjUSdHaK2Ta3bXuXPnqB19w9YIJkTPgAeNqA9Rhu84ceOEoq4wkjERUIpzCMUAjgDc4cOH1RGTJ092HOUggCROTpJGR04gp4vbQNSOt35xpEJwMEcqog5jSrave/OtZrqi2CtxTFgVAN6rVy8NqRAHkDjGQRTk2LFjuqoJryGnWLZsmZP7Da1nP0ZYneESKlx8BcBxGPPlODx8+PDoGEhkCpGIrYD3ENGog6AIZCNSBP2UcckGuYJw/MauIGvWrImIQhlbXdAVbA5tC/ssdKYpCu/YN2TRnBI4GZDlcpQMx53wh0//1p/y+HGyYDvZQ++o9259GENI8l/9xKFRWTiNxMuEZFovRIzaxe3htFTQXslBbmsrdw7RN3VBD/3QFbebdyF11B6bOV0EndgTv1CK9w1tCvNkk0JJ1oTVC9O5WBES6GUMly/sazCXP37mEobVFQ99cQNCHRGGlcdeHcrIC8hJWO2ER8agjj2cSyWE6EDfENIpI9SSkLEayUvIMYJ+2rLqiQBBD3oZn3ahjG1G7jGibYTIwIoPmTvjEh1Z2aFPeHIxxVYUogtRjC2K0wVCPeORYyDgyGkmnEJIILE31NMfG5lz0KEdM/gVsU3GyPg9nOW5PEG4rAnjhvsBMTwqC3X2zBz7DDHMngHxkCf7l14aYRzhMPwJpJEge3hn6PiCizF7hgVnS2Lop0yZooq4xo3vaVk2vuBk7LvwUT17RMDJso96yQPUIXK0M8cU3jFFil3Wk0UhgwoJWEh0Qpk9k4tATohAth4uR5I7dbMsjkBOiBBXYO/pQOA/96npsNWszCECRoQcgpumoY0IafJWDm01IuQQ3DQNbURIk7dyaKsRIYfgpmloI0KavJVDW40IOQQ3TUMbEdLkrRzaakTIIbhpGtqIkCZv5dBWI0IOwU3T0EaENHkrh7YaEXIIbpqGNiKkyVs5tNWIkENw0zS0ESFN3sqhrfyTN/ufhOcQ4LQMbX9VLS2eyrGdEGFsjnXY8IaAIZAWBIgImf9XFtIyW7PTEDAEDAFDwBAwBAwBQ8AQMAQMAUPAEDAEDAFDwBAwBAwBQ8AQMAQMAUPAEDAEDAFDwBAwBAwBQ8AQMAQMAUPAEDAEDAFDwBAwBAwBQ8AQMAQMAUPAEDAEDAFDwBAwBAwBQ8AQMAQMAUMgZQj8A1nFO753Z6pvAAAAAElFTkSuQmCC"},363:function(A,I,g){A.exports=g.p+"assets/img/bitkit.6eacba41.svg"},364:function(A,I,g){A.exports=g.p+"assets/img/mutiny.5939a956.svg"},365:function(A,I,g){A.exports=g.p+"assets/img/cashapp.db7a02f3.svg"},366:function(A,I,g){A.exports=g.p+"assets/img/bdk-logo.ea5ab41d.svg"},421:function(A,I,g){"use strict";g.r(I);var C=g(7),t=Object(C.a)({},(function(){var A=this,I=A._self._c;return I("ContentSlotsDistributor",{attrs:{"slot-key":A.$parent.slotKey}},[I("div",{staticClass:"case-studies"},[I("div",{staticClass:"case-studies-inner"},[I("div",{staticClass:"logo-wrapper"},[I("img",{attrs:{src:g(363)}}),A._v(" "),I("img",{attrs:{src:g(364)}}),A._v(" "),I("img",{attrs:{src:g(365)}}),A._v(" "),I("img",{attrs:{src:g(279)}})]),A._v(" "),I("div",{staticClass:"case-studies-inner-content"},[I("h1",[A._v("Trusted by the best")]),A._v(" "),I("p",{staticClass:"description"},[A._v("Innovative projects are building with LDK")]),A._v(" "),I("a",{attrs:{href:"/case-studies/"}},[A._v("All case studies ->")])])])]),A._v(" "),I("div",{staticClass:"cross-promo"},[I("a",{attrs:{href:"https://bitcoindevkit.org/"}},[I("div",{staticClass:"cross-promo-inner"},[I("img",{attrs:{src:g(366)}}),A._v(" "),I("div",{staticClass:"divider"}),A._v(" "),I("p",{staticClass:"cross-promo-description"},[A._v("The on-chain companion to LDK")])])])])])}),[],!1,null,null,null);I.default=t.exports}}]); \ No newline at end of file diff --git a/assets/js/12.3e9dbde3.js b/assets/js/12.57c4b7a7.js similarity index 54% rename from assets/js/12.3e9dbde3.js rename to assets/js/12.57c4b7a7.js index 641e5e768..a8eca06d4 100644 --- a/assets/js/12.3e9dbde3.js +++ b/assets/js/12.57c4b7a7.js @@ -1 +1 @@ -(window.webpackJsonp=window.webpackJsonp||[]).push([[12],{348:function(t,a,n){t.exports=n.p+"assets/img/qr-codes.58a16df5.png"},349:function(t,a,n){t.exports=n.p+"assets/img/blinded-path.2f9b76cf.svg"},350:function(t,a,n){t.exports=n.p+"assets/img/offers-flow.ccc79cd7.svg"},351:function(t,a,n){t.exports=n.p+"assets/img/offer-metadata.45a2a1cf.svg"},388:function(t,a,n){"use strict";n.r(a);var s=n(7),e=Object(s.a)({},(function(){var t=this,a=t._self._c;return a("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[a("p",[t._v("You may have heard of BOLT12—lovingly referred to as Offers—but what is it, and why should you care? In short, BOLT12 is a new payment protocol for Lightning that offers enhanced privacy, reusable payment codes, refunds, and much more, all natively over the Lightning Network. No additional servers are required. This is all possible using new technologies like onion messages and route blinding. Let’s further explore how to make use of BOLT12 in LDK.")]),t._v(" "),a("h2",{attrs:{id:"bolt11-invoices-and-reusability"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#bolt11-invoices-and-reusability"}},[t._v("#")]),t._v(" BOLT11 Invoices and Reusability")]),t._v(" "),a("p",[t._v("To understand why BOLT12 is essential, let’s briefly discuss what it’s replacing. BOLT11 defined an invoice format that, while useful, has some shortcomings. Invoices are communicated out-of-band—typically via a QR code—from recipient to sender. They are signed, making them large and thus difficult for some devices to scan. But more importantly, they can’t be safely reused since they contain a payment hash.")]),t._v(" "),a("p",[t._v("In Lightning, a payment is claimed by releasing the preimage of a payment hash. Once revealed, anyone with knowledge of the preimage—which could show up on-chain—may use it to claim a payment for an invoice using the same payment hash. So, reusing invoices is a no-no if you don’t want your payment stolen. While solutions have been built up around BOLT11 for requesting unique invoices, they have significant drawbacks. It requires either running a dedicated server or trusting a third party to do so on your behalf, including all the privacy implications that this entails.")]),t._v(" "),a("h2",{attrs:{id:"bolt12-to-the-rescue"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#bolt12-to-the-rescue"}},[t._v("#")]),t._v(" BOLT12 to the Rescue")]),t._v(" "),a("p",[t._v("That’s where BOLT12 comes in. The specification defines an "),a("em",[t._v("offer")]),t._v(" that can be considered a precursor to an "),a("em",[t._v("invoice")]),t._v(". It contains less data than an invoice and is smaller to display as a QR code. Optionally, it may contain blinded paths—more on that in a moment. Someone scanning an offer sends an "),a("em",[t._v("invoice request")]),t._v(" to the intended recipient, who replies with an invoice containing a unique payment hash. That’s it!")]),t._v(" "),a("figure",[a("img",{attrs:{src:n(348),alt:"BOLT11 vs BOLT12 QR Codes"}})]),t._v(" "),a("p",{staticStyle:{"text-align":"center"}},[a("i",[t._v("Comparison of typical BOLT11 (left) and BOLT12 (right) QR codes")])]),t._v(" "),a("p",[t._v("So how is this all happening without a dedicated server? The magic comes in with something called "),a("a",{attrs:{href:"../onion-messages-demystified"}},[t._v("onion messages")]),t._v(". The Lightning protocol is defined as messages exchanged between direct peers. An onion payment involves an interchange of messages along a path, collecting fees and transferring funds until the preimage is revealed and the funds claimed.")]),t._v(" "),a("p",[t._v("An onion message is very similar in that it involves sending messages along a path, encrypted as an onion such that each hop only knows where to send the message next. The difference is that they’re more efficient and don’t require locking any liquidity. Messages are forwarded until they reach the intended recipient. There is no interchange between adjacent peers to sign and revoke commitments or a round-trip along the path. Channel liquidity—or channels, for that matter—aren’t even required.")]),t._v(" "),a("h2",{attrs:{id:"ok-so-what-about-privacy"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#ok-so-what-about-privacy"}},[t._v("#")]),t._v(" OK, so what about privacy?")]),t._v(" "),a("p",[t._v("Ah, that’s where blinded paths come in. BOLT11 invoices reveal the recipient's node ID, which could be mapped to their IP address. But remember how an offer may contain some blinded paths? Those are to ensure recipient privacy. The recipient constructs a path leading to itself from some point in the Lightning Network, probably a few hops away. Then, it blinds the nodes along the route using fancy cryptography, leaving the first node unblinded. We call that the introduction node.")]),t._v(" "),a("figure",[a("img",{attrs:{src:n(349),alt:"Blinded Path"}})]),t._v(" "),a("p",{staticStyle:{"text-align":"center"}},[a("i",[t._v("Depiction of a blinded path used in an offer where adjacent nodes are peers")])]),t._v(" "),a("p",[t._v("When the sender scans an offer, it constructs a path from itself to the blinded path’s introduction node. This combined path is then made into an onion for routing with the invoice request as the payload. It also contains a "),a("em",[t._v("reply path")]),t._v("—another blinded path—back to the sender, allowing the recipient to respond similarly to an invoice without revealing the sender’s node ID.")]),t._v(" "),a("p",[t._v("This is taken further with the invoice, which contains "),a("em",[t._v("blinded payment paths")]),t._v("—essentially blinded paths with some additional payment information. This allows the recipient to provide partial routes with enough liquidity for payment as requests are made—yet in a privacy-preserving manner, unlike BOLT11.")]),t._v(" "),a("figure",[a("img",{attrs:{src:n(350),alt:"Offers flow"}})]),t._v(" "),a("p",{staticStyle:{"text-align":"center"}},[a("i",[t._v("Offers flow of Alice paying Bob where onion messages and payments culminate over blinded paths")])]),t._v(" "),a("p",[t._v("Invoices and invoice requests are signed using keys corresponding to pubkeys in the offer and invoice request. But guess what? These can be unique since, in the presence of blinded paths, they aren’t needed for routing. By always generating new keys, payments are more difficult to correlate to the same sender or recipient, an added boon for privacy! Contrast this with a BOLT11 invoice containing the recipient’s node ID. This is so the sender can construct a route to the recipient for the payment.")]),t._v(" "),a("h2",{attrs:{id:"offers-in-ldk"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#offers-in-ldk"}},[t._v("#")]),t._v(" Offers in LDK")]),t._v(" "),a("p",[t._v("There’s a lot to BOLT12, but LDK helpfully hides all those details from you. Let’s take a look at how you would construct an offer in LDK using the familiar builder pattern.")]),t._v(" "),a("div",{staticClass:"language-rust extra-class"},[a("pre",{pre:!0,attrs:{class:"language-rust"}},[a("code",[a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" offer "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" channel_manager\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("create_offer_builder")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("description")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"coffee"')]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("to_string")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("amount_msats")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("10_000_000")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("build")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" bech32_offer "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" offer"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("to_string")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),a("p",[t._v("One cool thing about offers is that they can be stateless, meaning you don’t need to store any data about them once constructed. How does this work? LDK encodes some information in the offer’s metadata, allowing it to recognize incoming invoice requests for the offer.")]),t._v(" "),a("p",[t._v("Paying an offer is just as simple.")]),t._v(" "),a("div",{staticClass:"language-rust extra-class"},[a("pre",{pre:!0,attrs:{class:"language-rust"}},[a("code",[a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" payment_id "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("PaymentId")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("42")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("32")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" retry "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Retry")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Timeout")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Duration")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("from_secs")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("60")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("match")]),t._v(" channel_manager"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("pay_for_offer")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n offer"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" quantity"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" amount_msats"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" payer_note"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" payment_id"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" retry"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" max_total_routing_fee_msat\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Ok")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token macro property"}},[t._v("println!")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Requesting invoice for offer"')]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Err")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("e"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token macro property"}},[t._v("println!")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Unable to request invoice for offer: {:?}"')]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" e"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// First the payment will be waiting on an invoice")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" expected_payment_id "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" payment_id"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token macro property"}},[t._v("assert!")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n channel_manager"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("list_recent_payments")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("iter")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("find")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token closure-params"}},[a("span",{pre:!0,attrs:{class:"token closure-punctuation punctuation"}},[t._v("|")]),t._v("details"),a("span",{pre:!0,attrs:{class:"token closure-punctuation punctuation"}},[t._v("|")])]),t._v(" "),a("span",{pre:!0,attrs:{class:"token macro property"}},[t._v("matches!")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n details"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("RecentPaymentDetails")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("AwaitingInvoice")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" payment_id"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" expected_payment_id "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("is_some")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Once the invoice is received, a payment will be sent")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token macro property"}},[t._v("assert!")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n channel_manager"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("list_recent_payments")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("iter")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("find")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token closure-params"}},[a("span",{pre:!0,attrs:{class:"token closure-punctuation punctuation"}},[t._v("|")]),t._v("details"),a("span",{pre:!0,attrs:{class:"token closure-punctuation punctuation"}},[t._v("|")])]),t._v(" "),a("span",{pre:!0,attrs:{class:"token macro property"}},[t._v("matches!")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n details"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("RecentPaymentDetails")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Pending")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" payment_id"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" expected_payment_id"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("..")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("is_some")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),a("p",[t._v("Here, LDK stores a small amount of data for outbound payments, which ensures you don’t pay an invoice more than once for a given payment ID.")]),t._v(" "),a("p",[t._v("As the recipient, you only need to wait for an event to claim the payment.")]),t._v(" "),a("div",{staticClass:"language-rust extra-class"},[a("pre",{pre:!0,attrs:{class:"language-rust"}},[a("code",[t._v("channel_manager"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("process_pending_events")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("|")]),t._v("event"),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("|")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("match")]),t._v(" event "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Event")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("PaymentClaimable")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" payment_hash"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" purpose"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("..")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("match")]),t._v(" purpose "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n \t"),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("PaymentPurpose")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("InvoicePayment")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" payment_preimage"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Some")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("payment_preimage"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("..")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token macro property"}},[t._v("println!")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Claiming payment {}"')]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" payment_hash"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n channel_manager"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("claim_funds")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("payment_preimage"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n \t"),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("PaymentPurpose")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("InvoicePayment")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" payment_preimage"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("None")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("..")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token macro property"}},[t._v("println!")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Unknown payment hash: {}"')]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" payment_hash"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n \t"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// ...")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Event")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("PaymentClaimed")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" payment_hash"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" amount_msat"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("..")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token macro property"}},[t._v("println!")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Claimed {} msats"')]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" amount_msat"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// ...")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),a("p",[t._v("Similarly, the sender will receive an event when the payment is resolved.")]),t._v(" "),a("div",{staticClass:"language-rust extra-class"},[a("pre",{pre:!0,attrs:{class:"language-rust"}},[a("code",[t._v("channel_manager"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("process_pending_events")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("|")]),t._v("event"),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("|")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("match")]),t._v(" event "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Event")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("PaymentSent")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" payment_id"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Some")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("payment_id"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("..")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token macro property"}},[t._v("println!")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Paid {}"')]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" payment_id"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Event")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("PaymentFailed")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" payment_id"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("..")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token macro property"}},[t._v("println!")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Failed paying {}"')]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" payment_id"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Event")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("InvoiceRequestFailed")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" payment_id"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("..")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token macro property"}},[t._v("println!")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Failed paying {}"')]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" payment_id"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// ...")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),a("p",[t._v("These examples work swimmingly when building a Lightning wallet programmatically. However, LDK uniquely exposes the underlying "),a("a",{attrs:{href:"https://docs.rs/lightning/0.0.123-beta/lightning/offers/index.html",target:"_blank",rel:"noopener noreferrer"}},[t._v("offers"),a("OutboundLink")],1),t._v(", "),a("a",{attrs:{href:"https://docs.rs/lightning/0.0.123-beta/lightning/blinded_path/index.html",target:"_blank",rel:"noopener noreferrer"}},[t._v("blinded paths"),a("OutboundLink")],1),t._v(", and "),a("a",{attrs:{href:"https://docs.rs/lightning/0.0.123-beta/lightning/onion_message/index.html",target:"_blank",rel:"noopener noreferrer"}},[t._v("onion message"),a("OutboundLink")],1),t._v(" modules for direct use. This means you can experiment with building your applications or add BOLT12 support to LND, such as the "),a("a",{attrs:{href:"https://github.com/lndk-org/lndk",target:"_blank",rel:"noopener noreferrer"}},[t._v("LNDK"),a("OutboundLink")],1),t._v(" project.")]),t._v(" "),a("h2",{attrs:{id:"wait-what-about-refunds"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#wait-what-about-refunds"}},[t._v("#")]),t._v(" Wait, what about refunds?")]),t._v(" "),a("p",[t._v("Whereas an offer is an “offer to be paid,” a "),a("em",[t._v("refund")]),t._v(" is an “offer for money.” Simply put, refunds allow a merchant to present a QR code to a customer to refund a purchase. The customer scans the refund just like it would an offer, but instead of sending the merchant an invoice request, the customer sends an invoice asking the merchant to pay.")]),t._v(" "),a("p",[t._v("LDK has a similar interface for constructing a refund and requesting payment.")]),t._v(" "),a("div",{staticClass:"language-rust extra-class"},[a("pre",{pre:!0,attrs:{class:"language-rust"}},[a("code",[a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" payment_id "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("PaymentId")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("42")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("32")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" retry "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Retry")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Timeout")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Duration")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("from_secs")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("60")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" refund "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" channel_manager\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("create_refund_builder")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n amount_msats"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" absolute_expiry"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" payment_id"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" retry"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" max_total_routing_fee_msat\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("description")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"coffee"')]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("to_string")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("payer_note")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"refund for order 1234"')]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("to_string")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("build")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" bech32_refund "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" refund"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("to_string")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),a("p",[t._v("Like when paying an offer, LDK will track a pending payment and surface events just the same.")]),t._v(" "),a("h2",{attrs:{id:"achieving-statelessness"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#achieving-statelessness"}},[t._v("#")]),t._v(" Achieving statelessness")]),t._v(" "),a("p",[t._v("Both offer and invoice requests contain a metadata field. This helps LDK store minimal information about a payment. For inbound payments, this equals nothing at all! So how does it work?")]),t._v(" "),a("p",[t._v("LDK generates a random nonce for an offer and, along with the offer’s TLV records, computes an HMAC using a secret key. The HMAC is used to derive a key to sign the invoice. The nonce is then stored in the offer’s metadata to re-derive the signing key later.")]),t._v(" "),a("p",[t._v("When an invoice request is received, it contains all the offer’s TLV records, including the metadata. By re-deriving the signing key from the metadata and TLV records, LDK can verify that the offer is authentic by checking whether the re-derived signing key corresponds to the offer’s signing pubkey. Now, it can create and sign an invoice with the key.")]),t._v(" "),a("p",[t._v("If you prefer to use your signing key, LDK will also include the HMAC in the metadata. Authentication then consists of re-computing the HMAC and comparing it against the one in the metadata.")]),t._v(" "),a("p",[t._v("An invoice request has its own payer metadata, which is similarly generated and includes an encrypted payment ID. Thus, when LDK receives an invoice, it can look up a pending payment with the ID and decide if the invoice should be paid after a similar authentication.")]),t._v(" "),a("figure",[a("img",{attrs:{src:n(351),alt:"Offer metadata"}})]),t._v(" "),a("p",{staticStyle:{"text-align":"center"}},[a("i",[t._v("Metadata consists primarily of a nonce and an optional HMAC, while outbound payments include an encrypted payment ID used for look-up upon receiving an invoice")])]),t._v(" "),a("h2",{attrs:{id:"what-s-next"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#what-s-next"}},[t._v("#")]),t._v(" What’s next?")]),t._v(" "),a("p",[t._v("BOLT12 is still in a very early stage of adoption, but as you can see, there’s much promise. In the next post, we’ll explore one of the most crucial problems in Lightning—receiving offline—and how BOLT12 and asynchronous payments solve it.")])])}),[],!1,null,null,null);a.default=e.exports}}]); \ No newline at end of file +(window.webpackJsonp=window.webpackJsonp||[]).push([[12],{347:function(t,a,n){t.exports=n.p+"assets/img/qr-codes.58a16df5.png"},348:function(t,a,n){t.exports=n.p+"assets/img/blinded-path.2f9b76cf.svg"},349:function(t,a,n){t.exports=n.p+"assets/img/offers-flow.ccc79cd7.svg"},350:function(t,a,n){t.exports=n.p+"assets/img/offer-metadata.45a2a1cf.svg"},388:function(t,a,n){"use strict";n.r(a);var s=n(7),e=Object(s.a)({},(function(){var t=this,a=t._self._c;return a("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[a("p",[t._v("You may have heard of BOLT12—lovingly referred to as Offers—but what is it, and why should you care? In short, BOLT12 is a new payment protocol for Lightning that offers enhanced privacy, reusable payment codes, refunds, and much more, all natively over the Lightning Network. No additional servers are required. This is all possible using new technologies like onion messages and route blinding. Let’s further explore how to make use of BOLT12 in LDK.")]),t._v(" "),a("h2",{attrs:{id:"bolt11-invoices-and-reusability"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#bolt11-invoices-and-reusability"}},[t._v("#")]),t._v(" BOLT11 Invoices and Reusability")]),t._v(" "),a("p",[t._v("To understand why BOLT12 is essential, let’s briefly discuss what it’s replacing. BOLT11 defined an invoice format that, while useful, has some shortcomings. Invoices are communicated out-of-band—typically via a QR code—from recipient to sender. They are signed, making them large and thus difficult for some devices to scan. But more importantly, they can’t be safely reused since they contain a payment hash.")]),t._v(" "),a("p",[t._v("In Lightning, a payment is claimed by releasing the preimage of a payment hash. Once revealed, anyone with knowledge of the preimage—which could show up on-chain—may use it to claim a payment for an invoice using the same payment hash. So, reusing invoices is a no-no if you don’t want your payment stolen. While solutions have been built up around BOLT11 for requesting unique invoices, they have significant drawbacks. It requires either running a dedicated server or trusting a third party to do so on your behalf, including all the privacy implications that this entails.")]),t._v(" "),a("h2",{attrs:{id:"bolt12-to-the-rescue"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#bolt12-to-the-rescue"}},[t._v("#")]),t._v(" BOLT12 to the Rescue")]),t._v(" "),a("p",[t._v("That’s where BOLT12 comes in. The specification defines an "),a("em",[t._v("offer")]),t._v(" that can be considered a precursor to an "),a("em",[t._v("invoice")]),t._v(". It contains less data than an invoice and is smaller to display as a QR code. Optionally, it may contain blinded paths—more on that in a moment. Someone scanning an offer sends an "),a("em",[t._v("invoice request")]),t._v(" to the intended recipient, who replies with an invoice containing a unique payment hash. That’s it!")]),t._v(" "),a("figure",[a("img",{attrs:{src:n(347),alt:"BOLT11 vs BOLT12 QR Codes"}})]),t._v(" "),a("p",{staticStyle:{"text-align":"center"}},[a("i",[t._v("Comparison of typical BOLT11 (left) and BOLT12 (right) QR codes")])]),t._v(" "),a("p",[t._v("So how is this all happening without a dedicated server? The magic comes in with something called "),a("a",{attrs:{href:"../onion-messages-demystified"}},[t._v("onion messages")]),t._v(". The Lightning protocol is defined as messages exchanged between direct peers. An onion payment involves an interchange of messages along a path, collecting fees and transferring funds until the preimage is revealed and the funds claimed.")]),t._v(" "),a("p",[t._v("An onion message is very similar in that it involves sending messages along a path, encrypted as an onion such that each hop only knows where to send the message next. The difference is that they’re more efficient and don’t require locking any liquidity. Messages are forwarded until they reach the intended recipient. There is no interchange between adjacent peers to sign and revoke commitments or a round-trip along the path. Channel liquidity—or channels, for that matter—aren’t even required.")]),t._v(" "),a("h2",{attrs:{id:"ok-so-what-about-privacy"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#ok-so-what-about-privacy"}},[t._v("#")]),t._v(" OK, so what about privacy?")]),t._v(" "),a("p",[t._v("Ah, that’s where blinded paths come in. BOLT11 invoices reveal the recipient's node ID, which could be mapped to their IP address. But remember how an offer may contain some blinded paths? Those are to ensure recipient privacy. The recipient constructs a path leading to itself from some point in the Lightning Network, probably a few hops away. Then, it blinds the nodes along the route using fancy cryptography, leaving the first node unblinded. We call that the introduction node.")]),t._v(" "),a("figure",[a("img",{attrs:{src:n(348),alt:"Blinded Path"}})]),t._v(" "),a("p",{staticStyle:{"text-align":"center"}},[a("i",[t._v("Depiction of a blinded path used in an offer where adjacent nodes are peers")])]),t._v(" "),a("p",[t._v("When the sender scans an offer, it constructs a path from itself to the blinded path’s introduction node. This combined path is then made into an onion for routing with the invoice request as the payload. It also contains a "),a("em",[t._v("reply path")]),t._v("—another blinded path—back to the sender, allowing the recipient to respond similarly to an invoice without revealing the sender’s node ID.")]),t._v(" "),a("p",[t._v("This is taken further with the invoice, which contains "),a("em",[t._v("blinded payment paths")]),t._v("—essentially blinded paths with some additional payment information. This allows the recipient to provide partial routes with enough liquidity for payment as requests are made—yet in a privacy-preserving manner, unlike BOLT11.")]),t._v(" "),a("figure",[a("img",{attrs:{src:n(349),alt:"Offers flow"}})]),t._v(" "),a("p",{staticStyle:{"text-align":"center"}},[a("i",[t._v("Offers flow of Alice paying Bob where onion messages and payments culminate over blinded paths")])]),t._v(" "),a("p",[t._v("Invoices and invoice requests are signed using keys corresponding to pubkeys in the offer and invoice request. But guess what? These can be unique since, in the presence of blinded paths, they aren’t needed for routing. By always generating new keys, payments are more difficult to correlate to the same sender or recipient, an added boon for privacy! Contrast this with a BOLT11 invoice containing the recipient’s node ID. This is so the sender can construct a route to the recipient for the payment.")]),t._v(" "),a("h2",{attrs:{id:"offers-in-ldk"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#offers-in-ldk"}},[t._v("#")]),t._v(" Offers in LDK")]),t._v(" "),a("p",[t._v("There’s a lot to BOLT12, but LDK helpfully hides all those details from you. Let’s take a look at how you would construct an offer in LDK using the familiar builder pattern.")]),t._v(" "),a("div",{staticClass:"language-rust extra-class"},[a("pre",{pre:!0,attrs:{class:"language-rust"}},[a("code",[a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" offer "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" channel_manager\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("create_offer_builder")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("description")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"coffee"')]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("to_string")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("amount_msats")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("10_000_000")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("build")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" bech32_offer "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" offer"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("to_string")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),a("p",[t._v("One cool thing about offers is that they can be stateless, meaning you don’t need to store any data about them once constructed. How does this work? LDK encodes some information in the offer’s metadata, allowing it to recognize incoming invoice requests for the offer.")]),t._v(" "),a("p",[t._v("Paying an offer is just as simple.")]),t._v(" "),a("div",{staticClass:"language-rust extra-class"},[a("pre",{pre:!0,attrs:{class:"language-rust"}},[a("code",[a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" payment_id "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("PaymentId")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("42")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("32")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" retry "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Retry")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Timeout")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Duration")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("from_secs")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("60")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("match")]),t._v(" channel_manager"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("pay_for_offer")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n offer"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" quantity"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" amount_msats"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" payer_note"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" payment_id"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" retry"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" max_total_routing_fee_msat\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Ok")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token macro property"}},[t._v("println!")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Requesting invoice for offer"')]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Err")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("e"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token macro property"}},[t._v("println!")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Unable to request invoice for offer: {:?}"')]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" e"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// First the payment will be waiting on an invoice")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" expected_payment_id "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" payment_id"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token macro property"}},[t._v("assert!")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n channel_manager"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("list_recent_payments")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("iter")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("find")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token closure-params"}},[a("span",{pre:!0,attrs:{class:"token closure-punctuation punctuation"}},[t._v("|")]),t._v("details"),a("span",{pre:!0,attrs:{class:"token closure-punctuation punctuation"}},[t._v("|")])]),t._v(" "),a("span",{pre:!0,attrs:{class:"token macro property"}},[t._v("matches!")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n details"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("RecentPaymentDetails")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("AwaitingInvoice")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" payment_id"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" expected_payment_id "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("is_some")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Once the invoice is received, a payment will be sent")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token macro property"}},[t._v("assert!")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n channel_manager"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("list_recent_payments")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("iter")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("find")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token closure-params"}},[a("span",{pre:!0,attrs:{class:"token closure-punctuation punctuation"}},[t._v("|")]),t._v("details"),a("span",{pre:!0,attrs:{class:"token closure-punctuation punctuation"}},[t._v("|")])]),t._v(" "),a("span",{pre:!0,attrs:{class:"token macro property"}},[t._v("matches!")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n details"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("RecentPaymentDetails")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Pending")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" payment_id"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" expected_payment_id"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("..")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("is_some")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),a("p",[t._v("Here, LDK stores a small amount of data for outbound payments, which ensures you don’t pay an invoice more than once for a given payment ID.")]),t._v(" "),a("p",[t._v("As the recipient, you only need to wait for an event to claim the payment.")]),t._v(" "),a("div",{staticClass:"language-rust extra-class"},[a("pre",{pre:!0,attrs:{class:"language-rust"}},[a("code",[t._v("channel_manager"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("process_pending_events")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("|")]),t._v("event"),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("|")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("match")]),t._v(" event "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Event")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("PaymentClaimable")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" payment_hash"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" purpose"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("..")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("match")]),t._v(" purpose "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("PaymentPurpose")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Bolt12OfferPayment")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" payment_preimage"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Some")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("payment_preimage"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("..")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token macro property"}},[t._v("println!")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Claiming payment {}"')]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" payment_hash"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n channel_manager"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("claim_funds")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("payment_preimage"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("PaymentPurpose")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Bolt12OfferPayment")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" payment_preimage"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("None")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("..")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token macro property"}},[t._v("println!")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Unknown payment hash: {}"')]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" payment_hash"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n \t"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// ...")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Event")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("PaymentClaimed")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" payment_hash"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" amount_msat"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("..")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token macro property"}},[t._v("println!")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Claimed {} msats"')]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" amount_msat"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// ...")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),a("p",[t._v("Similarly, the sender will receive an event when the payment is resolved.")]),t._v(" "),a("div",{staticClass:"language-rust extra-class"},[a("pre",{pre:!0,attrs:{class:"language-rust"}},[a("code",[t._v("channel_manager"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("process_pending_events")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("|")]),t._v("event"),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("|")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("match")]),t._v(" event "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Event")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("PaymentSent")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" payment_id"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Some")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("payment_id"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("..")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token macro property"}},[t._v("println!")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Paid {}"')]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" payment_id"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Event")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("PaymentFailed")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" payment_id"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("..")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token macro property"}},[t._v("println!")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Failed paying {}"')]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" payment_id"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Event")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("InvoiceRequestFailed")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" payment_id"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("..")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token macro property"}},[t._v("println!")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Failed paying {}"')]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" payment_id"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// ...")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),a("p",[t._v("These examples work swimmingly when building a Lightning wallet programmatically. However, LDK uniquely exposes the underlying "),a("a",{attrs:{href:"https://docs.rs/lightning/0.0.123/lightning/offers/index.html",target:"_blank",rel:"noopener noreferrer"}},[t._v("offers"),a("OutboundLink")],1),t._v(", "),a("a",{attrs:{href:"https://docs.rs/lightning/0.0.123/lightning/blinded_path/index.html",target:"_blank",rel:"noopener noreferrer"}},[t._v("blinded paths"),a("OutboundLink")],1),t._v(", and "),a("a",{attrs:{href:"https://docs.rs/lightning/0.0.123/lightning/onion_message/index.html",target:"_blank",rel:"noopener noreferrer"}},[t._v("onion message"),a("OutboundLink")],1),t._v(" modules for direct use. This means you can experiment with building your applications or add BOLT12 support to LND, such as the "),a("a",{attrs:{href:"https://github.com/lndk-org/lndk",target:"_blank",rel:"noopener noreferrer"}},[t._v("LNDK"),a("OutboundLink")],1),t._v(" project.")]),t._v(" "),a("h2",{attrs:{id:"wait-what-about-refunds"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#wait-what-about-refunds"}},[t._v("#")]),t._v(" Wait, what about refunds?")]),t._v(" "),a("p",[t._v("Whereas an offer is an “offer to be paid,” a "),a("em",[t._v("refund")]),t._v(" is an “offer for money.” Simply put, refunds allow a merchant to present a QR code to a customer to refund a purchase. The customer scans the refund just like it would an offer, but instead of sending the merchant an invoice request, the customer sends an invoice asking the merchant to pay.")]),t._v(" "),a("p",[t._v("LDK has a similar interface for constructing a refund and requesting payment.")]),t._v(" "),a("div",{staticClass:"language-rust extra-class"},[a("pre",{pre:!0,attrs:{class:"language-rust"}},[a("code",[a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" payment_id "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("PaymentId")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("42")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("32")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" retry "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Retry")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Timeout")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Duration")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("from_secs")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("60")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" refund "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" channel_manager\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("create_refund_builder")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n amount_msats"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" absolute_expiry"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" payment_id"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" retry"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" max_total_routing_fee_msat\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("description")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"coffee"')]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("to_string")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("payer_note")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"refund for order 1234"')]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("to_string")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("build")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" bech32_refund "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" refund"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("to_string")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),a("p",[t._v("Like when paying an offer, LDK will track a pending payment and surface events just the same. However, for inbound payments the events will use "),a("code",[t._v("PaymentPurpose::Bolt12RefundPayment")]),t._v(" instead.")]),t._v(" "),a("h2",{attrs:{id:"achieving-statelessness"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#achieving-statelessness"}},[t._v("#")]),t._v(" Achieving statelessness")]),t._v(" "),a("p",[t._v("Both offer and invoice requests contain a metadata field. This helps LDK store minimal information about a payment. For inbound payments, this equals nothing at all! So how does it work?")]),t._v(" "),a("p",[t._v("LDK generates a random nonce for an offer and, along with the offer’s TLV records, computes an HMAC using a secret key. The HMAC is used to derive a key to sign the invoice. The nonce is then stored in the offer’s metadata to re-derive the signing key later.")]),t._v(" "),a("p",[t._v("When an invoice request is received, it contains all the offer’s TLV records, including the metadata. By re-deriving the signing key from the metadata and TLV records, LDK can verify that the offer is authentic by checking whether the re-derived signing key corresponds to the offer’s signing pubkey. Now, it can create and sign an invoice with the key.")]),t._v(" "),a("p",[t._v("If you prefer to use your signing key, LDK will also include the HMAC in the metadata. Authentication then consists of re-computing the HMAC and comparing it against the one in the metadata.")]),t._v(" "),a("p",[t._v("An invoice request has its own payer metadata, which is similarly generated and includes an encrypted payment ID. Thus, when LDK receives an invoice, it can look up a pending payment with the ID and decide if the invoice should be paid after a similar authentication.")]),t._v(" "),a("figure",[a("img",{attrs:{src:n(350),alt:"Offer metadata"}})]),t._v(" "),a("p",{staticStyle:{"text-align":"center"}},[a("i",[t._v("Metadata consists primarily of a nonce and an optional HMAC, while outbound payments include an encrypted payment ID used for look-up upon receiving an invoice")])]),t._v(" "),a("h2",{attrs:{id:"what-s-next"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#what-s-next"}},[t._v("#")]),t._v(" What’s next?")]),t._v(" "),a("p",[t._v("BOLT12 is still in a very early stage of adoption, but as you can see, there’s much promise. In the next post, we’ll explore one of the most crucial problems in Lightning—receiving offline—and how BOLT12 and asynchronous payments solve it.")])])}),[],!1,null,null,null);a.default=e.exports}}]); \ No newline at end of file diff --git a/assets/js/17.a5a186e3.js b/assets/js/17.13adcd02.js similarity index 94% rename from assets/js/17.a5a186e3.js rename to assets/js/17.13adcd02.js index 6ff317ddf..adb4c04e6 100644 --- a/assets/js/17.a5a186e3.js +++ b/assets/js/17.13adcd02.js @@ -1 +1 @@ -(window.webpackJsonp=window.webpackJsonp||[]).push([[17],{353:function(e,t,n){e.exports=n.p+"assets/img/phantom-hints.64e934b6.png"},354:function(e,t,n){e.exports=n.p+"assets/img/phantom-pmt.8d872436.png"},391:function(e,t,n){"use strict";n.r(t);var o=n(7),a=Object(o.a)({},(function(){var e=this,t=e._self._c;return t("ContentSlotsDistributor",{attrs:{"slot-key":e.$parent.slotKey}},[t("p",[e._v("Introducing phantom node payments, a new-ish feature for LDK.")]),e._v(" "),t("p",[e._v("Phantom node payments let enterprise users running high-volume lightning nodes generate invoices that can be paid to one of multiple production nodes. Since it’s safe to assume that payers will retry along an alternate route hint if one fails, phantom payments allow for load balancing between nodes and resilience if a node or nodes go down.")]),e._v(" "),t("h2",{attrs:{id:"phantom-payment-flow"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#phantom-payment-flow"}},[e._v("#")]),e._v(" Phantom Payment Flow")]),e._v(" "),t("p",[e._v("Using LNMerchant as an example company, here’s how phantom payments work:")]),e._v(" "),t("ol",[t("li",[t("p",[e._v("Buyer on the Lightning Network requests an invoice")])]),e._v(" "),t("li",[t("p",[e._v("LNMerchant replies with an invoice. Per standard invoice protocol, it contains information on routing to LNMerchant. However, unlike conventional invoice route hints, phantom route hints include a combination of real and fake routing information. This fake or “phantom” routing information will later signal to LDK that the payment’s intended destination is a phantom node.")])])]),e._v(" "),t("p",[e._v("The following illustration demonstrates how phantom route hints work:")]),e._v(" "),t("figure",[t("img",{attrs:{src:n(353),alt:"Phantom Hints"}})]),e._v(" "),t("ol",{attrs:{start:"3"}},[t("li",[e._v("The buyer’s node generates a normal route. Using the route hints, the last two hops are [LNMerchantNode, PhantomNode], i.e., the phantom node is the destination node, and the second-to-last hop is an actual LNMerchant node. (Note: If the LNMerchant has public channels, only the last hop containing the fake channel is strictly necessary for the route hints.)")])]),e._v(" "),t("p",[e._v("The buyer uses this route, including the fake forwarding information from the route hints, to generate the payment onion. On Lightning, each hop along the route unwraps one layer of sender-constructed onion.")]),e._v(" "),t("ol",{attrs:{start:"4"}},[t("li",[t("p",[e._v("The buyer forwards the payment to the route’s first hop, which gets forwarded through intermediate hops.")])]),e._v(" "),t("li",[t("p",[e._v("The payment forwards to the second-to-last hop, an actual LNMerchant node.")])]),e._v(" "),t("li",[t("p",[e._v("The LNMerchant node checks what channel to forward the payment to and recognizes a phantom channel ID.")])]),e._v(" "),t("li",[t("p",[e._v("The LNMerchant node knows the phantom node’s secret key, so it can unwrap the last layer of the onion and verify the payment details. It also knows the preimage for the payment, so it can claim the amount owed without forwarding the payment to the non-existent phantom.")])])]),e._v(" "),t("figure",[t("img",{attrs:{src:n(354),alt:"Phantom PMT"}})]),e._v(" "),t("h2",{attrs:{id:"why-it-s-ok-to-not-support-mpp"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#why-it-s-ok-to-not-support-mpp"}},[e._v("#")]),e._v(" Why It’s OK to Not Support MPP")]),e._v(" "),t("p",[e._v("One potential drawback to phantom node payments is the lack of multi-path payments (MPP) support.")]),e._v(" "),t("p",[e._v("MPP payments benefit large transactions because they aren’t restricted to routes where each channel must carry its entire payment balance.")]),e._v(" "),t("p",[e._v("With this in mind, a compelling compromise is to:")]),e._v(" "),t("ul",[t("li",[e._v("Create MPP-supporting invoices against a single node for large payments.")]),e._v(" "),t("li",[e._v("Create phantom invoices for smaller payments, which are the most common and are unlikely to use MPP.")])]),e._v(" "),t("h2",{attrs:{id:"why-mpp-shouldn-t-be-enabled"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#why-mpp-shouldn-t-be-enabled"}},[e._v("#")]),e._v(" Why MPP Shouldn’t Be Enabled")]),e._v(" "),t("p",[e._v("Let’s say that we want to implement MPP for phantom payments. In this case, each real LNMerchant node may receive a slice of the phantom node-destined phantom payment. In this case, the question becomes: How do real nodes know when a payment is accepted across all nodes so that it’s safe to release the preimage?")]),e._v(" "),t("p",[e._v("On the surface, it seems like users should be able to tell LDK when a payment has been received across all nodes and is safe to claim. However, this would significantly compromise our safety guarantees because releasing the preimage before receiving the total payment value opens up the possibility for intermediate nodes to claim remaining payment parts. Moreover, implementing this would introduce perilous race conditions, because users would need to “lock” internal LDK data structures to ensure payment claims are atomic. Failing to properly handle these delicate cases would lead to force-closed channels and possibly lost funds.")]),e._v(" "),t("hr"),e._v(" "),t("p",[e._v("Thanks for taking the time to learn about phantom nodes and payments. We think it’s an exciting showcase for the lightning protocol’s flexibility and variety of use cases.")]),e._v(" "),t("p",[e._v("Want to make your own contribution to LDK? Join us on GitHub at our "),t("a",{attrs:{href:"https://github.com/lightningdevkit/",target:"_blank",rel:"noopener noreferrer"}},[e._v("LDK repo"),t("OutboundLink")],1),e._v(".")])])}),[],!1,null,null,null);t.default=a.exports}}]); \ No newline at end of file +(window.webpackJsonp=window.webpackJsonp||[]).push([[17],{354:function(e,t,n){e.exports=n.p+"assets/img/phantom-hints.64e934b6.png"},355:function(e,t,n){e.exports=n.p+"assets/img/phantom-pmt.8d872436.png"},394:function(e,t,n){"use strict";n.r(t);var o=n(7),a=Object(o.a)({},(function(){var e=this,t=e._self._c;return t("ContentSlotsDistributor",{attrs:{"slot-key":e.$parent.slotKey}},[t("p",[e._v("Introducing phantom node payments, a new-ish feature for LDK.")]),e._v(" "),t("p",[e._v("Phantom node payments let enterprise users running high-volume lightning nodes generate invoices that can be paid to one of multiple production nodes. Since it’s safe to assume that payers will retry along an alternate route hint if one fails, phantom payments allow for load balancing between nodes and resilience if a node or nodes go down.")]),e._v(" "),t("h2",{attrs:{id:"phantom-payment-flow"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#phantom-payment-flow"}},[e._v("#")]),e._v(" Phantom Payment Flow")]),e._v(" "),t("p",[e._v("Using LNMerchant as an example company, here’s how phantom payments work:")]),e._v(" "),t("ol",[t("li",[t("p",[e._v("Buyer on the Lightning Network requests an invoice")])]),e._v(" "),t("li",[t("p",[e._v("LNMerchant replies with an invoice. Per standard invoice protocol, it contains information on routing to LNMerchant. However, unlike conventional invoice route hints, phantom route hints include a combination of real and fake routing information. This fake or “phantom” routing information will later signal to LDK that the payment’s intended destination is a phantom node.")])])]),e._v(" "),t("p",[e._v("The following illustration demonstrates how phantom route hints work:")]),e._v(" "),t("figure",[t("img",{attrs:{src:n(354),alt:"Phantom Hints"}})]),e._v(" "),t("ol",{attrs:{start:"3"}},[t("li",[e._v("The buyer’s node generates a normal route. Using the route hints, the last two hops are [LNMerchantNode, PhantomNode], i.e., the phantom node is the destination node, and the second-to-last hop is an actual LNMerchant node. (Note: If the LNMerchant has public channels, only the last hop containing the fake channel is strictly necessary for the route hints.)")])]),e._v(" "),t("p",[e._v("The buyer uses this route, including the fake forwarding information from the route hints, to generate the payment onion. On Lightning, each hop along the route unwraps one layer of sender-constructed onion.")]),e._v(" "),t("ol",{attrs:{start:"4"}},[t("li",[t("p",[e._v("The buyer forwards the payment to the route’s first hop, which gets forwarded through intermediate hops.")])]),e._v(" "),t("li",[t("p",[e._v("The payment forwards to the second-to-last hop, an actual LNMerchant node.")])]),e._v(" "),t("li",[t("p",[e._v("The LNMerchant node checks what channel to forward the payment to and recognizes a phantom channel ID.")])]),e._v(" "),t("li",[t("p",[e._v("The LNMerchant node knows the phantom node’s secret key, so it can unwrap the last layer of the onion and verify the payment details. It also knows the preimage for the payment, so it can claim the amount owed without forwarding the payment to the non-existent phantom.")])])]),e._v(" "),t("figure",[t("img",{attrs:{src:n(355),alt:"Phantom PMT"}})]),e._v(" "),t("h2",{attrs:{id:"why-it-s-ok-to-not-support-mpp"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#why-it-s-ok-to-not-support-mpp"}},[e._v("#")]),e._v(" Why It’s OK to Not Support MPP")]),e._v(" "),t("p",[e._v("One potential drawback to phantom node payments is the lack of multi-path payments (MPP) support.")]),e._v(" "),t("p",[e._v("MPP payments benefit large transactions because they aren’t restricted to routes where each channel must carry its entire payment balance.")]),e._v(" "),t("p",[e._v("With this in mind, a compelling compromise is to:")]),e._v(" "),t("ul",[t("li",[e._v("Create MPP-supporting invoices against a single node for large payments.")]),e._v(" "),t("li",[e._v("Create phantom invoices for smaller payments, which are the most common and are unlikely to use MPP.")])]),e._v(" "),t("h2",{attrs:{id:"why-mpp-shouldn-t-be-enabled"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#why-mpp-shouldn-t-be-enabled"}},[e._v("#")]),e._v(" Why MPP Shouldn’t Be Enabled")]),e._v(" "),t("p",[e._v("Let’s say that we want to implement MPP for phantom payments. In this case, each real LNMerchant node may receive a slice of the phantom node-destined phantom payment. In this case, the question becomes: How do real nodes know when a payment is accepted across all nodes so that it’s safe to release the preimage?")]),e._v(" "),t("p",[e._v("On the surface, it seems like users should be able to tell LDK when a payment has been received across all nodes and is safe to claim. However, this would significantly compromise our safety guarantees because releasing the preimage before receiving the total payment value opens up the possibility for intermediate nodes to claim remaining payment parts. Moreover, implementing this would introduce perilous race conditions, because users would need to “lock” internal LDK data structures to ensure payment claims are atomic. Failing to properly handle these delicate cases would lead to force-closed channels and possibly lost funds.")]),e._v(" "),t("hr"),e._v(" "),t("p",[e._v("Thanks for taking the time to learn about phantom nodes and payments. We think it’s an exciting showcase for the lightning protocol’s flexibility and variety of use cases.")]),e._v(" "),t("p",[e._v("Want to make your own contribution to LDK? Join us on GitHub at our "),t("a",{attrs:{href:"https://github.com/lightningdevkit/",target:"_blank",rel:"noopener noreferrer"}},[e._v("LDK repo"),t("OutboundLink")],1),e._v(".")])])}),[],!1,null,null,null);t.default=a.exports}}]); \ No newline at end of file diff --git a/assets/js/19.6bcf995d.js b/assets/js/19.fd7c2efa.js similarity index 97% rename from assets/js/19.6bcf995d.js rename to assets/js/19.fd7c2efa.js index 3e10c17cc..08d022e08 100644 --- a/assets/js/19.6bcf995d.js +++ b/assets/js/19.fd7c2efa.js @@ -1 +1 @@ -(window.webpackJsonp=window.webpackJsonp||[]).push([[19],{347:function(e,t,i){e.exports=i.p+"assets/img/bitkit-architecture.be0e1a6b.png"},387:function(e,t,i){"use strict";i.r(t);var n=i(7),a=Object(n.a)({},(function(){var e=this,t=e._self._c;return t("ContentSlotsDistributor",{attrs:{"slot-key":e.$parent.slotKey}},[t("p",[e._v("In 2020, the Lightning Network was in its early stages, and most people used custodial wallets. We believe this trend towards custodial wallets contradicts the Bitcoin ethos, so we decided to create a self-custodial alternative that offers a great user experience for all, not just technical users.")]),e._v(" "),t("p",[t("a",{attrs:{href:"https://bitkit.to/",target:"_blank",rel:"noopener noreferrer"}},[e._v("And that's how Bitkit was born."),t("OutboundLink")],1)]),e._v(" "),t("h1",{attrs:{id:"before-ldk"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#before-ldk"}},[e._v("#")]),e._v(" Before LDK")]),e._v(" "),t("p",[e._v("Choosing your tech stack is always challenging. When we first looked into the available Lightning Network implementations, we faced a difficult decision.")]),e._v(" "),t("p",[e._v("Rust-lightning, now known as LDK, had a promising modular architecture but was still in the early stages of development. We considered developing an implementation from scratch to meet Bitkit's specific needs, akin to Acinq's approach with Eclair, but other priorities led us to set this option aside. Ultimately, we adopted LND, the most prevalent implementation at the time. Breez had successfully showcased its potential, making it a logical choice for our stack.")]),e._v(" "),t("p",[e._v("We used LND as the backbone of Bitkit for more than a year, but one aspect stood in the way of providing an optimal user experience: the initialization time. LND utilizes Neutrino, a light Bitcoin client that downloads compact block filters to synchronize with the blockchain. Although it provides better privacy than Electrum Server or Esplora, it's not as fast.")]),e._v(" "),t("p",[e._v("The implications of the initial synchronization time extended well beyond waiting a few seconds. The longer the app stays closed, the longer the synchronization time. We often impatiently closed the app before it finished syncing, causing it to stay out of sync permanently. When we waited for it to fully synchronize, we often found our channel closed, forcing us to start over.")]),e._v(" "),t("p",[e._v("If we were frustrated, Bitkit users would be, too. This reminded us of the second-order effects caused by the technology stacked into our products. John, our CEO, said, “We can’t do this to our users.”")]),e._v(" "),t("p",[e._v("LND was not designed to be modular, making it challenging to swap out Neutrino. To provide the user experience we wanted, we'd need to develop Bitkit on top of a more flexible library. Otherwise, the user experience of self-custodial wallets would continue to fall short, and custodial wallets would remain more popular.")]),e._v(" "),t("p",[e._v("Meanwhile, LDK had come a long way since the early Rust-Lightning days. After revisiting it, its mobile-friendliness convinced us it was the right path forward. The switching cost was high, but we believed our decision would pay off in the long run. So we archived our "),t("a",{attrs:{href:"https://github.com/synonymdev/react-native-lightning",target:"_blank",rel:"noopener noreferrer"}},[e._v("React Native Lightning library"),t("OutboundLink")],1),e._v(" and merged a "),t("a",{attrs:{href:"https://github.com/synonymdev/bitkit/pull/146",target:"_blank",rel:"noopener noreferrer"}},[e._v("pull request"),t("OutboundLink")],1),e._v(", subtracting more than a year of work.")]),e._v(" "),t("p",[e._v("It was time for LDK.")]),e._v(" "),t("h1",{attrs:{id:"what-we-did"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#what-we-did"}},[e._v("#")]),e._v(" What we did")]),e._v(" "),t("p",[e._v("Bitkit is built on React Native, and LDK primarily supports Kotlin and Swift bindings. Not to mention, there wasn't an off-the-shelf "),t("a",{attrs:{href:"https://lightningdevkit.org/blog/announcing-ldk-node/",target:"_blank",rel:"noopener noreferrer"}},[e._v("LDK Node"),t("OutboundLink")],1),e._v(" available back then. This led us to develop the "),t("a",{attrs:{href:"https://github.com/synonymdev/react-native-ldk",target:"_blank",rel:"noopener noreferrer"}},[e._v("React Native LDK library"),t("OutboundLink")],1),e._v(" from the ground up, which has since been adopted by "),t("a",{attrs:{href:"https://github.com/EttaWallet/EttaWallet",target:"_blank",rel:"noopener noreferrer"}},[e._v("Etta"),t("OutboundLink")],1),e._v(" and "),t("a",{attrs:{href:"https://github.com/bennyhodl/baywallet",target:"_blank",rel:"noopener noreferrer"}},[e._v("Bay"),t("OutboundLink")],1),e._v(".")]),e._v(" "),t("p",[e._v("By the time we decided to implement LDK, we had already built an on-chain wallet into Bitkit. LDK's flexibility allowed us to preserve it while we focused on rebuilding the Lightning logic.")]),e._v(" "),t("p",[e._v("We've recently "),t("a",{attrs:{href:"https://github.com/synonymdev/bitkit/pull/1450",target:"_blank",rel:"noopener noreferrer"}},[e._v("refactored the on-chain logic out of Bitkit"),t("OutboundLink")],1),e._v(" into a library, and LDK once again made it easy to retain the required methods and pass them through as needed.")]),e._v(" "),t("p",[e._v("We've also developed a custom "),t("a",{attrs:{href:"https://lightningdevkit.org/key_management/",target:"_blank",rel:"noopener noreferrer"}},[e._v("key manager"),t("OutboundLink")],1),e._v(" so the outputs of channel closure transactions get spent directly to Bitkit's on-chain wallet, removing the need for a costly sweeping transaction.")]),e._v(" "),t("p",[e._v("Throughout both on-chain wallet migrations, LDK enabled us to use Electrum Servers as the source of blockchain data, significantly reducing the initial sync time we've previously encountered.")]),e._v(" "),t("p",[e._v("To further minimize initialization delays, we started using LDK's "),t("a",{attrs:{href:"https://lightningdevkit.org/blog/announcing-rapid-gossip-sync/",target:"_blank",rel:"noopener noreferrer"}},[e._v("Rapid Gossip Sync"),t("OutboundLink")],1),e._v(". It skips client-side signature verification and compresses graph data, shrinking the required bandwidth and CPU resources. Without RGS, the easiest alternative to achieve fast initialization would be delegating routing to our servers, revealing users' payment destinations. With RGS, pathfinding is fast and client-side, preserving Lightning's privacy properties.")]),e._v(" "),t("p",[e._v("The customizability of the "),t("a",{attrs:{href:"https://docs.rs/lightning/*/lightning/routing/scoring/struct.ProbabilisticScorer.html",target:"_blank",rel:"noopener noreferrer"}},[e._v("probabilistic scorer"),t("OutboundLink")],1),e._v(" parameters allowed us to further improve route-finding, translating into a higher payment success rate for users.")]),e._v(" "),t("p",[e._v("In addition, we've architected a custom backup server to meet Bitkit's specific requirements, which LDK was flexible enough to accommodate.")]),e._v(" "),t("figure",[t("img",{attrs:{src:i(347),alt:"Bitkit architecture"}})]),e._v(" "),t("h1",{attrs:{id:"results"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#results"}},[e._v("#")]),e._v(" Results")]),e._v(" "),t("p",[e._v("Migrating to LDK wasn't an easy decision, but time has proven it to be the correct one. The support from the Spiral team was instrumental in easing the migration.")]),e._v(" "),t("p",[e._v("LDK enables us to focus on building a great wallet instead of getting bogged down by the complexities of the Lightning Network protocol.")]),e._v(" "),t("p",[e._v("Ultimately, LDK helps us to narrow the user experience gap between custodial and self-custodial wallets. As long as the lack of options leads people to rely on custodians, LDK will be pivotal in helping us to build a better alternative.")])])}),[],!1,null,null,null);t.default=a.exports}}]); \ No newline at end of file +(window.webpackJsonp=window.webpackJsonp||[]).push([[19],{351:function(e,t,i){e.exports=i.p+"assets/img/bitkit-architecture.be0e1a6b.png"},389:function(e,t,i){"use strict";i.r(t);var n=i(7),a=Object(n.a)({},(function(){var e=this,t=e._self._c;return t("ContentSlotsDistributor",{attrs:{"slot-key":e.$parent.slotKey}},[t("p",[e._v("In 2020, the Lightning Network was in its early stages, and most people used custodial wallets. We believe this trend towards custodial wallets contradicts the Bitcoin ethos, so we decided to create a self-custodial alternative that offers a great user experience for all, not just technical users.")]),e._v(" "),t("p",[t("a",{attrs:{href:"https://bitkit.to/",target:"_blank",rel:"noopener noreferrer"}},[e._v("And that's how Bitkit was born."),t("OutboundLink")],1)]),e._v(" "),t("h1",{attrs:{id:"before-ldk"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#before-ldk"}},[e._v("#")]),e._v(" Before LDK")]),e._v(" "),t("p",[e._v("Choosing your tech stack is always challenging. When we first looked into the available Lightning Network implementations, we faced a difficult decision.")]),e._v(" "),t("p",[e._v("Rust-lightning, now known as LDK, had a promising modular architecture but was still in the early stages of development. We considered developing an implementation from scratch to meet Bitkit's specific needs, akin to Acinq's approach with Eclair, but other priorities led us to set this option aside. Ultimately, we adopted LND, the most prevalent implementation at the time. Breez had successfully showcased its potential, making it a logical choice for our stack.")]),e._v(" "),t("p",[e._v("We used LND as the backbone of Bitkit for more than a year, but one aspect stood in the way of providing an optimal user experience: the initialization time. LND utilizes Neutrino, a light Bitcoin client that downloads compact block filters to synchronize with the blockchain. Although it provides better privacy than Electrum Server or Esplora, it's not as fast.")]),e._v(" "),t("p",[e._v("The implications of the initial synchronization time extended well beyond waiting a few seconds. The longer the app stays closed, the longer the synchronization time. We often impatiently closed the app before it finished syncing, causing it to stay out of sync permanently. When we waited for it to fully synchronize, we often found our channel closed, forcing us to start over.")]),e._v(" "),t("p",[e._v("If we were frustrated, Bitkit users would be, too. This reminded us of the second-order effects caused by the technology stacked into our products. John, our CEO, said, “We can’t do this to our users.”")]),e._v(" "),t("p",[e._v("LND was not designed to be modular, making it challenging to swap out Neutrino. To provide the user experience we wanted, we'd need to develop Bitkit on top of a more flexible library. Otherwise, the user experience of self-custodial wallets would continue to fall short, and custodial wallets would remain more popular.")]),e._v(" "),t("p",[e._v("Meanwhile, LDK had come a long way since the early Rust-Lightning days. After revisiting it, its mobile-friendliness convinced us it was the right path forward. The switching cost was high, but we believed our decision would pay off in the long run. So we archived our "),t("a",{attrs:{href:"https://github.com/synonymdev/react-native-lightning",target:"_blank",rel:"noopener noreferrer"}},[e._v("React Native Lightning library"),t("OutboundLink")],1),e._v(" and merged a "),t("a",{attrs:{href:"https://github.com/synonymdev/bitkit/pull/146",target:"_blank",rel:"noopener noreferrer"}},[e._v("pull request"),t("OutboundLink")],1),e._v(", subtracting more than a year of work.")]),e._v(" "),t("p",[e._v("It was time for LDK.")]),e._v(" "),t("h1",{attrs:{id:"what-we-did"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#what-we-did"}},[e._v("#")]),e._v(" What we did")]),e._v(" "),t("p",[e._v("Bitkit is built on React Native, and LDK primarily supports Kotlin and Swift bindings. Not to mention, there wasn't an off-the-shelf "),t("a",{attrs:{href:"https://lightningdevkit.org/blog/announcing-ldk-node/",target:"_blank",rel:"noopener noreferrer"}},[e._v("LDK Node"),t("OutboundLink")],1),e._v(" available back then. This led us to develop the "),t("a",{attrs:{href:"https://github.com/synonymdev/react-native-ldk",target:"_blank",rel:"noopener noreferrer"}},[e._v("React Native LDK library"),t("OutboundLink")],1),e._v(" from the ground up, which has since been adopted by "),t("a",{attrs:{href:"https://github.com/EttaWallet/EttaWallet",target:"_blank",rel:"noopener noreferrer"}},[e._v("Etta"),t("OutboundLink")],1),e._v(" and "),t("a",{attrs:{href:"https://github.com/bennyhodl/baywallet",target:"_blank",rel:"noopener noreferrer"}},[e._v("Bay"),t("OutboundLink")],1),e._v(".")]),e._v(" "),t("p",[e._v("By the time we decided to implement LDK, we had already built an on-chain wallet into Bitkit. LDK's flexibility allowed us to preserve it while we focused on rebuilding the Lightning logic.")]),e._v(" "),t("p",[e._v("We've recently "),t("a",{attrs:{href:"https://github.com/synonymdev/bitkit/pull/1450",target:"_blank",rel:"noopener noreferrer"}},[e._v("refactored the on-chain logic out of Bitkit"),t("OutboundLink")],1),e._v(" into a library, and LDK once again made it easy to retain the required methods and pass them through as needed.")]),e._v(" "),t("p",[e._v("We've also developed a custom "),t("a",{attrs:{href:"https://lightningdevkit.org/key_management/",target:"_blank",rel:"noopener noreferrer"}},[e._v("key manager"),t("OutboundLink")],1),e._v(" so the outputs of channel closure transactions get spent directly to Bitkit's on-chain wallet, removing the need for a costly sweeping transaction.")]),e._v(" "),t("p",[e._v("Throughout both on-chain wallet migrations, LDK enabled us to use Electrum Servers as the source of blockchain data, significantly reducing the initial sync time we've previously encountered.")]),e._v(" "),t("p",[e._v("To further minimize initialization delays, we started using LDK's "),t("a",{attrs:{href:"https://lightningdevkit.org/blog/announcing-rapid-gossip-sync/",target:"_blank",rel:"noopener noreferrer"}},[e._v("Rapid Gossip Sync"),t("OutboundLink")],1),e._v(". It skips client-side signature verification and compresses graph data, shrinking the required bandwidth and CPU resources. Without RGS, the easiest alternative to achieve fast initialization would be delegating routing to our servers, revealing users' payment destinations. With RGS, pathfinding is fast and client-side, preserving Lightning's privacy properties.")]),e._v(" "),t("p",[e._v("The customizability of the "),t("a",{attrs:{href:"https://docs.rs/lightning/*/lightning/routing/scoring/struct.ProbabilisticScorer.html",target:"_blank",rel:"noopener noreferrer"}},[e._v("probabilistic scorer"),t("OutboundLink")],1),e._v(" parameters allowed us to further improve route-finding, translating into a higher payment success rate for users.")]),e._v(" "),t("p",[e._v("In addition, we've architected a custom backup server to meet Bitkit's specific requirements, which LDK was flexible enough to accommodate.")]),e._v(" "),t("figure",[t("img",{attrs:{src:i(351),alt:"Bitkit architecture"}})]),e._v(" "),t("h1",{attrs:{id:"results"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#results"}},[e._v("#")]),e._v(" Results")]),e._v(" "),t("p",[e._v("Migrating to LDK wasn't an easy decision, but time has proven it to be the correct one. The support from the Spiral team was instrumental in easing the migration.")]),e._v(" "),t("p",[e._v("LDK enables us to focus on building a great wallet instead of getting bogged down by the complexities of the Lightning Network protocol.")]),e._v(" "),t("p",[e._v("Ultimately, LDK helps us to narrow the user experience gap between custodial and self-custodial wallets. As long as the lack of options leads people to rely on custodians, LDK will be pivotal in helping us to build a better alternative.")])])}),[],!1,null,null,null);t.default=a.exports}}]); \ No newline at end of file diff --git a/assets/js/20.e149ffdd.js b/assets/js/20.101f0f0e.js similarity index 98% rename from assets/js/20.e149ffdd.js rename to assets/js/20.101f0f0e.js index 1ddfe3b47..80301735c 100644 --- a/assets/js/20.e149ffdd.js +++ b/assets/js/20.101f0f0e.js @@ -1 +1 @@ -(window.webpackJsonp=window.webpackJsonp||[]).push([[20],{352:function(e,t,a){e.exports=a.p+"assets/img/cash-app-architecture.b24c7ec1.svg"},389:function(e,t,a){"use strict";a.r(t);var n=a(7),o=Object(n.a)({},(function(){var e=this,t=e._self._c;return t("ContentSlotsDistributor",{attrs:{"slot-key":e.$parent.slotKey}},[t("p",[e._v("Cash App allows users to instantly deposit and withdraw bitcoin over the lightning network. As an engineer on the Cash App Lightning Wallet team, I was very involved in the entire implementation process.")]),e._v(" "),t("p",[e._v("Cash App is the #1 Finance App in the app store – we have extremely high standards for product development and the infrastructure that powers all our cool features. We were looking for a solution that would ensure high reliability, high scalability, and a stellar developer experience. Cash App is the financial hub for millions of people and often the first place an individual acquires bitcoin. It’s important to have a slick user experience and robust infrastructure that can onboard many new users. As a publicly traded company we take security seriously and need the ability to customize our wallet implementation in order to adhere to strict standards.")]),e._v(" "),t("p",[e._v("We chose LDK for various reasons over other implementations. It provided us with a lot of customizability and flexibility. The "),t("a",{attrs:{href:"https://github.com/lightningdevkit/ldk-garbagecollected",target:"_blank",rel:"noopener noreferrer"}},[e._v("Java bindings"),t("OutboundLink")],1),e._v(" let us develop in Kotlin, which is the preferred language for backend services. We also have a great working relationship with the "),t("a",{attrs:{href:"https://spiral.xyz/",target:"_blank",rel:"noopener noreferrer"}},[e._v("Spiral"),t("OutboundLink")],1),e._v(" folks, making it easy to collaborate on more advanced feature requests such as phantom invoices.")]),e._v(" "),t("h1",{attrs:{id:"what-we-did"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#what-we-did"}},[e._v("#")]),e._v(" What we did")]),e._v(" "),t("p",[e._v("LDK allowed us to develop a scalable lightning node infrastructure. Cash App runs multiple wallet nodes and has strict parameters around opening channels and connecting to peers. We have logic that does advanced probing in the background in order to ensure an up-to-date snapshot of liquidity on the lightning network.")]),e._v(" "),t("figure",[t("img",{attrs:{src:a(352),alt:"CashApp architecture"}})]),e._v(" "),t("p",[e._v("Probing is done before every send, allowing us to pre-fetch a route and execute the send once the customer confirms. LDK’s "),t("a",{attrs:{href:"https://lightningdevkit.org/blog/introducing-phantom-node-payments/",target:"_blank",rel:"noopener noreferrer"}},[e._v("phantom node"),t("OutboundLink")],1),e._v(" feature makes it possible to generate invoices that can be claimed by more than one node. We use MySQL to save our channel state data + node metadata in order to quickly shut down and start up nodes at will on different servers. Additionally, LDK lets us run AB tests on different pathfinding algorithms.")]),e._v(" "),t("h1",{attrs:{id:"results"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#results"}},[e._v("#")]),e._v(" Results")]),e._v(" "),t("p",[e._v("LDK made it possible to relatively quickly build an easy-to-use lightning wallet while adhering to the complicated constraints Cash App faces as a publicly traded company with tens of millions of users. Users can now instantly deposit and withdraw bitcoin to Cash App over lightning.")]),e._v(" "),t("p",[e._v("To learn more check out this "),t("a",{attrs:{href:"https://www.youtube.com/watch?v=kbhL5RqL8Aw",target:"_blank",rel:"noopener noreferrer"}},[e._v("presentation"),t("OutboundLink")],1),e._v(" at btc++ explaining some of the trade-offs the Cash App team had to think about when comparing LDK to other solutions.")])])}),[],!1,null,null,null);t.default=o.exports}}]); \ No newline at end of file +(window.webpackJsonp=window.webpackJsonp||[]).push([[20],{352:function(e,t,a){e.exports=a.p+"assets/img/cash-app-architecture.b24c7ec1.svg"},390:function(e,t,a){"use strict";a.r(t);var n=a(7),o=Object(n.a)({},(function(){var e=this,t=e._self._c;return t("ContentSlotsDistributor",{attrs:{"slot-key":e.$parent.slotKey}},[t("p",[e._v("Cash App allows users to instantly deposit and withdraw bitcoin over the lightning network. As an engineer on the Cash App Lightning Wallet team, I was very involved in the entire implementation process.")]),e._v(" "),t("p",[e._v("Cash App is the #1 Finance App in the app store – we have extremely high standards for product development and the infrastructure that powers all our cool features. We were looking for a solution that would ensure high reliability, high scalability, and a stellar developer experience. Cash App is the financial hub for millions of people and often the first place an individual acquires bitcoin. It’s important to have a slick user experience and robust infrastructure that can onboard many new users. As a publicly traded company we take security seriously and need the ability to customize our wallet implementation in order to adhere to strict standards.")]),e._v(" "),t("p",[e._v("We chose LDK for various reasons over other implementations. It provided us with a lot of customizability and flexibility. The "),t("a",{attrs:{href:"https://github.com/lightningdevkit/ldk-garbagecollected",target:"_blank",rel:"noopener noreferrer"}},[e._v("Java bindings"),t("OutboundLink")],1),e._v(" let us develop in Kotlin, which is the preferred language for backend services. We also have a great working relationship with the "),t("a",{attrs:{href:"https://spiral.xyz/",target:"_blank",rel:"noopener noreferrer"}},[e._v("Spiral"),t("OutboundLink")],1),e._v(" folks, making it easy to collaborate on more advanced feature requests such as phantom invoices.")]),e._v(" "),t("h1",{attrs:{id:"what-we-did"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#what-we-did"}},[e._v("#")]),e._v(" What we did")]),e._v(" "),t("p",[e._v("LDK allowed us to develop a scalable lightning node infrastructure. Cash App runs multiple wallet nodes and has strict parameters around opening channels and connecting to peers. We have logic that does advanced probing in the background in order to ensure an up-to-date snapshot of liquidity on the lightning network.")]),e._v(" "),t("figure",[t("img",{attrs:{src:a(352),alt:"CashApp architecture"}})]),e._v(" "),t("p",[e._v("Probing is done before every send, allowing us to pre-fetch a route and execute the send once the customer confirms. LDK’s "),t("a",{attrs:{href:"https://lightningdevkit.org/blog/introducing-phantom-node-payments/",target:"_blank",rel:"noopener noreferrer"}},[e._v("phantom node"),t("OutboundLink")],1),e._v(" feature makes it possible to generate invoices that can be claimed by more than one node. We use MySQL to save our channel state data + node metadata in order to quickly shut down and start up nodes at will on different servers. Additionally, LDK lets us run AB tests on different pathfinding algorithms.")]),e._v(" "),t("h1",{attrs:{id:"results"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#results"}},[e._v("#")]),e._v(" Results")]),e._v(" "),t("p",[e._v("LDK made it possible to relatively quickly build an easy-to-use lightning wallet while adhering to the complicated constraints Cash App faces as a publicly traded company with tens of millions of users. Users can now instantly deposit and withdraw bitcoin to Cash App over lightning.")]),e._v(" "),t("p",[e._v("To learn more check out this "),t("a",{attrs:{href:"https://www.youtube.com/watch?v=kbhL5RqL8Aw",target:"_blank",rel:"noopener noreferrer"}},[e._v("presentation"),t("OutboundLink")],1),e._v(" at btc++ explaining some of the trade-offs the Cash App team had to think about when comparing LDK to other solutions.")])])}),[],!1,null,null,null);t.default=o.exports}}]); \ No newline at end of file diff --git a/assets/js/21.4c409f2f.js b/assets/js/21.2cf82c2f.js similarity index 98% rename from assets/js/21.4c409f2f.js rename to assets/js/21.2cf82c2f.js index 278437ed4..c0f6035a5 100644 --- a/assets/js/21.4c409f2f.js +++ b/assets/js/21.2cf82c2f.js @@ -1 +1 @@ -(window.webpackJsonp=window.webpackJsonp||[]).push([[21],{355:function(e,t,a){e.exports=a.p+"assets/img/ldk-roadmap.08c2e5db.png"},393:function(e,t,a){"use strict";a.r(t);var r=a(7),o=Object(r.a)({},(function(){var e=this,t=e._self._c;return t("ContentSlotsDistributor",{attrs:{"slot-key":e.$parent.slotKey}},[t("p",[e._v("LDK is going to have a big year. Several key features are actively being developed or expected to be developed in the next few quarters. There are also a few projects of interest that don’t yet have any committed developers. If you want to get involved, hop into the "),t("a",{attrs:{href:"https://discord.gg/xaYE3pDQpm",target:"_blank",rel:"noopener noreferrer"}},[e._v("Discord Server"),t("OutboundLink")],1),e._v(" or "),t("a",{attrs:{href:"https://github.com/lightningdevkit",target:"_blank",rel:"noopener noreferrer"}},[e._v("GitHub repo"),t("OutboundLink")],1),e._v(".")]),e._v(" "),t("p",[e._v("As a reminder, the LDK project is community-driven with no centralized authority. Anyone is welcome to contribute and propose ideas at any point. Additionally, it’s extremely important to listen to LDK users. The timeline listed below is just an estimate that may shift if a user request needs to be prioritized over another project.")]),e._v(" "),t("figure",[t("img",{attrs:{src:a(355),alt:"OM"}})]),e._v(" "),t("h1",{attrs:{id:"activecommited-projects"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#activecommited-projects"}},[e._v("#")]),e._v(" Active/Commited Projects")]),e._v(" "),t("h2",{attrs:{id:"ldk-node"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#ldk-node"}},[e._v("#")]),e._v(" LDK Node")]),e._v(" "),t("p",[e._v("LDK Node is an implementation of an LDK-based LN wallet and node. The LDK API is a powerful, extensive API that gives developers significant control, which can be intimidating to the uninitiated user. The LDK Node project delivers a fully functional LN wallet/node. The mobile-optimized recipe includes a "),t("a",{attrs:{href:"https://bitcoindevkit.org",target:"_blank",rel:"noopener noreferrer"}},[e._v("BDK"),t("OutboundLink")],1),e._v("-based on-chain wallet, integration with Esplora/Electrum for block data, "),t("a",{attrs:{href:"https://docs.rs/lightning-rapid-gossip-sync/*/lightning_rapid_gossip_sync/",target:"_blank",rel:"noopener noreferrer"}},[e._v("RGS"),t("OutboundLink")],1),e._v(" for performant mobile pathfinding, use of SQLite for local data storage, and VSS (once it is ready) for cloud backup of LN and other wallet state. The end result is a very small API surface (~15 methods vs. the >900 methods in LDK API), making it extremely easy to build a functioning mobile wallet in less than a day.")]),e._v(" "),t("p",[e._v("LDK Node can serve a variety of purposes for developers. For starters, it provides a simple way to get a mobile LN node/wallet up and running. Developers are then able to prototype the experience they’re imagining, and in some cases this will be sufficient for them to build and launch their product in production.")]),e._v(" "),t("p",[e._v("In other cases, developers will come to realize more customization is necessary, and they’ll have a couple of options at their disposal:")]),e._v(" "),t("ol",[t("li",[e._v("Build using the lower-level, more powerful LDK API and reference the LDK Node as an example.")]),e._v(" "),t("li",[e._v("Fork the LDK Node code and make custom modifications themselves. This has the benefit of reusing most of the LDK Node code. However, this requires knowledge of Rust and exposing more of the LDK API in LDK Node.")])]),e._v(" "),t("p",[e._v("While LDK Node is written in Rust, it is anticipated many languages will be supported through "),t("a",{attrs:{href:"https://github.com/mozilla/uniffi-rs",target:"_blank",rel:"noopener noreferrer"}},[e._v("UniFFI"),t("OutboundLink")],1),e._v(" or other mechanisms, including:")]),e._v(" "),t("ul",[t("li",[e._v("Java/Kotlin (near term)")]),e._v(" "),t("li",[e._v("Swift (near term)")]),e._v(" "),t("li",[e._v("Python (near term)")]),e._v(" "),t("li",[e._v("Flutter (near term)")]),e._v(" "),t("li",[e._v("React Native (near term)")]),e._v(" "),t("li",[e._v("Web (medium term)")])]),e._v(" "),t("p",[e._v("Through the development of LDK Node, it has been observed that most of the code can also be leveraged for a server configuration. The LDK project is conducting ongoing customer research to identify the needs and requirements for this configuration. The end result might be an LDK Node server daemon with a small RPC API.")]),e._v(" "),t("p",[e._v("The plan is to launch an initial version of LDK Node for mobile in Q2 2023 with continued improvements over time.")]),e._v(" "),t("h2",{attrs:{id:"bolt-12"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#bolt-12"}},[e._v("#")]),e._v(" BOLT 12")]),e._v(" "),t("p",[e._v("As of the 114 release, LDK supports onion messages and parsing BOLT 12 messages. It is expected to have full BOLT 12 send/receive support including blinded paths and compatibility with other BOLT 12 implementations in Q2 of 2023.")]),e._v(" "),t("h2",{attrs:{id:"anchor-outputs"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#anchor-outputs"}},[e._v("#")]),e._v(" Anchor Outputs")]),e._v(" "),t("p",[e._v("LDK should fully support anchor outputs by Q2 2023.")]),e._v(" "),t("h2",{attrs:{id:"vss"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#vss"}},[e._v("#")]),e._v(" VSS")]),e._v(" "),t("p",[e._v("VSS (Versioned Storage Service) addresses two problems. First, it offers a cloud backup for (encrypted) LN state and other wallet data that is crucial for recovery if the phone is lost or otherwise unavailable. Second, VSS will enable support for multi-device access to the same wallet, handling the synchronization properly so the wallet doesn’t wind up in a confused state. The first phase is expected to be released in Q2 2023. The second phase will be subject to monitoring for demand from wallets and may slip to 2024.")]),e._v(" "),t("h2",{attrs:{id:"improved-async-ness-in-ldk-api"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#improved-async-ness-in-ldk-api"}},[e._v("#")]),e._v(" Improved Async-ness in LDK API")]),e._v(" "),t("p",[e._v("The Rust language originally did not support async but it was added after the rust-lightning project started. Thus, LDK itself initially only supported synchronous calls, but over time LDK is adding more async support throughout the API.")]),e._v(" "),t("h2",{attrs:{id:"simple-taproot-channels"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#simple-taproot-channels"}},[e._v("#")]),e._v(" Simple Taproot Channels")]),e._v(" "),t("p",[e._v("Work has been ongoing since last fall to add "),t("a",{attrs:{href:"https://github.com/lightning/bolts/pull/995",target:"_blank",rel:"noopener noreferrer"}},[e._v("simple taproot channels"),t("OutboundLink")],1),e._v(". LDK developers have provided feedback to the Taproot protocol specification which has resulted in improvements, and it is now close to finalizing simple channels. While LDK has its own MuSig implementation for development purposes, the LDK project will wait for the "),t("a",{attrs:{href:"https://github.com/BlockstreamResearch/secp256k1-zkp/pull/211",target:"_blank",rel:"noopener noreferrer"}},[e._v("libsecp implementation"),t("OutboundLink")],1),e._v(" as well as "),t("a",{attrs:{href:"https://github.com/BlockstreamResearch/rust-secp256k1-zkp/pull/48",target:"_blank",rel:"noopener noreferrer"}},[e._v("Rust bindings"),t("OutboundLink")],1),e._v(" in order to have the highest security assurances. The hope is that the spec, libsecp, and the LDK implementation all come together for a Q2 2023 release.")]),e._v(" "),t("h2",{attrs:{id:"dual-funded-channels"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#dual-funded-channels"}},[e._v("#")]),e._v(" Dual-Funded Channels")]),e._v(" "),t("p",[e._v("Some work "),t("a",{attrs:{href:"https://github.com/lightningdevkit/rust-lightning/issues/1621",target:"_blank",rel:"noopener noreferrer"}},[e._v("has begun"),t("OutboundLink")],1),e._v(" such as refactoring and implementing the "),t("a",{attrs:{href:"https://github.com/lightning/bolts/pull/851",target:"_blank",rel:"noopener noreferrer"}},[e._v("interactive tx protocol"),t("OutboundLink")],1),e._v(". Dual-funded channels might make a release in Q2 2023, but more likely Q3 2023.")]),e._v(" "),t("h2",{attrs:{id:"splicing"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#splicing"}},[e._v("#")]),e._v(" Splicing")]),e._v(" "),t("p",[e._v("Work has not yet begun on splicing due to other commitments, but several developers have committed to working on it as a next project. Work is expected to commence in Q2. Given work hasn’t started yet, it is hard to estimate completion, but an aim for Q3 2023 seems reasonable at this point.")]),e._v(" "),t("h2",{attrs:{id:"async-payments"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#async-payments"}},[e._v("#")]),e._v(" Async Payments")]),e._v(" "),t("p",[e._v("The "),t("a",{attrs:{href:"https://github.com/lightning/bolts/pull/989#issuecomment-1325389542",target:"_blank",rel:"noopener noreferrer"}},[e._v("async payments proposal"),t("OutboundLink")],1),e._v(" will substantially improve the mobile wallet user experience by allowing people to receive payments under any conditions. The general design and workflow has been "),t("a",{attrs:{href:"https://gist.github.com/remyers/e0d2bedb7bc87371d1bdbbb6fff2edd1",target:"_blank",rel:"noopener noreferrer"}},[e._v("mostly fleshed out"),t("OutboundLink")],1),e._v(". The initial plan is to build a prototype and improve the specification along the way.")]),e._v(" "),t("p",[e._v("The work will be broken down into two phases. The first phase will support async receive and the second will support async send. The reasoning behind this two stage approach is that the first phase has value on its own. Any custodial service, which will naturally have persistent internet, would then be able to reliably send payments to recipients without a persistent internet connection (mobile phones, web browser wallets, etc.).")]),e._v(" "),t("p",[e._v("The second phase is of course necessary for wallets sending from a phone or web browser. This will require support of trampoline in order to retry payments in a trustless way from the sender’s peer (eg an LSP).")]),e._v(" "),t("p",[e._v("LDK is just starting this development, so timeframes have large error bars, but probably the best case scenario would be delivering a working demonstration of phase 1 in Q3 2023 and phase 2 in Q4 2023. In addition to a working demonstration, it is expected to publish a complete specification for each phase that will be available for feedback by the development community.")]),e._v(" "),t("h2",{attrs:{id:"ptlcs"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#ptlcs"}},[e._v("#")]),e._v(" PTLCs")]),e._v(" "),t("p",[e._v("The LDK project intends to contribute to the specification and development of PTLCs in 2023. The plan is to build upon previous work ("),t("a",{attrs:{href:"https://lists.linuxfoundation.org/pipermail/lightning-dev/2021-October/003278.html",target:"_blank",rel:"noopener noreferrer"}},[e._v("here"),t("OutboundLink")],1),e._v(" and "),t("a",{attrs:{href:"https://lists.linuxfoundation.org/pipermail/lightning-dev/2021-December/003377.html",target:"_blank",rel:"noopener noreferrer"}},[e._v("here"),t("OutboundLink")],1),e._v(") by building a prototype and improving the specification. The ideal outcome is a specification that comes out later this year which gains developer consensus and a complete implementation in LDK. By 2024, hopefully there are multiple implementations and initial deployment throughout the network.")]),e._v(" "),t("h1",{attrs:{id:"prospective-future-projects"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#prospective-future-projects"}},[e._v("#")]),e._v(" Prospective Future Projects")]),e._v(" "),t("h2",{attrs:{id:"additional-language-bindings"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#additional-language-bindings"}},[e._v("#")]),e._v(" Additional Language Bindings")]),e._v(" "),t("p",[e._v("LDK already supports many languages, but there are several unsupported languages/frameworks that are used by existing applications, including:")]),e._v(" "),t("ul",[t("li",[e._v("C#")]),e._v(" "),t("li",[e._v("Python")]),e._v(" "),t("li",[e._v("Go")]),e._v(" "),t("li",[e._v("Flutter")])]),e._v(" "),t("h2",{attrs:{id:"custom-scripts"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#custom-scripts"}},[e._v("#")]),e._v(" Custom Scripts")]),e._v(" "),t("p",[e._v("LDK currently only supports the standard LN protocol spec script, however, it is possible to make LDK more flexible and allow 3rd parties to create custom scripts for applications such as taproot, DLCs, or Taro.")]),e._v(" "),t("h2",{attrs:{id:"dynamic-commitments"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#dynamic-commitments"}},[e._v("#")]),e._v(" Dynamic Commitments")]),e._v(" "),t("p",[e._v("See "),t("a",{attrs:{href:"https://lists.linuxfoundation.org/pipermail/lightning-dev/2022-March/003531.html",target:"_blank",rel:"noopener noreferrer"}},[e._v("this mailing list post"),t("OutboundLink")],1),e._v(" for reference.")])])}),[],!1,null,null,null);t.default=o.exports}}]); \ No newline at end of file +(window.webpackJsonp=window.webpackJsonp||[]).push([[21],{353:function(e,t,a){e.exports=a.p+"assets/img/ldk-roadmap.08c2e5db.png"},392:function(e,t,a){"use strict";a.r(t);var r=a(7),o=Object(r.a)({},(function(){var e=this,t=e._self._c;return t("ContentSlotsDistributor",{attrs:{"slot-key":e.$parent.slotKey}},[t("p",[e._v("LDK is going to have a big year. Several key features are actively being developed or expected to be developed in the next few quarters. There are also a few projects of interest that don’t yet have any committed developers. If you want to get involved, hop into the "),t("a",{attrs:{href:"https://discord.gg/xaYE3pDQpm",target:"_blank",rel:"noopener noreferrer"}},[e._v("Discord Server"),t("OutboundLink")],1),e._v(" or "),t("a",{attrs:{href:"https://github.com/lightningdevkit",target:"_blank",rel:"noopener noreferrer"}},[e._v("GitHub repo"),t("OutboundLink")],1),e._v(".")]),e._v(" "),t("p",[e._v("As a reminder, the LDK project is community-driven with no centralized authority. Anyone is welcome to contribute and propose ideas at any point. Additionally, it’s extremely important to listen to LDK users. The timeline listed below is just an estimate that may shift if a user request needs to be prioritized over another project.")]),e._v(" "),t("figure",[t("img",{attrs:{src:a(353),alt:"OM"}})]),e._v(" "),t("h1",{attrs:{id:"activecommited-projects"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#activecommited-projects"}},[e._v("#")]),e._v(" Active/Commited Projects")]),e._v(" "),t("h2",{attrs:{id:"ldk-node"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#ldk-node"}},[e._v("#")]),e._v(" LDK Node")]),e._v(" "),t("p",[e._v("LDK Node is an implementation of an LDK-based LN wallet and node. The LDK API is a powerful, extensive API that gives developers significant control, which can be intimidating to the uninitiated user. The LDK Node project delivers a fully functional LN wallet/node. The mobile-optimized recipe includes a "),t("a",{attrs:{href:"https://bitcoindevkit.org",target:"_blank",rel:"noopener noreferrer"}},[e._v("BDK"),t("OutboundLink")],1),e._v("-based on-chain wallet, integration with Esplora/Electrum for block data, "),t("a",{attrs:{href:"https://docs.rs/lightning-rapid-gossip-sync/*/lightning_rapid_gossip_sync/",target:"_blank",rel:"noopener noreferrer"}},[e._v("RGS"),t("OutboundLink")],1),e._v(" for performant mobile pathfinding, use of SQLite for local data storage, and VSS (once it is ready) for cloud backup of LN and other wallet state. The end result is a very small API surface (~15 methods vs. the >900 methods in LDK API), making it extremely easy to build a functioning mobile wallet in less than a day.")]),e._v(" "),t("p",[e._v("LDK Node can serve a variety of purposes for developers. For starters, it provides a simple way to get a mobile LN node/wallet up and running. Developers are then able to prototype the experience they’re imagining, and in some cases this will be sufficient for them to build and launch their product in production.")]),e._v(" "),t("p",[e._v("In other cases, developers will come to realize more customization is necessary, and they’ll have a couple of options at their disposal:")]),e._v(" "),t("ol",[t("li",[e._v("Build using the lower-level, more powerful LDK API and reference the LDK Node as an example.")]),e._v(" "),t("li",[e._v("Fork the LDK Node code and make custom modifications themselves. This has the benefit of reusing most of the LDK Node code. However, this requires knowledge of Rust and exposing more of the LDK API in LDK Node.")])]),e._v(" "),t("p",[e._v("While LDK Node is written in Rust, it is anticipated many languages will be supported through "),t("a",{attrs:{href:"https://github.com/mozilla/uniffi-rs",target:"_blank",rel:"noopener noreferrer"}},[e._v("UniFFI"),t("OutboundLink")],1),e._v(" or other mechanisms, including:")]),e._v(" "),t("ul",[t("li",[e._v("Java/Kotlin (near term)")]),e._v(" "),t("li",[e._v("Swift (near term)")]),e._v(" "),t("li",[e._v("Python (near term)")]),e._v(" "),t("li",[e._v("Flutter (near term)")]),e._v(" "),t("li",[e._v("React Native (near term)")]),e._v(" "),t("li",[e._v("Web (medium term)")])]),e._v(" "),t("p",[e._v("Through the development of LDK Node, it has been observed that most of the code can also be leveraged for a server configuration. The LDK project is conducting ongoing customer research to identify the needs and requirements for this configuration. The end result might be an LDK Node server daemon with a small RPC API.")]),e._v(" "),t("p",[e._v("The plan is to launch an initial version of LDK Node for mobile in Q2 2023 with continued improvements over time.")]),e._v(" "),t("h2",{attrs:{id:"bolt-12"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#bolt-12"}},[e._v("#")]),e._v(" BOLT 12")]),e._v(" "),t("p",[e._v("As of the 114 release, LDK supports onion messages and parsing BOLT 12 messages. It is expected to have full BOLT 12 send/receive support including blinded paths and compatibility with other BOLT 12 implementations in Q2 of 2023.")]),e._v(" "),t("h2",{attrs:{id:"anchor-outputs"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#anchor-outputs"}},[e._v("#")]),e._v(" Anchor Outputs")]),e._v(" "),t("p",[e._v("LDK should fully support anchor outputs by Q2 2023.")]),e._v(" "),t("h2",{attrs:{id:"vss"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#vss"}},[e._v("#")]),e._v(" VSS")]),e._v(" "),t("p",[e._v("VSS (Versioned Storage Service) addresses two problems. First, it offers a cloud backup for (encrypted) LN state and other wallet data that is crucial for recovery if the phone is lost or otherwise unavailable. Second, VSS will enable support for multi-device access to the same wallet, handling the synchronization properly so the wallet doesn’t wind up in a confused state. The first phase is expected to be released in Q2 2023. The second phase will be subject to monitoring for demand from wallets and may slip to 2024.")]),e._v(" "),t("h2",{attrs:{id:"improved-async-ness-in-ldk-api"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#improved-async-ness-in-ldk-api"}},[e._v("#")]),e._v(" Improved Async-ness in LDK API")]),e._v(" "),t("p",[e._v("The Rust language originally did not support async but it was added after the rust-lightning project started. Thus, LDK itself initially only supported synchronous calls, but over time LDK is adding more async support throughout the API.")]),e._v(" "),t("h2",{attrs:{id:"simple-taproot-channels"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#simple-taproot-channels"}},[e._v("#")]),e._v(" Simple Taproot Channels")]),e._v(" "),t("p",[e._v("Work has been ongoing since last fall to add "),t("a",{attrs:{href:"https://github.com/lightning/bolts/pull/995",target:"_blank",rel:"noopener noreferrer"}},[e._v("simple taproot channels"),t("OutboundLink")],1),e._v(". LDK developers have provided feedback to the Taproot protocol specification which has resulted in improvements, and it is now close to finalizing simple channels. While LDK has its own MuSig implementation for development purposes, the LDK project will wait for the "),t("a",{attrs:{href:"https://github.com/BlockstreamResearch/secp256k1-zkp/pull/211",target:"_blank",rel:"noopener noreferrer"}},[e._v("libsecp implementation"),t("OutboundLink")],1),e._v(" as well as "),t("a",{attrs:{href:"https://github.com/BlockstreamResearch/rust-secp256k1-zkp/pull/48",target:"_blank",rel:"noopener noreferrer"}},[e._v("Rust bindings"),t("OutboundLink")],1),e._v(" in order to have the highest security assurances. The hope is that the spec, libsecp, and the LDK implementation all come together for a Q2 2023 release.")]),e._v(" "),t("h2",{attrs:{id:"dual-funded-channels"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#dual-funded-channels"}},[e._v("#")]),e._v(" Dual-Funded Channels")]),e._v(" "),t("p",[e._v("Some work "),t("a",{attrs:{href:"https://github.com/lightningdevkit/rust-lightning/issues/1621",target:"_blank",rel:"noopener noreferrer"}},[e._v("has begun"),t("OutboundLink")],1),e._v(" such as refactoring and implementing the "),t("a",{attrs:{href:"https://github.com/lightning/bolts/pull/851",target:"_blank",rel:"noopener noreferrer"}},[e._v("interactive tx protocol"),t("OutboundLink")],1),e._v(". Dual-funded channels might make a release in Q2 2023, but more likely Q3 2023.")]),e._v(" "),t("h2",{attrs:{id:"splicing"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#splicing"}},[e._v("#")]),e._v(" Splicing")]),e._v(" "),t("p",[e._v("Work has not yet begun on splicing due to other commitments, but several developers have committed to working on it as a next project. Work is expected to commence in Q2. Given work hasn’t started yet, it is hard to estimate completion, but an aim for Q3 2023 seems reasonable at this point.")]),e._v(" "),t("h2",{attrs:{id:"async-payments"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#async-payments"}},[e._v("#")]),e._v(" Async Payments")]),e._v(" "),t("p",[e._v("The "),t("a",{attrs:{href:"https://github.com/lightning/bolts/pull/989#issuecomment-1325389542",target:"_blank",rel:"noopener noreferrer"}},[e._v("async payments proposal"),t("OutboundLink")],1),e._v(" will substantially improve the mobile wallet user experience by allowing people to receive payments under any conditions. The general design and workflow has been "),t("a",{attrs:{href:"https://gist.github.com/remyers/e0d2bedb7bc87371d1bdbbb6fff2edd1",target:"_blank",rel:"noopener noreferrer"}},[e._v("mostly fleshed out"),t("OutboundLink")],1),e._v(". The initial plan is to build a prototype and improve the specification along the way.")]),e._v(" "),t("p",[e._v("The work will be broken down into two phases. The first phase will support async receive and the second will support async send. The reasoning behind this two stage approach is that the first phase has value on its own. Any custodial service, which will naturally have persistent internet, would then be able to reliably send payments to recipients without a persistent internet connection (mobile phones, web browser wallets, etc.).")]),e._v(" "),t("p",[e._v("The second phase is of course necessary for wallets sending from a phone or web browser. This will require support of trampoline in order to retry payments in a trustless way from the sender’s peer (eg an LSP).")]),e._v(" "),t("p",[e._v("LDK is just starting this development, so timeframes have large error bars, but probably the best case scenario would be delivering a working demonstration of phase 1 in Q3 2023 and phase 2 in Q4 2023. In addition to a working demonstration, it is expected to publish a complete specification for each phase that will be available for feedback by the development community.")]),e._v(" "),t("h2",{attrs:{id:"ptlcs"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#ptlcs"}},[e._v("#")]),e._v(" PTLCs")]),e._v(" "),t("p",[e._v("The LDK project intends to contribute to the specification and development of PTLCs in 2023. The plan is to build upon previous work ("),t("a",{attrs:{href:"https://lists.linuxfoundation.org/pipermail/lightning-dev/2021-October/003278.html",target:"_blank",rel:"noopener noreferrer"}},[e._v("here"),t("OutboundLink")],1),e._v(" and "),t("a",{attrs:{href:"https://lists.linuxfoundation.org/pipermail/lightning-dev/2021-December/003377.html",target:"_blank",rel:"noopener noreferrer"}},[e._v("here"),t("OutboundLink")],1),e._v(") by building a prototype and improving the specification. The ideal outcome is a specification that comes out later this year which gains developer consensus and a complete implementation in LDK. By 2024, hopefully there are multiple implementations and initial deployment throughout the network.")]),e._v(" "),t("h1",{attrs:{id:"prospective-future-projects"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#prospective-future-projects"}},[e._v("#")]),e._v(" Prospective Future Projects")]),e._v(" "),t("h2",{attrs:{id:"additional-language-bindings"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#additional-language-bindings"}},[e._v("#")]),e._v(" Additional Language Bindings")]),e._v(" "),t("p",[e._v("LDK already supports many languages, but there are several unsupported languages/frameworks that are used by existing applications, including:")]),e._v(" "),t("ul",[t("li",[e._v("C#")]),e._v(" "),t("li",[e._v("Python")]),e._v(" "),t("li",[e._v("Go")]),e._v(" "),t("li",[e._v("Flutter")])]),e._v(" "),t("h2",{attrs:{id:"custom-scripts"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#custom-scripts"}},[e._v("#")]),e._v(" Custom Scripts")]),e._v(" "),t("p",[e._v("LDK currently only supports the standard LN protocol spec script, however, it is possible to make LDK more flexible and allow 3rd parties to create custom scripts for applications such as taproot, DLCs, or Taro.")]),e._v(" "),t("h2",{attrs:{id:"dynamic-commitments"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#dynamic-commitments"}},[e._v("#")]),e._v(" Dynamic Commitments")]),e._v(" "),t("p",[e._v("See "),t("a",{attrs:{href:"https://lists.linuxfoundation.org/pipermail/lightning-dev/2022-March/003531.html",target:"_blank",rel:"noopener noreferrer"}},[e._v("this mailing list post"),t("OutboundLink")],1),e._v(" for reference.")])])}),[],!1,null,null,null);t.default=o.exports}}]); \ No newline at end of file diff --git a/assets/js/23.60e41ae2.js b/assets/js/23.8a52fe20.js similarity index 98% rename from assets/js/23.60e41ae2.js rename to assets/js/23.8a52fe20.js index 7928dcb63..8470422ca 100644 --- a/assets/js/23.60e41ae2.js +++ b/assets/js/23.8a52fe20.js @@ -1 +1 @@ -(window.webpackJsonp=window.webpackJsonp||[]).push([[23],{361:function(e,t,a){e.exports=a.p+"assets/img/teos-architecture-diagram.3ab57d46.png"},397:function(e,t,a){"use strict";a.r(t);var n=a(7),o=Object(n.a)({},(function(){var e=this,t=e._self._c;return t("ContentSlotsDistributor",{attrs:{"slot-key":e.$parent.slotKey}},[t("p",[t("a",{attrs:{href:"https://github.com/talaia-labs/rust-teos",target:"_blank",rel:"noopener noreferrer"}},[e._v("The Eye of Satoshi (TEOS)"),t("OutboundLink")],1),e._v(" is a bitcoin watchtower with a specific focus on lightning. Watchtowers are third-party viewing services that help prevent people from cheating on the lightning network by constantly monitoring the bitcoin blockchain for channel breaches. If found, a watchtower will react by penalizing the misbehaving party and sending all funds to its counterpart.")]),e._v(" "),t("p",[e._v("In order for TEOS to work, information is needed from several different building blocks. This includes block data processing (such as reacting to forks/chain splits), interaction with a bitcoin node (for transaction broadcasting), and general tooling around bitcoin/lightning (transaction parsing, data encoding/decoding, lightning P2P messaging, etc).")]),e._v(" "),t("p",[e._v("TEOS does not have strong performance requirements, as data is checked in newly processed blocks approximately every 10 mins. However, if it services a substantial amount of nodes at once or channels with high traffic, it may need to compare processed info against huge amounts of data.")]),e._v(" "),t("h1",{attrs:{id:"what-we-did"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#what-we-did"}},[e._v("#")]),e._v(" What we did?")]),e._v(" "),t("p",[e._v("We initially had a Python implementation, but as the project evolved we realized it could be beneficial to switch to a language that was more robust and had better tooling. Rust was an obvious choice given how well it works for other bitcoin-related projects. Moving away from Python allowed us to drop a substantial amount of dependencies that were unmaintained or maintained by us, and instead use properly maintained counterparts.")]),e._v(" "),t("figure",[t("img",{attrs:{src:a(361),alt:"TEOS architecture"}})]),e._v(" "),t("p",[e._v("While it did take time to perform the Rust re-implementation, it was worth it for several reasons. LDK does a substantial amount of the low-level heavy lifting (e.g. reorg management), allowing us to remove several components of the original design and abstract interaction with bitcoind. Additionally, Python lacks proper support for most of lightning’s functionality, so we would have had to implement and maintain all of the related toolings to support lightning P2P communication features.")]),e._v(" "),t("p",[e._v("Furthermore, LDK supports various lightning features that we may need in the future, such as anchors. At the end of the day, LDK makes it possible to focus on the product/protocol you are building and care less about the low-level lightning/bitcoin parts that are needed.")]),e._v(" "),t("h1",{attrs:{id:"results"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#results"}},[e._v("#")]),e._v(" Results")]),e._v(" "),t("p",[e._v("The TEOS codebase is now more robust and stable, making it easier to contribute to and integrate with other projects.")]),e._v(" "),t("p",[e._v("In terms of functionality, we recently reached the same state as the old Python codebase. We are currently focusing on new features and integrations. Additionally, using Rust and LDK has allowed us to build a healthier community. It’s easier to make improvements to a project when you use the same tools and literally speak the same language.")]),e._v(" "),t("p",[e._v("It's been a pleasure working with the LDK team. They’ve helped us solve several Rust and LDK issues, and have been open to accepting PRs and implementing new functionality that we require.")]),e._v(" "),t("p",[e._v("Learn how you can deploy your own TEOS watchtower on the Bitcoin Developers Youtube "),t("a",{attrs:{href:"https://www.youtube.com/watch?v=8vzNB_NZt2A",target:"_blank",rel:"noopener noreferrer"}},[e._v("channel"),t("OutboundLink")],1),e._v(".")])])}),[],!1,null,null,null);t.default=o.exports}}]); \ No newline at end of file +(window.webpackJsonp=window.webpackJsonp||[]).push([[23],{361:function(e,t,a){e.exports=a.p+"assets/img/teos-architecture-diagram.3ab57d46.png"},398:function(e,t,a){"use strict";a.r(t);var n=a(7),o=Object(n.a)({},(function(){var e=this,t=e._self._c;return t("ContentSlotsDistributor",{attrs:{"slot-key":e.$parent.slotKey}},[t("p",[t("a",{attrs:{href:"https://github.com/talaia-labs/rust-teos",target:"_blank",rel:"noopener noreferrer"}},[e._v("The Eye of Satoshi (TEOS)"),t("OutboundLink")],1),e._v(" is a bitcoin watchtower with a specific focus on lightning. Watchtowers are third-party viewing services that help prevent people from cheating on the lightning network by constantly monitoring the bitcoin blockchain for channel breaches. If found, a watchtower will react by penalizing the misbehaving party and sending all funds to its counterpart.")]),e._v(" "),t("p",[e._v("In order for TEOS to work, information is needed from several different building blocks. This includes block data processing (such as reacting to forks/chain splits), interaction with a bitcoin node (for transaction broadcasting), and general tooling around bitcoin/lightning (transaction parsing, data encoding/decoding, lightning P2P messaging, etc).")]),e._v(" "),t("p",[e._v("TEOS does not have strong performance requirements, as data is checked in newly processed blocks approximately every 10 mins. However, if it services a substantial amount of nodes at once or channels with high traffic, it may need to compare processed info against huge amounts of data.")]),e._v(" "),t("h1",{attrs:{id:"what-we-did"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#what-we-did"}},[e._v("#")]),e._v(" What we did?")]),e._v(" "),t("p",[e._v("We initially had a Python implementation, but as the project evolved we realized it could be beneficial to switch to a language that was more robust and had better tooling. Rust was an obvious choice given how well it works for other bitcoin-related projects. Moving away from Python allowed us to drop a substantial amount of dependencies that were unmaintained or maintained by us, and instead use properly maintained counterparts.")]),e._v(" "),t("figure",[t("img",{attrs:{src:a(361),alt:"TEOS architecture"}})]),e._v(" "),t("p",[e._v("While it did take time to perform the Rust re-implementation, it was worth it for several reasons. LDK does a substantial amount of the low-level heavy lifting (e.g. reorg management), allowing us to remove several components of the original design and abstract interaction with bitcoind. Additionally, Python lacks proper support for most of lightning’s functionality, so we would have had to implement and maintain all of the related toolings to support lightning P2P communication features.")]),e._v(" "),t("p",[e._v("Furthermore, LDK supports various lightning features that we may need in the future, such as anchors. At the end of the day, LDK makes it possible to focus on the product/protocol you are building and care less about the low-level lightning/bitcoin parts that are needed.")]),e._v(" "),t("h1",{attrs:{id:"results"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#results"}},[e._v("#")]),e._v(" Results")]),e._v(" "),t("p",[e._v("The TEOS codebase is now more robust and stable, making it easier to contribute to and integrate with other projects.")]),e._v(" "),t("p",[e._v("In terms of functionality, we recently reached the same state as the old Python codebase. We are currently focusing on new features and integrations. Additionally, using Rust and LDK has allowed us to build a healthier community. It’s easier to make improvements to a project when you use the same tools and literally speak the same language.")]),e._v(" "),t("p",[e._v("It's been a pleasure working with the LDK team. They’ve helped us solve several Rust and LDK issues, and have been open to accepting PRs and implementing new functionality that we require.")]),e._v(" "),t("p",[e._v("Learn how you can deploy your own TEOS watchtower on the Bitcoin Developers Youtube "),t("a",{attrs:{href:"https://www.youtube.com/watch?v=8vzNB_NZt2A",target:"_blank",rel:"noopener noreferrer"}},[e._v("channel"),t("OutboundLink")],1),e._v(".")])])}),[],!1,null,null,null);t.default=o.exports}}]); \ No newline at end of file diff --git a/assets/js/31.975f9e88.js b/assets/js/31.95069fbe.js similarity index 99% rename from assets/js/31.975f9e88.js rename to assets/js/31.95069fbe.js index b96d09a36..cd93cd0c5 100644 --- a/assets/js/31.975f9e88.js +++ b/assets/js/31.95069fbe.js @@ -1 +1 @@ -(window.webpackJsonp=window.webpackJsonp||[]).push([[31],{390:function(e,t,a){"use strict";a.r(t);var n=a(7),s=Object(n.a)({},(function(){var e=this,t=e._self._c;return t("ContentSlotsDistributor",{attrs:{"slot-key":e.$parent.slotKey}},[t("p",[e._v("If you've run a Lightning node, you'll have noticed that initialization can be time-consuming. Merely opening a channel requires six block confirmations or about one hour. However, even if your node already has open channels but has been offline for a while, restarting it still requires fetching the latest channel graph data (commonly referred to as \"gossip”) and verifying that all its channels have remained intact.")]),e._v(" "),t("p",[e._v("While most Lightning implementations have mechanisms to quickly catch up to the latest block, one bottleneck that may remain is the exchange of aforementioned gossip, which rarely takes more than a couple of minutes but significantly impacts UX when initiating locally-routed payments from a mobile device. Assuming that an app remains closed until you need to send a payment, even a one-minute waiting period becomes a major payment flow disruptor. This issue is commonly resolved by sharing the intended payment recipient with a Lightning Service Provider, thus compromising privacy to offload the route calculation to a server.")]),e._v(" "),t("p",[e._v("For that reason, we're very excited to announce Rapid Gossip Sync, a protocol that allows nodes to catch up with channel gossip data by relying on semi-trusted servers.")]),e._v(" "),t("h2",{attrs:{id:"exchanging-gossip-today"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#exchanging-gossip-today"}},[e._v("#")]),e._v(" Exchanging Gossip Today")]),e._v(" "),t("p",[e._v("Before we delve too deeply into the optimizations that Rapid Gossip Sync relies on, first a primer on how gossip works today. It involves three main message types: channel announcements, channel updates, and node announcements. (The last of which isn’t really relevant to this post.)")]),e._v(" "),t("p",[e._v("As their names imply, channel announcements are sent when a public channel opens, and updates when changes are made to a channel. One peculiar characteristic of channels is that they aren't symmetrical: depending on the direction, some of their properties may vary. For instance, if Alice and Bob have a channel, Alice may charge higher fees for forwarding payments to Bob than Bob to Alice. Unlike channel updates, channel announcements do not carry directional information, so that scenario would require that different channel updates be broadcast to the network for each direction. Similarly, opening a new channel also requires sending at least two channel updates to initialize direction-specific properties.")]),e._v(" "),t("p",[e._v("One of the noteworthy properties of gossip is that a lot of data is duplicated across messages. For example, each channel announcement and update contains the genesis block hash. Similarly, each channel announcement contains both nodes’ public keys, exacerbating data redundancy for well-connected nodes. So, to reduce bandwidth requirements, we decided to see if we could strip data to create a more efficient way of conveying the same information.")]),e._v(" "),t("p",[e._v("In the next few paragraphs, we'll outline a selection of the various optimizations we came up with.")]),e._v(" "),t("h2",{attrs:{id:"rapid-gossip-sync"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#rapid-gossip-sync"}},[e._v("#")]),e._v(" Rapid Gossip Sync")]),e._v(" "),t("p",[e._v("Firstly, the idea of Rapid Gossip Sync is that gossip data is pre-processed by one or multiple semi-trusted servers. These validate the signatures sent via regular gossip and verify the channels against the blockchain. This should obviate client-side signature verification and allow us to entirely remove signatures from the messages.")]),e._v(" "),t("p",[e._v("Secondly, the server sends batches of gossip data, representing snapshots of recent channel graphs. Given that the server batches the data, global properties across all announcements and updates (such as the chain hash) can be stripped out and sent just once. Similarly, since clients are primarily interested in new information, a single timestamp (the latest one) suffices to determine what data the client has or hasn't seen before when it requests the latest gossip snapshot.")]),e._v(" "),t("p",[e._v("The most crucial optimization that comes with Rapid Gossip Sync is that it doesn't send redundant updates. So even if a node sends 100 channel updates, and the only mutated property is its base fee, there would be no need to send out any other unchanged properties. To do that, we overloaded the channel flag byte, which would otherwise only use two bits to indicate an update's affected direction and whether a channel is disabled.")]),e._v(" "),t("p",[e._v("Channel updates are sent frequently and often refer to channels the client hasn't seen before, meaning that the server must include all properties, not just the mutated ones. This realization led us to notice that many properties were set to the same value across different channel updates, so we decided to measure what values occurred most frequently. Then, to reduce data overhead, we declare those most commonly occurring values as defaults at the start of every gossip snapshot. Any property whose value matches the default can be omitted from the snapshot if a channel update refers to a previously unknown channel. The only difficulty arising from that optimization is distinguishing whether a channel update is new or incremental. As it happens, the last remaining bit of the channel flags lends itself perfectly for this purpose. This way, when an update is new, a set property bit will indicate a deviation from the default specified at the beginning of the snapshot. Otherwise, that same bit, when set, would instead indicate a mutation. In either case, when a property's bit flag is not set, its corresponding value needn't be sent over the wire.")]),e._v(" "),t("p",[e._v("Finally, short channel IDs need to be specified for each announcement and update. Since they require 8 bytes per message, we were able to reduce memory requirements by sorting announcements and updates incrementally, and then successively specifying channel IDs in terms of their relative delta, which can be expressed in fewer than 8 bytes by using the BigSize data type.")]),e._v(" "),t("h2",{attrs:{id:"rapid-gossip-sync-server"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#rapid-gossip-sync-server"}},[e._v("#")]),e._v(" Rapid Gossip Sync Server")]),e._v(" "),t("p",[e._v("The Rapid Gossip Sync protocol can only function with a corresponding server. Its operating principle is straightforward: connect to a set of peers on the Lightning Network, monitor the gossip, and persist the timestamped changes to a database. Upon receiving a client’s request, determine which changes have occurred after the provided timestamp and serialize the delta in Rapid Gossip Sync’s compact snapshot format. However, this comes with some caveats.")]),e._v(" "),t("p",[e._v('Channel updates sometimes percolate slowly through the network, resulting in disagreements between the included timestamp and what the server detects. To avoid ambiguity, the server marks all announcements and updates with a "seen" timestamp, canonically ordering all events and making difference determination straightforward. Each snapshot returned to the client includes the latest "seen" timestamp across every announcement and update.')]),e._v(" "),t("p",[e._v("Additionally, calculating graph delta on the fly is resource-intensive and can last tens of seconds. To avoid this, the Rapid Gossip Sync server calculates static delta snapshots at regular 24-hour-intervals. This means that any snapshot a client receives is, on average, 12 hours behind the current state of the graph. Depending on your use case, snapshot calculation frequency may be tweaked.")]),e._v(" "),t("h2",{attrs:{id:"trust-model"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#trust-model"}},[e._v("#")]),e._v(" Trust Model")]),e._v(" "),t("p",[e._v("Many mobile Lightning wallets delegate routing to servers, which jeopardizes some of the Lightning Network’s privacy benefits. Despite the marginal improvements stemming from the fact that transactions don’t end up on-chain, your payment history remains one data dump away from becoming public knowledge.")]),e._v(" "),t("p",[e._v("By relying on a Rapid Gossip Sync server, mobile wallets no longer need to compromise UX to gain the privacy benefit of client-side routing. The trust model shifts the onus of verifying the channel graph against the blockchain and validating node signatures to the server. That would allow a malicious Rapid Gossip Sync server to partially omit graph data to force payments to be routed through itself. If the server is widely used, it could also concentrate routing through another network node to facilitate a denial of service attack.")]),e._v(" "),t("p",[e._v("Considering that most mobile Lightning wallets communicate with their developers' servers, these concerns can be easily mitigated by deploying a Rapid Gossip Sync server to enable your mobile wallet to route privately without third parties or sacrificing UX.")]),e._v(" "),t("h2",{attrs:{id:"conclusion"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#conclusion"}},[e._v("#")]),e._v(" Conclusion")]),e._v(" "),t("p",[e._v("Let's look at our data usage improvements with the above optimizations factored in.")]),e._v(" "),t("p",[e._v("Without Rapid Gossip Sync, we measured sync data using a random set of 80,000 channel announcements and 160,000 channel updates and identified an average of approximately 53MB.")]),e._v(" "),t("p",[e._v("With Rapid Gossip Sync, a snapshot representing the same graph took up 4.7MB and, after gzip, only 2MB. The time to process and apply that snapshot on a mobile phone was less than 0.4 seconds. For more detailed numbers, please refer to the "),t("a",{attrs:{href:"https://github.com/lightningdevkit/rust-lightning/tree/main/lightning-rapid-gossip-sync",target:"_blank",rel:"noopener noreferrer"}},[e._v("Rapid Gossip Sync README"),t("OutboundLink")],1),e._v(".")]),e._v(" "),t("p",[e._v("We're excited for you to try Rapid Gossip Sync out and invite you to look at the "),t("a",{attrs:{href:"https://github.com/lightningdevkit/rapid-gossip-sync-server",target:"_blank",rel:"noopener noreferrer"}},[e._v("server code"),t("OutboundLink")],1),e._v(". If you don't wish to operate a Rapid Gossip Sync snapshotting server, feel free to try our deployment, which is available at "),t("a",{attrs:{href:"https://rapidsync.lightningdevkit.org",target:"_blank",rel:"noopener noreferrer"}},[e._v("rapidsync.lightningdevkit.org"),t("OutboundLink")],1),e._v(".")])])}),[],!1,null,null,null);t.default=s.exports}}]); \ No newline at end of file +(window.webpackJsonp=window.webpackJsonp||[]).push([[31],{387:function(e,t,a){"use strict";a.r(t);var n=a(7),s=Object(n.a)({},(function(){var e=this,t=e._self._c;return t("ContentSlotsDistributor",{attrs:{"slot-key":e.$parent.slotKey}},[t("p",[e._v("If you've run a Lightning node, you'll have noticed that initialization can be time-consuming. Merely opening a channel requires six block confirmations or about one hour. However, even if your node already has open channels but has been offline for a while, restarting it still requires fetching the latest channel graph data (commonly referred to as \"gossip”) and verifying that all its channels have remained intact.")]),e._v(" "),t("p",[e._v("While most Lightning implementations have mechanisms to quickly catch up to the latest block, one bottleneck that may remain is the exchange of aforementioned gossip, which rarely takes more than a couple of minutes but significantly impacts UX when initiating locally-routed payments from a mobile device. Assuming that an app remains closed until you need to send a payment, even a one-minute waiting period becomes a major payment flow disruptor. This issue is commonly resolved by sharing the intended payment recipient with a Lightning Service Provider, thus compromising privacy to offload the route calculation to a server.")]),e._v(" "),t("p",[e._v("For that reason, we're very excited to announce Rapid Gossip Sync, a protocol that allows nodes to catch up with channel gossip data by relying on semi-trusted servers.")]),e._v(" "),t("h2",{attrs:{id:"exchanging-gossip-today"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#exchanging-gossip-today"}},[e._v("#")]),e._v(" Exchanging Gossip Today")]),e._v(" "),t("p",[e._v("Before we delve too deeply into the optimizations that Rapid Gossip Sync relies on, first a primer on how gossip works today. It involves three main message types: channel announcements, channel updates, and node announcements. (The last of which isn’t really relevant to this post.)")]),e._v(" "),t("p",[e._v("As their names imply, channel announcements are sent when a public channel opens, and updates when changes are made to a channel. One peculiar characteristic of channels is that they aren't symmetrical: depending on the direction, some of their properties may vary. For instance, if Alice and Bob have a channel, Alice may charge higher fees for forwarding payments to Bob than Bob to Alice. Unlike channel updates, channel announcements do not carry directional information, so that scenario would require that different channel updates be broadcast to the network for each direction. Similarly, opening a new channel also requires sending at least two channel updates to initialize direction-specific properties.")]),e._v(" "),t("p",[e._v("One of the noteworthy properties of gossip is that a lot of data is duplicated across messages. For example, each channel announcement and update contains the genesis block hash. Similarly, each channel announcement contains both nodes’ public keys, exacerbating data redundancy for well-connected nodes. So, to reduce bandwidth requirements, we decided to see if we could strip data to create a more efficient way of conveying the same information.")]),e._v(" "),t("p",[e._v("In the next few paragraphs, we'll outline a selection of the various optimizations we came up with.")]),e._v(" "),t("h2",{attrs:{id:"rapid-gossip-sync"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#rapid-gossip-sync"}},[e._v("#")]),e._v(" Rapid Gossip Sync")]),e._v(" "),t("p",[e._v("Firstly, the idea of Rapid Gossip Sync is that gossip data is pre-processed by one or multiple semi-trusted servers. These validate the signatures sent via regular gossip and verify the channels against the blockchain. This should obviate client-side signature verification and allow us to entirely remove signatures from the messages.")]),e._v(" "),t("p",[e._v("Secondly, the server sends batches of gossip data, representing snapshots of recent channel graphs. Given that the server batches the data, global properties across all announcements and updates (such as the chain hash) can be stripped out and sent just once. Similarly, since clients are primarily interested in new information, a single timestamp (the latest one) suffices to determine what data the client has or hasn't seen before when it requests the latest gossip snapshot.")]),e._v(" "),t("p",[e._v("The most crucial optimization that comes with Rapid Gossip Sync is that it doesn't send redundant updates. So even if a node sends 100 channel updates, and the only mutated property is its base fee, there would be no need to send out any other unchanged properties. To do that, we overloaded the channel flag byte, which would otherwise only use two bits to indicate an update's affected direction and whether a channel is disabled.")]),e._v(" "),t("p",[e._v("Channel updates are sent frequently and often refer to channels the client hasn't seen before, meaning that the server must include all properties, not just the mutated ones. This realization led us to notice that many properties were set to the same value across different channel updates, so we decided to measure what values occurred most frequently. Then, to reduce data overhead, we declare those most commonly occurring values as defaults at the start of every gossip snapshot. Any property whose value matches the default can be omitted from the snapshot if a channel update refers to a previously unknown channel. The only difficulty arising from that optimization is distinguishing whether a channel update is new or incremental. As it happens, the last remaining bit of the channel flags lends itself perfectly for this purpose. This way, when an update is new, a set property bit will indicate a deviation from the default specified at the beginning of the snapshot. Otherwise, that same bit, when set, would instead indicate a mutation. In either case, when a property's bit flag is not set, its corresponding value needn't be sent over the wire.")]),e._v(" "),t("p",[e._v("Finally, short channel IDs need to be specified for each announcement and update. Since they require 8 bytes per message, we were able to reduce memory requirements by sorting announcements and updates incrementally, and then successively specifying channel IDs in terms of their relative delta, which can be expressed in fewer than 8 bytes by using the BigSize data type.")]),e._v(" "),t("h2",{attrs:{id:"rapid-gossip-sync-server"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#rapid-gossip-sync-server"}},[e._v("#")]),e._v(" Rapid Gossip Sync Server")]),e._v(" "),t("p",[e._v("The Rapid Gossip Sync protocol can only function with a corresponding server. Its operating principle is straightforward: connect to a set of peers on the Lightning Network, monitor the gossip, and persist the timestamped changes to a database. Upon receiving a client’s request, determine which changes have occurred after the provided timestamp and serialize the delta in Rapid Gossip Sync’s compact snapshot format. However, this comes with some caveats.")]),e._v(" "),t("p",[e._v('Channel updates sometimes percolate slowly through the network, resulting in disagreements between the included timestamp and what the server detects. To avoid ambiguity, the server marks all announcements and updates with a "seen" timestamp, canonically ordering all events and making difference determination straightforward. Each snapshot returned to the client includes the latest "seen" timestamp across every announcement and update.')]),e._v(" "),t("p",[e._v("Additionally, calculating graph delta on the fly is resource-intensive and can last tens of seconds. To avoid this, the Rapid Gossip Sync server calculates static delta snapshots at regular 24-hour-intervals. This means that any snapshot a client receives is, on average, 12 hours behind the current state of the graph. Depending on your use case, snapshot calculation frequency may be tweaked.")]),e._v(" "),t("h2",{attrs:{id:"trust-model"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#trust-model"}},[e._v("#")]),e._v(" Trust Model")]),e._v(" "),t("p",[e._v("Many mobile Lightning wallets delegate routing to servers, which jeopardizes some of the Lightning Network’s privacy benefits. Despite the marginal improvements stemming from the fact that transactions don’t end up on-chain, your payment history remains one data dump away from becoming public knowledge.")]),e._v(" "),t("p",[e._v("By relying on a Rapid Gossip Sync server, mobile wallets no longer need to compromise UX to gain the privacy benefit of client-side routing. The trust model shifts the onus of verifying the channel graph against the blockchain and validating node signatures to the server. That would allow a malicious Rapid Gossip Sync server to partially omit graph data to force payments to be routed through itself. If the server is widely used, it could also concentrate routing through another network node to facilitate a denial of service attack.")]),e._v(" "),t("p",[e._v("Considering that most mobile Lightning wallets communicate with their developers' servers, these concerns can be easily mitigated by deploying a Rapid Gossip Sync server to enable your mobile wallet to route privately without third parties or sacrificing UX.")]),e._v(" "),t("h2",{attrs:{id:"conclusion"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#conclusion"}},[e._v("#")]),e._v(" Conclusion")]),e._v(" "),t("p",[e._v("Let's look at our data usage improvements with the above optimizations factored in.")]),e._v(" "),t("p",[e._v("Without Rapid Gossip Sync, we measured sync data using a random set of 80,000 channel announcements and 160,000 channel updates and identified an average of approximately 53MB.")]),e._v(" "),t("p",[e._v("With Rapid Gossip Sync, a snapshot representing the same graph took up 4.7MB and, after gzip, only 2MB. The time to process and apply that snapshot on a mobile phone was less than 0.4 seconds. For more detailed numbers, please refer to the "),t("a",{attrs:{href:"https://github.com/lightningdevkit/rust-lightning/tree/main/lightning-rapid-gossip-sync",target:"_blank",rel:"noopener noreferrer"}},[e._v("Rapid Gossip Sync README"),t("OutboundLink")],1),e._v(".")]),e._v(" "),t("p",[e._v("We're excited for you to try Rapid Gossip Sync out and invite you to look at the "),t("a",{attrs:{href:"https://github.com/lightningdevkit/rapid-gossip-sync-server",target:"_blank",rel:"noopener noreferrer"}},[e._v("server code"),t("OutboundLink")],1),e._v(". If you don't wish to operate a Rapid Gossip Sync snapshotting server, feel free to try our deployment, which is available at "),t("a",{attrs:{href:"https://rapidsync.lightningdevkit.org",target:"_blank",rel:"noopener noreferrer"}},[e._v("rapidsync.lightningdevkit.org"),t("OutboundLink")],1),e._v(".")])])}),[],!1,null,null,null);t.default=s.exports}}]); \ No newline at end of file diff --git a/assets/js/32.5c181b9a.js b/assets/js/32.503a0421.js similarity index 99% rename from assets/js/32.5c181b9a.js rename to assets/js/32.503a0421.js index 909a26392..3077f38e3 100644 --- a/assets/js/32.5c181b9a.js +++ b/assets/js/32.503a0421.js @@ -1 +1 @@ -(window.webpackJsonp=window.webpackJsonp||[]).push([[32],{392:function(e,t,n){"use strict";n.r(t);var i=n(7),r=Object(i.a)({},(function(){var e=this,t=e._self._c;return t("ContentSlotsDistributor",{attrs:{"slot-key":e.$parent.slotKey}},[t("p",[e._v("We are excited to release our first blog post, we have a lot to share and a lot to build. We’ll be updating this blog regularly with what we’re working on, new features and the details on new releases.")]),e._v(" "),t("h2",{attrs:{id:"ldwho"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#ldwho"}},[e._v("#")]),e._v(" LDWho?")]),e._v(" "),t("p",[e._v("If you’re reading this, you probably know something about the Lightning Development Kit, the easy-to-use open-source tool that simplifies how developers add highly secure, privacy-preserving Lightning functionality to bitcoin applications. What you might not know is how it got started.")]),e._v(" "),t("p",[e._v("LDK began as a side project developed by Matt Corallo "),t("a",{attrs:{href:"https://twitter.com/TheBlueMatt",target:"_blank",rel:"noopener noreferrer"}},[e._v("@TheBlueMatt"),t("OutboundLink")],1),e._v(" in "),t("a",{attrs:{href:"https://github.com/lightningdevkit/rust-lightning/commit/6185a2819090bd077954244c5e2adaab5efcaa1a",target:"_blank",rel:"noopener noreferrer"}},[e._v("2018"),t("OutboundLink")],1),e._v(" called rust-lightning. One of Matt’s earliest rust-lightning "),t("a",{attrs:{href:"https://www.youtube.com/watch?v=bfAz0vYlDAI",target:"_blank",rel:"noopener noreferrer"}},[e._v("demos"),t("OutboundLink")],1),e._v(" shows how you can take a full Lightning implementation (managing channels, generating messages to send to peers, signatures, on-chain punishment, etc), and use it to create a library with high-level APIs, so developers can build more and agonize less.")]),e._v(" "),t("p",[e._v("This highly specialized library needed to be flexible enough to let developers customize areas like on-chain wallet creation, sourcing blockchain data, and backing up channel states while paving the way for them to make those critical decisions at 10x speed.")]),e._v(" "),t("p",[e._v("Initially supported by "),t("a",{attrs:{href:"https://chaincode.com/",target:"_blank",rel:"noopener noreferrer"}},[e._v("Chaincode Labs"),t("OutboundLink")],1),e._v(" and then by "),t("a",{attrs:{href:"https://spiral.xyz/",target:"_blank",rel:"noopener noreferrer"}},[e._v("Spiral"),t("OutboundLink")],1),e._v(", LDK has gone from a good idea to a mature, "),t("a",{attrs:{href:"https://github.com/lightningdevkit",target:"_blank",rel:"noopener noreferrer"}},[e._v("open-source project"),t("OutboundLink")],1),e._v(" with "),t("a",{attrs:{href:"https://github.com/lightningdevkit/rust-lightning/graphs/contributors",target:"_blank",rel:"noopener noreferrer"}},[e._v("many contributors"),t("OutboundLink")],1),e._v(" in just a few years. LDK is a robust, modular, mobile-friendly SDK that can be "),t("a",{attrs:{href:"https://vimeo.com/showcase/8372504/video/412818125",target:"_blank",rel:"noopener noreferrer"}},[e._v("integrated into existing bitcoin wallets"),t("OutboundLink")],1),e._v(" while significantly "),t("a",{attrs:{href:"https://bitcointv.com/w/sy6s9vVCmDvXr46YtbYcXM",target:"_blank",rel:"noopener noreferrer"}},[e._v("improving how developers integrate Lightning"),t("OutboundLink")],1),e._v(".")]),e._v(" "),t("p",[e._v("Over time, we hope that LDK will become a public good that doesn’t rely on a single entity like Spiral to be sustainable, which is why we’re already fostering a community, empowering non-Spiral participants, and "),t("a",{attrs:{href:"https://spiral.xyz/blog/a-framework-for-sustainable-open-source-bitcoin-development/",target:"_blank",rel:"noopener noreferrer"}},[e._v("gradually reducing Spiral’s influence"),t("OutboundLink")],1),e._v(". Like Bitcoin Core, we expect LDK to have a strong group of volunteers contributing to the project and many entities funding the project.")]),e._v(" "),t("h2",{attrs:{id:"what-advantages-does-ldk-offer-developers"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#what-advantages-does-ldk-offer-developers"}},[e._v("#")]),e._v(" What advantages does LDK offer developers?")]),e._v(" "),t("p",[e._v("Before committing to LDK, we spoke with over 50 wallet developers to learn what challenges they faced. We learned that developing Lightning apps was a universally bad experience, especially in mobile environments, and that a small team of experienced engineers could take up to two years to build a basic Lightning application. So… not great.")]),e._v(" "),t("p",[e._v("LDK is a flexible Lightning implementation that focuses on running the Lightning node on a mobile phone in a non-custodial manner, which has significant privacy and sovereignty benefits. While this presents some technical challenges, non-custodial mobile apps are where LDK specializes, whether someone is building a wallet from scratch or integrating LDK into one that already exists.")]),e._v(" "),t("p",[e._v("Before LDK, if your team wanted to add Lightning functionality to a mobile app, you most likely had to modify and customize an existing implementation like LND to make it suitable for mobile devices. Core Lightning is also hard to run on iPhones. Both of these implementations are out-of-the-box node solutions that provide solid RPC and HTTP interfaces, but are targeted for server environments or simply aren’t suited to mobile.")]),e._v(" "),t("p",[e._v("Furthermore, if you want to turn your on-chain wallet into a unified wallet experience or source chain data from a third-party server using the Electrum protocol for resource-constrained devices, it’s complex, time-consuming, and a huge engineering undertaking.")]),e._v(" "),t("p",[e._v("Maintaining an LN implementation that you can trust with real money is challenging, and different needs exist for routing nodes and mobile nodes. Maintenance costs also increase over time due to ageing codebases, interactions with other layers, and new use cases with different performance and security trade-offs. We see this with "),t("a",{attrs:{href:"https://github.com/breez/breezmobile",target:"_blank",rel:"noopener noreferrer"}},[e._v("Breez"),t("OutboundLink")],1),e._v(" forking "),t("a",{attrs:{href:"https://github.com/breez/lnd",target:"_blank",rel:"noopener noreferrer"}},[e._v("LND"),t("OutboundLink")],1),e._v(" to make it suitable for mobile and ACINQ doing something similar with "),t("a",{attrs:{href:"https://github.com/ACINQ/phoenix",target:"_blank",rel:"noopener noreferrer"}},[e._v("Phoenix"),t("OutboundLink")],1),e._v(" wallet and "),t("a",{attrs:{href:"https://github.com/ACINQ/lightning-kmp",target:"_blank",rel:"noopener noreferrer"}},[e._v("lightning-kmp"),t("OutboundLink")],1),e._v(".")]),e._v(" "),t("p",[e._v("We created LDK in multiple languages with an API-first approach designed to run at the application layer, like Rust’s "),t("a",{attrs:{href:"https://docs.rs/lightning/latest/lightning/chain/chainmonitor/trait.Persist.html",target:"_blank",rel:"noopener noreferrer"}},[e._v("Persist"),t("OutboundLink")],1),e._v(" trait. Persist defines behaviour for persisting channel states but lets you specify whether you write this data to disk or another backup mechanism, such as the cloud. You don’t need to write an LN implementation from scratch or modify an existing one to use LN functionality. Just call our APIs from your app.")]),e._v(" "),t("p",[e._v("Finally (for this section), LDK’s flexibility enables several different architectures without sacrificing security. Its lightweight design can be optimized to run on embedded devices or HSMs (hardware security modules) and it doesn’t make system calls, so it can run in almost any OS environment. For example, you can opt to run some Lightning logic, such as signing transactions and updating channel states on an HSM that has specific "),t("a",{attrs:{href:"https://gitlab.com/lightning-signer/docs/-/blob/master/README.md",target:"_blank",rel:"noopener noreferrer"}},[e._v("spending policies"),t("OutboundLink")],1),e._v(" and manages private keys. Then you connect it to a server with its own TCP/IP stack using a serial communication method such as USB.")]),e._v(" "),t("p",[e._v("Check out this "),t("a",{attrs:{href:"https://www.youtube.com/watch?v=9-81tobFSKg",target:"_blank",rel:"noopener noreferrer"}},[e._v("presentation"),t("OutboundLink")],1),e._v(" at btc++ by "),t("a",{attrs:{href:"https://twitter.com/jkczyz",target:"_blank",rel:"noopener noreferrer"}},[e._v("Jeff Czyz"),t("OutboundLink")],1),e._v(" and "),t("a",{attrs:{href:"https://twitter.com/arikaleph",target:"_blank",rel:"noopener noreferrer"}},[e._v("Arik Sosman"),t("OutboundLink")],1),e._v(" to learn more about LDK "),t("a",{attrs:{href:"https://lightningdevkit.org/introduction/use_cases/",target:"_blank",rel:"noopener noreferrer"}},[e._v("use cases"),t("OutboundLink")],1),e._v(".")]),e._v(" "),t("h2",{attrs:{id:"who-uses-ldk"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#who-uses-ldk"}},[e._v("#")]),e._v(" Who uses LDK?")]),e._v(" "),t("p",[e._v("LDK supports applications that require running many nodes (such as server/custodial apps), letting users run nodes on mobile devices, integrating with existing infrastructure, broad customization options, and resource-constrained embedded systems such as point of sale, IoT, and so on and so on, etc.")]),e._v(" "),t("p",[t("a",{attrs:{href:"https://bluewallet.io",target:"_blank",rel:"noopener noreferrer"}},[e._v("Blue Wallet"),t("OutboundLink")],1),e._v(" was LDK’s patient zero and ideal first adopter since it is both non-custodial and mobile. Their team maintains "),t("a",{attrs:{href:"https://github.com/BlueWallet/rn-ldk",target:"_blank",rel:"noopener noreferrer"}},[e._v("rn-ldk"),t("OutboundLink")],1),e._v(" and runs it on both Android and iOS.The wallet is likely to ship with LDK soon but not before some critical infrastructure is in place. While non-custodial mobile wallets are LDK’s primary use case, that doesn’t make it limited to them.")]),e._v(" "),t("p",[t("a",{attrs:{href:"https://cash.app",target:"_blank",rel:"noopener noreferrer"}},[e._v("CashApp"),t("OutboundLink")],1),e._v(", one of the world’s most used payment apps, chose LDK for its Lightning implementation because of its customizability. While custodial server-based solutions are not the primary use case for LDK, it shows how adaptable the library is. Ryan Loomba recently explained some of the trade-offs their team had to think about when comparing LDK to other solutions "),t("a",{attrs:{href:"https://www.youtube.com/watch?v=kbhL5RqL8Aw",target:"_blank",rel:"noopener noreferrer"}},[e._v("at btc++"),t("OutboundLink")],1),e._v(".")]),e._v(" "),t("p",[t("a",{attrs:{href:"https://l2.technology/sensei",target:"_blank",rel:"noopener noreferrer"}},[e._v("Sensei"),t("OutboundLink")],1),e._v(", an out-of-the-box lightning node solution, is also powered by LDK. Its modular architecture enables a unique multi-node operation mode, letting nodes easily share a network graph, route scoring, and chain data which enables exciting new use cases.")]),e._v(" "),t("p",[e._v("We’re also talking to dozens of developers, some of whom we expect to adopt LDK soon.")]),e._v(" "),t("p",[t("a",{attrs:{href:"https://github.com/orgs/lightningdevkit/discussions/1554",target:"_blank",rel:"noopener noreferrer"}},[e._v("Know someone building a Lightning wallet or related application?"),t("OutboundLink")],1),e._v(" Point them in "),t("a",{attrs:{href:"https://twitter.com/moneyball",target:"_blank",rel:"noopener noreferrer"}},[e._v("@moneyball’s"),t("OutboundLink")],1),e._v(" direction. If you’re already using LDK and have questions, hop into our "),t("a",{attrs:{href:"https://discord.gg/xaYE3pDQpm",target:"_blank",rel:"noopener noreferrer"}},[e._v("Discord"),t("OutboundLink")],1),e._v(" or checkout GitHub "),t("a",{attrs:{href:"https://github.com/orgs/lightningdevkit/discussions",target:"_blank",rel:"noopener noreferrer"}},[e._v("Discussions"),t("OutboundLink")],1)]),e._v(" "),t("h2",{attrs:{id:"what-are-ldk-s-engineering-priorities"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#what-are-ldk-s-engineering-priorities"}},[e._v("#")]),e._v(" What are LDK’s engineering priorities?")]),e._v(" "),t("p",[t("code",[e._v("Offline Receive")]),t("br"),e._v("\nA problem with Lightning UX is that mobile wallets can’t receive payments unless the user is using the app. We’re developing solutions in conjunction with the LN developer community that will let offline nodes receive payments. Spiral’s Matt Corallo has a "),t("a",{attrs:{href:"https://github.com/lightning/bolts/pull/989",target:"_blank",rel:"noopener noreferrer"}},[e._v("pull request"),t("OutboundLink")],1),e._v(" open that proposes a protocol to fix this exact problem. It includes his original post to the Lightning Devs mailing list which is a "),t("a",{attrs:{href:"https://lists.linuxfoundation.org/pipermail/lightning-dev/2021-October/003307.html",target:"_blank",rel:"noopener noreferrer"}},[e._v("pretty good technical"),t("OutboundLink")],1),e._v(" read on this issue if you’re in the mood for one of those.")]),e._v(" "),t("p",[t("code",[e._v("BOLT 12")]),t("br"),e._v("\nThis feature improves privacy by allowing reusable payments over blinded paths and provides a framework for future upgrades that support recurring payments. There’s still work to be done, and it includes implementing route blinding/blinded paths, an onion messages API for requesting invoices, and BOLT 12 invoice parsing.")]),e._v(" "),t("p",[t("code",[e._v("Taproot")]),t("br"),e._v("\nTaproot! People love it. We love it. It’s been several months since full activation, and LDK will start to take advantage of everything it offers. This includes improved on-chain privacy by making current funding channel outputs (2-of-2 multisig) indistinguishable from single sig outputs, and making channel opening and closing transactions look more like regular non-lightning transactions. In addition, we’re looking to support multi-sig channel capabilities as they allow for greater security, redundancy, and flexibility.")]),e._v(" "),t("p",[t("code",[e._v("Language Bindings")]),t("br"),e._v("\nWe’re making existing language integrations feel more native. We currently support Rust, C/C++, Swift, Java, & Kotlin. It’s now in the beta stage, but "),t("a",{attrs:{href:"https://www.npmjs.com/package/lightningdevkit",target:"_blank",rel:"noopener noreferrer"}},[e._v("JavaScript/TypeScript/Wasm"),t("OutboundLink")],1),e._v(" is also supported, and we are prioritizing bug fixing for early adopters. In the future, expect support for C#, Python, Flutter/Dart, and possibly others.")]),e._v(" "),t("p",[e._v("Also in LDK’s future: a simplified API that makes opinionated decisions on behalf of developers that will accelerate getting their apps up and running. Think of it as a Rust crate but using UniFFI to auto-generate language bindings for Kotlin, Swift, Python, and Ruby that expedite basic send/receive functionality.")]),e._v(" "),t("h2",{attrs:{id:"notable-updates"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#notable-updates"}},[e._v("#")]),e._v(" Notable Updates")]),e._v(" "),t("p",[e._v("Phantom Node support is up and running (separate blog post coming soon…ish). This integration adds support for multi-node receive, which enables enterprise-level architecture. This is important since users might need production nodes to receive payments when load balancing is required.")]),e._v(" "),t("p",[e._v("We've introduced a new client-side pathfinding API to LDK that simplifies quickly downloading gossip data from a server. This means that servers can't know who you are paying or how much.")]),e._v(" "),t("p",[e._v("We now support zero conf channels, allowing immediate forwarding of payments after channel opening/receiving for those wanting to build inbound liquidity services.")]),e._v(" "),t("p",[e._v("SCID Aliases (short channel IDs) were added in a recent release and may be negotiated when opening a channel with a peer. This has significant privacy benefits and will likely be the default in the future.")]),e._v(" "),t("p",[e._v("Anything else?")]),e._v(" "),t("p",[e._v("Absolutely. But this post is long enough for now. Keep an eye out for announcements from "),t("a",{attrs:{href:"https://twitter.com/spiralbtc",target:"_blank",rel:"noopener noreferrer"}},[e._v("@spiralbtc"),t("OutboundLink")],1),e._v(" and "),t("a",{attrs:{href:"https://twitter.com/lightningdevkit",target:"_blank",rel:"noopener noreferrer"}},[e._v("@lightningdevkit"),t("OutboundLink")],1),e._v(".")])])}),[],!1,null,null,null);t.default=r.exports}}]); \ No newline at end of file +(window.webpackJsonp=window.webpackJsonp||[]).push([[32],{391:function(e,t,n){"use strict";n.r(t);var i=n(7),r=Object(i.a)({},(function(){var e=this,t=e._self._c;return t("ContentSlotsDistributor",{attrs:{"slot-key":e.$parent.slotKey}},[t("p",[e._v("We are excited to release our first blog post, we have a lot to share and a lot to build. We’ll be updating this blog regularly with what we’re working on, new features and the details on new releases.")]),e._v(" "),t("h2",{attrs:{id:"ldwho"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#ldwho"}},[e._v("#")]),e._v(" LDWho?")]),e._v(" "),t("p",[e._v("If you’re reading this, you probably know something about the Lightning Development Kit, the easy-to-use open-source tool that simplifies how developers add highly secure, privacy-preserving Lightning functionality to bitcoin applications. What you might not know is how it got started.")]),e._v(" "),t("p",[e._v("LDK began as a side project developed by Matt Corallo "),t("a",{attrs:{href:"https://twitter.com/TheBlueMatt",target:"_blank",rel:"noopener noreferrer"}},[e._v("@TheBlueMatt"),t("OutboundLink")],1),e._v(" in "),t("a",{attrs:{href:"https://github.com/lightningdevkit/rust-lightning/commit/6185a2819090bd077954244c5e2adaab5efcaa1a",target:"_blank",rel:"noopener noreferrer"}},[e._v("2018"),t("OutboundLink")],1),e._v(" called rust-lightning. One of Matt’s earliest rust-lightning "),t("a",{attrs:{href:"https://www.youtube.com/watch?v=bfAz0vYlDAI",target:"_blank",rel:"noopener noreferrer"}},[e._v("demos"),t("OutboundLink")],1),e._v(" shows how you can take a full Lightning implementation (managing channels, generating messages to send to peers, signatures, on-chain punishment, etc), and use it to create a library with high-level APIs, so developers can build more and agonize less.")]),e._v(" "),t("p",[e._v("This highly specialized library needed to be flexible enough to let developers customize areas like on-chain wallet creation, sourcing blockchain data, and backing up channel states while paving the way for them to make those critical decisions at 10x speed.")]),e._v(" "),t("p",[e._v("Initially supported by "),t("a",{attrs:{href:"https://chaincode.com/",target:"_blank",rel:"noopener noreferrer"}},[e._v("Chaincode Labs"),t("OutboundLink")],1),e._v(" and then by "),t("a",{attrs:{href:"https://spiral.xyz/",target:"_blank",rel:"noopener noreferrer"}},[e._v("Spiral"),t("OutboundLink")],1),e._v(", LDK has gone from a good idea to a mature, "),t("a",{attrs:{href:"https://github.com/lightningdevkit",target:"_blank",rel:"noopener noreferrer"}},[e._v("open-source project"),t("OutboundLink")],1),e._v(" with "),t("a",{attrs:{href:"https://github.com/lightningdevkit/rust-lightning/graphs/contributors",target:"_blank",rel:"noopener noreferrer"}},[e._v("many contributors"),t("OutboundLink")],1),e._v(" in just a few years. LDK is a robust, modular, mobile-friendly SDK that can be "),t("a",{attrs:{href:"https://vimeo.com/showcase/8372504/video/412818125",target:"_blank",rel:"noopener noreferrer"}},[e._v("integrated into existing bitcoin wallets"),t("OutboundLink")],1),e._v(" while significantly "),t("a",{attrs:{href:"https://bitcointv.com/w/sy6s9vVCmDvXr46YtbYcXM",target:"_blank",rel:"noopener noreferrer"}},[e._v("improving how developers integrate Lightning"),t("OutboundLink")],1),e._v(".")]),e._v(" "),t("p",[e._v("Over time, we hope that LDK will become a public good that doesn’t rely on a single entity like Spiral to be sustainable, which is why we’re already fostering a community, empowering non-Spiral participants, and "),t("a",{attrs:{href:"https://spiral.xyz/blog/a-framework-for-sustainable-open-source-bitcoin-development/",target:"_blank",rel:"noopener noreferrer"}},[e._v("gradually reducing Spiral’s influence"),t("OutboundLink")],1),e._v(". Like Bitcoin Core, we expect LDK to have a strong group of volunteers contributing to the project and many entities funding the project.")]),e._v(" "),t("h2",{attrs:{id:"what-advantages-does-ldk-offer-developers"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#what-advantages-does-ldk-offer-developers"}},[e._v("#")]),e._v(" What advantages does LDK offer developers?")]),e._v(" "),t("p",[e._v("Before committing to LDK, we spoke with over 50 wallet developers to learn what challenges they faced. We learned that developing Lightning apps was a universally bad experience, especially in mobile environments, and that a small team of experienced engineers could take up to two years to build a basic Lightning application. So… not great.")]),e._v(" "),t("p",[e._v("LDK is a flexible Lightning implementation that focuses on running the Lightning node on a mobile phone in a non-custodial manner, which has significant privacy and sovereignty benefits. While this presents some technical challenges, non-custodial mobile apps are where LDK specializes, whether someone is building a wallet from scratch or integrating LDK into one that already exists.")]),e._v(" "),t("p",[e._v("Before LDK, if your team wanted to add Lightning functionality to a mobile app, you most likely had to modify and customize an existing implementation like LND to make it suitable for mobile devices. Core Lightning is also hard to run on iPhones. Both of these implementations are out-of-the-box node solutions that provide solid RPC and HTTP interfaces, but are targeted for server environments or simply aren’t suited to mobile.")]),e._v(" "),t("p",[e._v("Furthermore, if you want to turn your on-chain wallet into a unified wallet experience or source chain data from a third-party server using the Electrum protocol for resource-constrained devices, it’s complex, time-consuming, and a huge engineering undertaking.")]),e._v(" "),t("p",[e._v("Maintaining an LN implementation that you can trust with real money is challenging, and different needs exist for routing nodes and mobile nodes. Maintenance costs also increase over time due to ageing codebases, interactions with other layers, and new use cases with different performance and security trade-offs. We see this with "),t("a",{attrs:{href:"https://github.com/breez/breezmobile",target:"_blank",rel:"noopener noreferrer"}},[e._v("Breez"),t("OutboundLink")],1),e._v(" forking "),t("a",{attrs:{href:"https://github.com/breez/lnd",target:"_blank",rel:"noopener noreferrer"}},[e._v("LND"),t("OutboundLink")],1),e._v(" to make it suitable for mobile and ACINQ doing something similar with "),t("a",{attrs:{href:"https://github.com/ACINQ/phoenix",target:"_blank",rel:"noopener noreferrer"}},[e._v("Phoenix"),t("OutboundLink")],1),e._v(" wallet and "),t("a",{attrs:{href:"https://github.com/ACINQ/lightning-kmp",target:"_blank",rel:"noopener noreferrer"}},[e._v("lightning-kmp"),t("OutboundLink")],1),e._v(".")]),e._v(" "),t("p",[e._v("We created LDK in multiple languages with an API-first approach designed to run at the application layer, like Rust’s "),t("a",{attrs:{href:"https://docs.rs/lightning/latest/lightning/chain/chainmonitor/trait.Persist.html",target:"_blank",rel:"noopener noreferrer"}},[e._v("Persist"),t("OutboundLink")],1),e._v(" trait. Persist defines behaviour for persisting channel states but lets you specify whether you write this data to disk or another backup mechanism, such as the cloud. You don’t need to write an LN implementation from scratch or modify an existing one to use LN functionality. Just call our APIs from your app.")]),e._v(" "),t("p",[e._v("Finally (for this section), LDK’s flexibility enables several different architectures without sacrificing security. Its lightweight design can be optimized to run on embedded devices or HSMs (hardware security modules) and it doesn’t make system calls, so it can run in almost any OS environment. For example, you can opt to run some Lightning logic, such as signing transactions and updating channel states on an HSM that has specific "),t("a",{attrs:{href:"https://gitlab.com/lightning-signer/docs/-/blob/master/README.md",target:"_blank",rel:"noopener noreferrer"}},[e._v("spending policies"),t("OutboundLink")],1),e._v(" and manages private keys. Then you connect it to a server with its own TCP/IP stack using a serial communication method such as USB.")]),e._v(" "),t("p",[e._v("Check out this "),t("a",{attrs:{href:"https://www.youtube.com/watch?v=9-81tobFSKg",target:"_blank",rel:"noopener noreferrer"}},[e._v("presentation"),t("OutboundLink")],1),e._v(" at btc++ by "),t("a",{attrs:{href:"https://twitter.com/jkczyz",target:"_blank",rel:"noopener noreferrer"}},[e._v("Jeff Czyz"),t("OutboundLink")],1),e._v(" and "),t("a",{attrs:{href:"https://twitter.com/arikaleph",target:"_blank",rel:"noopener noreferrer"}},[e._v("Arik Sosman"),t("OutboundLink")],1),e._v(" to learn more about LDK "),t("a",{attrs:{href:"https://lightningdevkit.org/introduction/use_cases/",target:"_blank",rel:"noopener noreferrer"}},[e._v("use cases"),t("OutboundLink")],1),e._v(".")]),e._v(" "),t("h2",{attrs:{id:"who-uses-ldk"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#who-uses-ldk"}},[e._v("#")]),e._v(" Who uses LDK?")]),e._v(" "),t("p",[e._v("LDK supports applications that require running many nodes (such as server/custodial apps), letting users run nodes on mobile devices, integrating with existing infrastructure, broad customization options, and resource-constrained embedded systems such as point of sale, IoT, and so on and so on, etc.")]),e._v(" "),t("p",[t("a",{attrs:{href:"https://bluewallet.io",target:"_blank",rel:"noopener noreferrer"}},[e._v("Blue Wallet"),t("OutboundLink")],1),e._v(" was LDK’s patient zero and ideal first adopter since it is both non-custodial and mobile. Their team maintains "),t("a",{attrs:{href:"https://github.com/BlueWallet/rn-ldk",target:"_blank",rel:"noopener noreferrer"}},[e._v("rn-ldk"),t("OutboundLink")],1),e._v(" and runs it on both Android and iOS.The wallet is likely to ship with LDK soon but not before some critical infrastructure is in place. While non-custodial mobile wallets are LDK’s primary use case, that doesn’t make it limited to them.")]),e._v(" "),t("p",[t("a",{attrs:{href:"https://cash.app",target:"_blank",rel:"noopener noreferrer"}},[e._v("CashApp"),t("OutboundLink")],1),e._v(", one of the world’s most used payment apps, chose LDK for its Lightning implementation because of its customizability. While custodial server-based solutions are not the primary use case for LDK, it shows how adaptable the library is. Ryan Loomba recently explained some of the trade-offs their team had to think about when comparing LDK to other solutions "),t("a",{attrs:{href:"https://www.youtube.com/watch?v=kbhL5RqL8Aw",target:"_blank",rel:"noopener noreferrer"}},[e._v("at btc++"),t("OutboundLink")],1),e._v(".")]),e._v(" "),t("p",[t("a",{attrs:{href:"https://l2.technology/sensei",target:"_blank",rel:"noopener noreferrer"}},[e._v("Sensei"),t("OutboundLink")],1),e._v(", an out-of-the-box lightning node solution, is also powered by LDK. Its modular architecture enables a unique multi-node operation mode, letting nodes easily share a network graph, route scoring, and chain data which enables exciting new use cases.")]),e._v(" "),t("p",[e._v("We’re also talking to dozens of developers, some of whom we expect to adopt LDK soon.")]),e._v(" "),t("p",[t("a",{attrs:{href:"https://github.com/orgs/lightningdevkit/discussions/1554",target:"_blank",rel:"noopener noreferrer"}},[e._v("Know someone building a Lightning wallet or related application?"),t("OutboundLink")],1),e._v(" Point them in "),t("a",{attrs:{href:"https://twitter.com/moneyball",target:"_blank",rel:"noopener noreferrer"}},[e._v("@moneyball’s"),t("OutboundLink")],1),e._v(" direction. If you’re already using LDK and have questions, hop into our "),t("a",{attrs:{href:"https://discord.gg/xaYE3pDQpm",target:"_blank",rel:"noopener noreferrer"}},[e._v("Discord"),t("OutboundLink")],1),e._v(" or checkout GitHub "),t("a",{attrs:{href:"https://github.com/orgs/lightningdevkit/discussions",target:"_blank",rel:"noopener noreferrer"}},[e._v("Discussions"),t("OutboundLink")],1)]),e._v(" "),t("h2",{attrs:{id:"what-are-ldk-s-engineering-priorities"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#what-are-ldk-s-engineering-priorities"}},[e._v("#")]),e._v(" What are LDK’s engineering priorities?")]),e._v(" "),t("p",[t("code",[e._v("Offline Receive")]),t("br"),e._v("\nA problem with Lightning UX is that mobile wallets can’t receive payments unless the user is using the app. We’re developing solutions in conjunction with the LN developer community that will let offline nodes receive payments. Spiral’s Matt Corallo has a "),t("a",{attrs:{href:"https://github.com/lightning/bolts/pull/989",target:"_blank",rel:"noopener noreferrer"}},[e._v("pull request"),t("OutboundLink")],1),e._v(" open that proposes a protocol to fix this exact problem. It includes his original post to the Lightning Devs mailing list which is a "),t("a",{attrs:{href:"https://lists.linuxfoundation.org/pipermail/lightning-dev/2021-October/003307.html",target:"_blank",rel:"noopener noreferrer"}},[e._v("pretty good technical"),t("OutboundLink")],1),e._v(" read on this issue if you’re in the mood for one of those.")]),e._v(" "),t("p",[t("code",[e._v("BOLT 12")]),t("br"),e._v("\nThis feature improves privacy by allowing reusable payments over blinded paths and provides a framework for future upgrades that support recurring payments. There’s still work to be done, and it includes implementing route blinding/blinded paths, an onion messages API for requesting invoices, and BOLT 12 invoice parsing.")]),e._v(" "),t("p",[t("code",[e._v("Taproot")]),t("br"),e._v("\nTaproot! People love it. We love it. It’s been several months since full activation, and LDK will start to take advantage of everything it offers. This includes improved on-chain privacy by making current funding channel outputs (2-of-2 multisig) indistinguishable from single sig outputs, and making channel opening and closing transactions look more like regular non-lightning transactions. In addition, we’re looking to support multi-sig channel capabilities as they allow for greater security, redundancy, and flexibility.")]),e._v(" "),t("p",[t("code",[e._v("Language Bindings")]),t("br"),e._v("\nWe’re making existing language integrations feel more native. We currently support Rust, C/C++, Swift, Java, & Kotlin. It’s now in the beta stage, but "),t("a",{attrs:{href:"https://www.npmjs.com/package/lightningdevkit",target:"_blank",rel:"noopener noreferrer"}},[e._v("JavaScript/TypeScript/Wasm"),t("OutboundLink")],1),e._v(" is also supported, and we are prioritizing bug fixing for early adopters. In the future, expect support for C#, Python, Flutter/Dart, and possibly others.")]),e._v(" "),t("p",[e._v("Also in LDK’s future: a simplified API that makes opinionated decisions on behalf of developers that will accelerate getting their apps up and running. Think of it as a Rust crate but using UniFFI to auto-generate language bindings for Kotlin, Swift, Python, and Ruby that expedite basic send/receive functionality.")]),e._v(" "),t("h2",{attrs:{id:"notable-updates"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#notable-updates"}},[e._v("#")]),e._v(" Notable Updates")]),e._v(" "),t("p",[e._v("Phantom Node support is up and running (separate blog post coming soon…ish). This integration adds support for multi-node receive, which enables enterprise-level architecture. This is important since users might need production nodes to receive payments when load balancing is required.")]),e._v(" "),t("p",[e._v("We've introduced a new client-side pathfinding API to LDK that simplifies quickly downloading gossip data from a server. This means that servers can't know who you are paying or how much.")]),e._v(" "),t("p",[e._v("We now support zero conf channels, allowing immediate forwarding of payments after channel opening/receiving for those wanting to build inbound liquidity services.")]),e._v(" "),t("p",[e._v("SCID Aliases (short channel IDs) were added in a recent release and may be negotiated when opening a channel with a peer. This has significant privacy benefits and will likely be the default in the future.")]),e._v(" "),t("p",[e._v("Anything else?")]),e._v(" "),t("p",[e._v("Absolutely. But this post is long enough for now. Keep an eye out for announcements from "),t("a",{attrs:{href:"https://twitter.com/spiralbtc",target:"_blank",rel:"noopener noreferrer"}},[e._v("@spiralbtc"),t("OutboundLink")],1),e._v(" and "),t("a",{attrs:{href:"https://twitter.com/lightningdevkit",target:"_blank",rel:"noopener noreferrer"}},[e._v("@lightningdevkit"),t("OutboundLink")],1),e._v(".")])])}),[],!1,null,null,null);t.default=r.exports}}]); \ No newline at end of file diff --git a/assets/js/33.ad075210.js b/assets/js/33.d2e97baa.js similarity index 98% rename from assets/js/33.ad075210.js rename to assets/js/33.d2e97baa.js index 2aeb91a4b..49fa8dfa1 100644 --- a/assets/js/33.ad075210.js +++ b/assets/js/33.d2e97baa.js @@ -1 +1 @@ -(window.webpackJsonp=window.webpackJsonp||[]).push([[33],{394:function(e,t,n){"use strict";n.r(t);var i=n(7),a=Object(i.a)({},(function(){var e=this,t=e._self._c;return t("ContentSlotsDistributor",{attrs:{"slot-key":e.$parent.slotKey}},[t("p",[e._v("Mutiny is a new lightning wallet for the web. It is the first self-custodial wallet to run directly in a user's browser. It’s built on top of LDK and "),t("a",{attrs:{href:"https://bitcoindevkit.org/",target:"_blank",rel:"noopener noreferrer"}},[e._v("BDK"),t("OutboundLink")],1),e._v(", written in Rust, and compiled into WebAssembly. It offers a simple, intuitive interface for sending and receiving payments and other advanced features, such as Nostr Wallet Connect and subscription payments.")]),e._v(" "),t("p",[e._v("We chose to build on LDK and BDK because it wouldn’t have been possible to build a wallet like Mutiny in any other way. Since LDK is written in Rust, we were able to compile it into WebAssembly. Rust's unique combination of type-safety, memory-safety, and efficient runtime performance make it ideally suited to a lightning node that must be reliable, fast, and lightweight enough to run on a mobile phone. LDK's modular design means we can customize it to work within the specific constraints of a web browser. LDK also provides a robust API for building advanced features for our wallet that would otherwise not be possible.")]),e._v(" "),t("h1",{attrs:{id:"what-we-did"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#what-we-did"}},[e._v("#")]),e._v(" What we did?")]),e._v(" "),t("p",[e._v("We used LDK to make a crate called mutiny-node which holds all our main wallet logic. Then we used the wasm-bindgencrate to generate JavaScript bindings that can be imported into a regular web project. Thankfully, LDK supports no_std, so compiling it into WebAssembly without any modifications was possible.")]),e._v(" "),t("p",[e._v("Mutiny is a lite-client wallet, meaning it does not run a full bitcoin node. Instead, it gets its blockchain data from an esplora instance. LDK's Filter interface made it easy to implement this, allowing for a simple and efficient way to sync the wallet with the blockchain. "),t("a",{attrs:{href:"https://docs.rs/lightning-rapid-gossip-sync/0.0.115/",target:"_blank",rel:"noopener noreferrer"}},[e._v("Rapid Gossip Sync"),t("OutboundLink")],1),e._v(" also helps make the wallet sync quickly, and RGS allows us to sync lightning gossip data nearly instantly without spending unnecessary bandwidth and CPU resources.")]),e._v(" "),t("p",[e._v("Local storage can be unreliable in web browsers, so we also want users to be able to recover their wallet in case they lose their device. We implemented the LDK project's "),t("a",{attrs:{href:"https://github.com/lightningdevkit/vss-server",target:"_blank",rel:"noopener noreferrer"}},[e._v("VSS"),t("OutboundLink")],1),e._v(" specification to give our users encrypted cloud backups to support this.")]),e._v(" "),t("p",[e._v("While we're currently focused on the web, this architecture and the flexibility of LDK means we will be able to share most of our code with a mobile or even server version of Mutiny in the future.")]),e._v(" "),t("h1",{attrs:{id:"results"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#results"}},[e._v("#")]),e._v(" Results")]),e._v(" "),t("p",[e._v("LDK made building a lightning wallet that runs in the browser possible. Compiling to WebAssembly and LDK's various tools for lite clients allowed us to create an unstoppable, self-custodial wallet that anyone can use without downloading any software. We hope that Mutiny will help bring lightning to the masses, and we are excited to see what the future holds for LDK and lightning on the web.")]),e._v(" "),t("p",[e._v("You can learn more and try it out at "),t("a",{attrs:{href:"https://www.mutinywallet.com/",target:"_blank",rel:"noopener noreferrer"}},[e._v("mutinywallet.com"),t("OutboundLink")],1),e._v(".")])])}),[],!1,null,null,null);t.default=a.exports}}]); \ No newline at end of file +(window.webpackJsonp=window.webpackJsonp||[]).push([[33],{393:function(e,t,n){"use strict";n.r(t);var i=n(7),a=Object(i.a)({},(function(){var e=this,t=e._self._c;return t("ContentSlotsDistributor",{attrs:{"slot-key":e.$parent.slotKey}},[t("p",[e._v("Mutiny is a new lightning wallet for the web. It is the first self-custodial wallet to run directly in a user's browser. It’s built on top of LDK and "),t("a",{attrs:{href:"https://bitcoindevkit.org/",target:"_blank",rel:"noopener noreferrer"}},[e._v("BDK"),t("OutboundLink")],1),e._v(", written in Rust, and compiled into WebAssembly. It offers a simple, intuitive interface for sending and receiving payments and other advanced features, such as Nostr Wallet Connect and subscription payments.")]),e._v(" "),t("p",[e._v("We chose to build on LDK and BDK because it wouldn’t have been possible to build a wallet like Mutiny in any other way. Since LDK is written in Rust, we were able to compile it into WebAssembly. Rust's unique combination of type-safety, memory-safety, and efficient runtime performance make it ideally suited to a lightning node that must be reliable, fast, and lightweight enough to run on a mobile phone. LDK's modular design means we can customize it to work within the specific constraints of a web browser. LDK also provides a robust API for building advanced features for our wallet that would otherwise not be possible.")]),e._v(" "),t("h1",{attrs:{id:"what-we-did"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#what-we-did"}},[e._v("#")]),e._v(" What we did?")]),e._v(" "),t("p",[e._v("We used LDK to make a crate called mutiny-node which holds all our main wallet logic. Then we used the wasm-bindgencrate to generate JavaScript bindings that can be imported into a regular web project. Thankfully, LDK supports no_std, so compiling it into WebAssembly without any modifications was possible.")]),e._v(" "),t("p",[e._v("Mutiny is a lite-client wallet, meaning it does not run a full bitcoin node. Instead, it gets its blockchain data from an esplora instance. LDK's Filter interface made it easy to implement this, allowing for a simple and efficient way to sync the wallet with the blockchain. "),t("a",{attrs:{href:"https://docs.rs/lightning-rapid-gossip-sync/0.0.115/",target:"_blank",rel:"noopener noreferrer"}},[e._v("Rapid Gossip Sync"),t("OutboundLink")],1),e._v(" also helps make the wallet sync quickly, and RGS allows us to sync lightning gossip data nearly instantly without spending unnecessary bandwidth and CPU resources.")]),e._v(" "),t("p",[e._v("Local storage can be unreliable in web browsers, so we also want users to be able to recover their wallet in case they lose their device. We implemented the LDK project's "),t("a",{attrs:{href:"https://github.com/lightningdevkit/vss-server",target:"_blank",rel:"noopener noreferrer"}},[e._v("VSS"),t("OutboundLink")],1),e._v(" specification to give our users encrypted cloud backups to support this.")]),e._v(" "),t("p",[e._v("While we're currently focused on the web, this architecture and the flexibility of LDK means we will be able to share most of our code with a mobile or even server version of Mutiny in the future.")]),e._v(" "),t("h1",{attrs:{id:"results"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#results"}},[e._v("#")]),e._v(" Results")]),e._v(" "),t("p",[e._v("LDK made building a lightning wallet that runs in the browser possible. Compiling to WebAssembly and LDK's various tools for lite clients allowed us to create an unstoppable, self-custodial wallet that anyone can use without downloading any software. We hope that Mutiny will help bring lightning to the masses, and we are excited to see what the future holds for LDK and lightning on the web.")]),e._v(" "),t("p",[e._v("You can learn more and try it out at "),t("a",{attrs:{href:"https://www.mutinywallet.com/",target:"_blank",rel:"noopener noreferrer"}},[e._v("mutinywallet.com"),t("OutboundLink")],1),e._v(".")])])}),[],!1,null,null,null);t.default=a.exports}}]); \ No newline at end of file diff --git a/assets/js/34.f706fbc9.js b/assets/js/34.e2575da0.js similarity index 99% rename from assets/js/34.f706fbc9.js rename to assets/js/34.e2575da0.js index feceec639..949194e8c 100644 --- a/assets/js/34.f706fbc9.js +++ b/assets/js/34.e2575da0.js @@ -1 +1 @@ -(window.webpackJsonp=window.webpackJsonp||[]).push([[34],{398:function(e,t,n){"use strict";n.r(t);var i=n(7),o=Object(i.a)({},(function(){var e=this,t=e._self._c;return t("ContentSlotsDistributor",{attrs:{"slot-key":e.$parent.slotKey}},[t("p",[e._v("Lightning development is tough. While going custodial simplifies the process, it means sacrificing user privacy, censorship resistance, and self-sovereignty, all of which contradict bitcoin’s ethos. Therefore, many companies and projects have started with or redirected their focus from building custodial to non-custodial Lightning applications.")]),e._v(" "),t("h2",{attrs:{id:"obstacles"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#obstacles"}},[e._v("#")]),e._v(" Obstacles")]),e._v(" "),t("p",[e._v("There are several basic requirements for wallets wanting to add Lightning capabilities, such as connecting to the Lightning Network via a Lightning Implementation, syncing with on-chain transactions, and opening and closing channels. When building a mobile application, developers face additional technical challenges:")]),e._v(" "),t("h2",{attrs:{id:"liquidity"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#liquidity"}},[e._v("#")]),e._v(" Liquidity")]),e._v(" "),t("p",[e._v("To receive funds via Lightning, someone must have on-chain bitcoin locked up in a channel. Transaction completion is delayed if the receiver has an empty or insufficient channel balance. For example, let’s say that someone has 50,000 sats of inbound liquidity and is trying to receive 100,000 sats. Before the Lightning transaction can be initiated, additional liquidity is required to cover the 100,000 sats total plus fees from channel reserves and anchor outputs, which are mechanisms to improve security. This is done via on-chain transactions, which come with fees.")]),e._v(" "),t("p",[e._v("Additionally, on-chain transactions must be mined into multiple blocks before being confirmed. It’s not a great user experience if someone has to do work upfront and wait roughly 30–60 minutes before they can send or receive money.")]),e._v(" "),t("p",[t("a",{attrs:{href:"https://lightningdevkit.org/blog/zero-confirmation-channels/",target:"_blank",rel:"noopener noreferrer"}},[e._v("0-conf"),t("OutboundLink")],1),e._v(" channels offer a partial solution, allowing users to receive Lightning instantly. 0-conf enables the client to trust their channel counterparty (usually an application vendor or partner) for a limited time until an on-chain transaction is confirmed. While this helps with speed, the fact that 0conf channels require some level of trust is a trade-off.")]),e._v(" "),t("p",[e._v("Liquidity Service Providers (LSPs) provide liquidity upfront through automated channel and liquidity management. LSPs supply more liquidity than required for immediate payments rather than the exact amount to ensure that remaining funds are in the channel for future transactions. If a user conducts multiple payments, it’s best to avoid doing on-chain transactions for every Lightning transaction.")]),e._v(" "),t("p",[e._v("LSPs do not want to pay excessive on-chain fees, but it’s hard to predict how often people will send and receive transactions and for how much. Therefore, there’s no straightforward way to know how much liquidity should be locked into a given channel. LSPs have to determine how much money they can contribute and how much it'll cost. This can be anywhere from aggressive (locking up a generous amount) to conservative (locking up a small amount). Ultimately, this decision results in a “compression ratio,\" i.e., the number of on-chain transactions required per Lightning transaction. Some very conservative LSPs may get a compression ratio close to one, saving their users relatively little on fees, but there is nearly always some gain to be had in using Lightning over on-chain.")]),e._v(" "),t("p",[e._v("While predicting what the compression ratio should be remains a major challenge, most solutions today offer some compression information, allowing us to learn and improve. For this reason, it’s worth deploying Lightning for instant transactions at lower costs compared to on-chain, even if it's not as common as it could be. We expect this to get better over time.")]),e._v(" "),t("h1",{attrs:{id:"receive-wakeup"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#receive-wakeup"}},[e._v("#")]),e._v(" Receive Wakeup")]),e._v(" "),t("p",[e._v("Lightning requires nodes (or, specifically, their cryptographic keys) to be online to exchange signatures and complete payments, meaning the user must be on their phone and with service. Receiving wakeups is problematic because incomplete payments are not great for the Lightning Network—it’s detrimental to keep the money for a payment locked up until someone comes back online.")]),e._v(" "),t("p",[e._v("iOS and Android operating systems help address this problem by allowing a small amount of code to run when notifications are received, even if the relevant application isn’t open. However, suppose an application is infrequently used or the device has a low battery. In that case, the application will often not get any CPU time, resulting in the payment being stuck until the user opens the app.")]),e._v(" "),t("p",[e._v("A lot of work must be done to make it possible for senders and recipients to exchange payments asynchronously, "),t("a",{attrs:{href:"https://lists.linuxfoundation.org/pipermail/lightning-dev/2021-October/003307",target:"_blank",rel:"noopener noreferrer"}},[e._v("but a protocol sketch is in the works"),t("OutboundLink")],1),e._v(". You can find a more detailed explainer "),t("a",{attrs:{href:"https://gist.github.com/remyers/e0d2bedb7bc87371d1bdbbb6fff2edd1",target:"_blank",rel:"noopener noreferrer"}},[e._v("here"),t("OutboundLink")],1),e._v(".")]),e._v(" "),t("h1",{attrs:{id:"live-backups"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#live-backups"}},[e._v("#")]),e._v(" Live Backups")]),e._v(" "),t("p",[e._v("These are especially problematic when a user has to reinstall an application or loses their phone. In addition to needing their seed phrase, they’ll need the latest Lightning state data stored on their device to get their money back reliably.")]),e._v(" "),t("p",[e._v("The Lightning state changes every time a user sends or receives money, so backups must be frequently updated on a server. While some devices use Google Drive or iCloud, those protocols sync asynchronously, often leading to data being out of sync. Cloud methods sanitize data stored on the client well, but they may not ensure reliable full funds recovery if a device is lost.")]),e._v(" "),t("p",[e._v("Advanced versions of live online sync allow users to open the same wallet on multiple devices. Users often do this despite it being challenging to do with Lightning applications since two devices running simultaneously can result in losing funds.")]),e._v(" "),t("h1",{attrs:{id:"privacy-preserving-payment-routing"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#privacy-preserving-payment-routing"}},[e._v("#")]),e._v(" Privacy-preserving Payment Routing")]),e._v(" "),t("p",[e._v("Another commonly discussed issue is payment routing through the Lightning Network. This isn't easy because the route finder has to have some history of liquidity on the Lightning Network.")]),e._v(" "),t("p",[e._v("The most common method is to rely on a server for route-finding, which sees users' payment history and therefore compromises privacy. This may also pose long-term regulatory concerns for apps relying on such servers.")]),e._v(" "),t("p",[e._v("Without a server, the client needs to download the full Lightning graph. This can be slow and performance-compromising. Worse, the Lightning graph alone doesn’t provide enough information to achieve reliable payment success, leading to the possibility that transactions may take a long time to complete, or not go through at all.")]),e._v(" "),t("p",[e._v("To achieve better payment success, the client must send lots of payments, which can be done via probing (fake payments). Probing trains data on the network graph from a client's perspective and builds up a history of liquidity on the network. While this offers a solution, probing must be done consistently, requiring the client to be online 24/7. This could instead be done by an LSP, which can offer the resulting data to clients. Additionally, information is not super portable across LSPs, so each LSP needs to do its own probing.")]),e._v(" "),t("h1",{attrs:{id:"privacy-preserving-block-fetching"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#privacy-preserving-block-fetching"}},[e._v("#")]),e._v(" Privacy-preserving Block Fetching")]),e._v(" "),t("p",[e._v("For users to see their transaction history and balance, bitcoin and Lightning wallets need to connect to and download the blockchain. Each block contains a lot of data, making downloading the full blockchain on mobile devices impractical due to bandwidth constraints.")]),e._v(" "),t("p",[e._v("The most common way to obtain blockchain data is to connect to a server using Electrum or Esplora. To do this and get the relevant information, the client has to provide their user’s list of addresses, exposing transaction histories and balances.")]),e._v(" "),t("p",[e._v("It’s difficult to fetch blockchain data without giving up privacy. One way around this is to use compact block filters, which download data from a full node and only download a select amount of blocks. While compact block filters offer better privacy than a server and are more efficient than downloading the entire blockchain, the method isn’t perfect. Compact block filters are slow to sync and still require substantial bandwidth on the user’s device, making it a less enticing tradeoff for many wallets.")]),e._v(" "),t("p",[e._v("A third option, called private information retrieval, is more future-looking. This method is efficient for clients but expensive on the server side.")]),e._v(" "),t("h1",{attrs:{id:"conclusion"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#conclusion"}},[e._v("#")]),e._v(" Conclusion")]),e._v(" "),t("p",[e._v("There are many obstacles to making non-custodial Lightning work privately on mobile devices, but it is doable. It requires a mobile-focused LN implementation, SDK, and infrastructure operated by an LSP or the application vendor. None of that needs to compromise user privacy or self-sovereignty, even though, in many designs, it does.")])])}),[],!1,null,null,null);t.default=o.exports}}]); \ No newline at end of file +(window.webpackJsonp=window.webpackJsonp||[]).push([[34],{397:function(e,t,n){"use strict";n.r(t);var i=n(7),o=Object(i.a)({},(function(){var e=this,t=e._self._c;return t("ContentSlotsDistributor",{attrs:{"slot-key":e.$parent.slotKey}},[t("p",[e._v("Lightning development is tough. While going custodial simplifies the process, it means sacrificing user privacy, censorship resistance, and self-sovereignty, all of which contradict bitcoin’s ethos. Therefore, many companies and projects have started with or redirected their focus from building custodial to non-custodial Lightning applications.")]),e._v(" "),t("h2",{attrs:{id:"obstacles"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#obstacles"}},[e._v("#")]),e._v(" Obstacles")]),e._v(" "),t("p",[e._v("There are several basic requirements for wallets wanting to add Lightning capabilities, such as connecting to the Lightning Network via a Lightning Implementation, syncing with on-chain transactions, and opening and closing channels. When building a mobile application, developers face additional technical challenges:")]),e._v(" "),t("h2",{attrs:{id:"liquidity"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#liquidity"}},[e._v("#")]),e._v(" Liquidity")]),e._v(" "),t("p",[e._v("To receive funds via Lightning, someone must have on-chain bitcoin locked up in a channel. Transaction completion is delayed if the receiver has an empty or insufficient channel balance. For example, let’s say that someone has 50,000 sats of inbound liquidity and is trying to receive 100,000 sats. Before the Lightning transaction can be initiated, additional liquidity is required to cover the 100,000 sats total plus fees from channel reserves and anchor outputs, which are mechanisms to improve security. This is done via on-chain transactions, which come with fees.")]),e._v(" "),t("p",[e._v("Additionally, on-chain transactions must be mined into multiple blocks before being confirmed. It’s not a great user experience if someone has to do work upfront and wait roughly 30–60 minutes before they can send or receive money.")]),e._v(" "),t("p",[t("a",{attrs:{href:"https://lightningdevkit.org/blog/zero-confirmation-channels/",target:"_blank",rel:"noopener noreferrer"}},[e._v("0-conf"),t("OutboundLink")],1),e._v(" channels offer a partial solution, allowing users to receive Lightning instantly. 0-conf enables the client to trust their channel counterparty (usually an application vendor or partner) for a limited time until an on-chain transaction is confirmed. While this helps with speed, the fact that 0conf channels require some level of trust is a trade-off.")]),e._v(" "),t("p",[e._v("Liquidity Service Providers (LSPs) provide liquidity upfront through automated channel and liquidity management. LSPs supply more liquidity than required for immediate payments rather than the exact amount to ensure that remaining funds are in the channel for future transactions. If a user conducts multiple payments, it’s best to avoid doing on-chain transactions for every Lightning transaction.")]),e._v(" "),t("p",[e._v("LSPs do not want to pay excessive on-chain fees, but it’s hard to predict how often people will send and receive transactions and for how much. Therefore, there’s no straightforward way to know how much liquidity should be locked into a given channel. LSPs have to determine how much money they can contribute and how much it'll cost. This can be anywhere from aggressive (locking up a generous amount) to conservative (locking up a small amount). Ultimately, this decision results in a “compression ratio,\" i.e., the number of on-chain transactions required per Lightning transaction. Some very conservative LSPs may get a compression ratio close to one, saving their users relatively little on fees, but there is nearly always some gain to be had in using Lightning over on-chain.")]),e._v(" "),t("p",[e._v("While predicting what the compression ratio should be remains a major challenge, most solutions today offer some compression information, allowing us to learn and improve. For this reason, it’s worth deploying Lightning for instant transactions at lower costs compared to on-chain, even if it's not as common as it could be. We expect this to get better over time.")]),e._v(" "),t("h1",{attrs:{id:"receive-wakeup"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#receive-wakeup"}},[e._v("#")]),e._v(" Receive Wakeup")]),e._v(" "),t("p",[e._v("Lightning requires nodes (or, specifically, their cryptographic keys) to be online to exchange signatures and complete payments, meaning the user must be on their phone and with service. Receiving wakeups is problematic because incomplete payments are not great for the Lightning Network—it’s detrimental to keep the money for a payment locked up until someone comes back online.")]),e._v(" "),t("p",[e._v("iOS and Android operating systems help address this problem by allowing a small amount of code to run when notifications are received, even if the relevant application isn’t open. However, suppose an application is infrequently used or the device has a low battery. In that case, the application will often not get any CPU time, resulting in the payment being stuck until the user opens the app.")]),e._v(" "),t("p",[e._v("A lot of work must be done to make it possible for senders and recipients to exchange payments asynchronously, "),t("a",{attrs:{href:"https://lists.linuxfoundation.org/pipermail/lightning-dev/2021-October/003307",target:"_blank",rel:"noopener noreferrer"}},[e._v("but a protocol sketch is in the works"),t("OutboundLink")],1),e._v(". You can find a more detailed explainer "),t("a",{attrs:{href:"https://gist.github.com/remyers/e0d2bedb7bc87371d1bdbbb6fff2edd1",target:"_blank",rel:"noopener noreferrer"}},[e._v("here"),t("OutboundLink")],1),e._v(".")]),e._v(" "),t("h1",{attrs:{id:"live-backups"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#live-backups"}},[e._v("#")]),e._v(" Live Backups")]),e._v(" "),t("p",[e._v("These are especially problematic when a user has to reinstall an application or loses their phone. In addition to needing their seed phrase, they’ll need the latest Lightning state data stored on their device to get their money back reliably.")]),e._v(" "),t("p",[e._v("The Lightning state changes every time a user sends or receives money, so backups must be frequently updated on a server. While some devices use Google Drive or iCloud, those protocols sync asynchronously, often leading to data being out of sync. Cloud methods sanitize data stored on the client well, but they may not ensure reliable full funds recovery if a device is lost.")]),e._v(" "),t("p",[e._v("Advanced versions of live online sync allow users to open the same wallet on multiple devices. Users often do this despite it being challenging to do with Lightning applications since two devices running simultaneously can result in losing funds.")]),e._v(" "),t("h1",{attrs:{id:"privacy-preserving-payment-routing"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#privacy-preserving-payment-routing"}},[e._v("#")]),e._v(" Privacy-preserving Payment Routing")]),e._v(" "),t("p",[e._v("Another commonly discussed issue is payment routing through the Lightning Network. This isn't easy because the route finder has to have some history of liquidity on the Lightning Network.")]),e._v(" "),t("p",[e._v("The most common method is to rely on a server for route-finding, which sees users' payment history and therefore compromises privacy. This may also pose long-term regulatory concerns for apps relying on such servers.")]),e._v(" "),t("p",[e._v("Without a server, the client needs to download the full Lightning graph. This can be slow and performance-compromising. Worse, the Lightning graph alone doesn’t provide enough information to achieve reliable payment success, leading to the possibility that transactions may take a long time to complete, or not go through at all.")]),e._v(" "),t("p",[e._v("To achieve better payment success, the client must send lots of payments, which can be done via probing (fake payments). Probing trains data on the network graph from a client's perspective and builds up a history of liquidity on the network. While this offers a solution, probing must be done consistently, requiring the client to be online 24/7. This could instead be done by an LSP, which can offer the resulting data to clients. Additionally, information is not super portable across LSPs, so each LSP needs to do its own probing.")]),e._v(" "),t("h1",{attrs:{id:"privacy-preserving-block-fetching"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#privacy-preserving-block-fetching"}},[e._v("#")]),e._v(" Privacy-preserving Block Fetching")]),e._v(" "),t("p",[e._v("For users to see their transaction history and balance, bitcoin and Lightning wallets need to connect to and download the blockchain. Each block contains a lot of data, making downloading the full blockchain on mobile devices impractical due to bandwidth constraints.")]),e._v(" "),t("p",[e._v("The most common way to obtain blockchain data is to connect to a server using Electrum or Esplora. To do this and get the relevant information, the client has to provide their user’s list of addresses, exposing transaction histories and balances.")]),e._v(" "),t("p",[e._v("It’s difficult to fetch blockchain data without giving up privacy. One way around this is to use compact block filters, which download data from a full node and only download a select amount of blocks. While compact block filters offer better privacy than a server and are more efficient than downloading the entire blockchain, the method isn’t perfect. Compact block filters are slow to sync and still require substantial bandwidth on the user’s device, making it a less enticing tradeoff for many wallets.")]),e._v(" "),t("p",[e._v("A third option, called private information retrieval, is more future-looking. This method is efficient for clients but expensive on the server side.")]),e._v(" "),t("h1",{attrs:{id:"conclusion"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#conclusion"}},[e._v("#")]),e._v(" Conclusion")]),e._v(" "),t("p",[e._v("There are many obstacles to making non-custodial Lightning work privately on mobile devices, but it is doable. It requires a mobile-focused LN implementation, SDK, and infrastructure operated by an LSP or the application vendor. None of that needs to compromise user privacy or self-sovereignty, even though, in many designs, it does.")])])}),[],!1,null,null,null);t.default=o.exports}}]); \ No newline at end of file diff --git a/assets/js/39.8ae8d1bb.js b/assets/js/39.a3b117ad.js similarity index 98% rename from assets/js/39.8ae8d1bb.js rename to assets/js/39.a3b117ad.js index b73bee541..63d4281c2 100644 --- a/assets/js/39.8ae8d1bb.js +++ b/assets/js/39.a3b117ad.js @@ -1 +1 @@ -(window.webpackJsonp=window.webpackJsonp||[]).push([[39],{403:function(t,e,n){"use strict";n.r(e);var i=n(7),o=Object(i.a)({},(function(){var t=this,e=t._self._c;return e("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[e("h1",{attrs:{id:"confirmed-transactions"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#confirmed-transactions"}},[t._v("#")]),t._v(" Confirmed Transactions")]),t._v(" "),e("p",[t._v("Up until this point, we've explored how to notify LDK of chain activity using\nblocks. But what if you're sourcing chain activity from a place that doesn't\nprovide a block-centric interface, like Electrum?")]),t._v(" "),e("p",[t._v("LDK's "),e("code",[t._v("ChannelManager")]),t._v(" and "),e("code",[t._v("ChainMonitor")]),t._v(" implement a\n"),e("a",{attrs:{href:"https://docs.rs/lightning/*/lightning/chain/trait.Confirm.html",target:"_blank",rel:"noopener noreferrer"}},[e("code",[t._v("chain::Confirm")]),e("OutboundLink")],1),t._v("\ninterface to support this use case, analogous to the block-oriented\n"),e("a",{attrs:{href:"https://docs.rs/lightning/*/lightning/chain/trait.Listen.html",target:"_blank",rel:"noopener noreferrer"}},[e("code",[t._v("chain::Listen")]),e("OutboundLink")],1),t._v("\ninterface which we've been using up until now. With this alternative approach,\nyou still need to give LDK information about chain activity,\nbut only for transactions of interest. To this end, you must call\n"),e("code",[t._v("Confirm::transactions_confirmed")]),t._v(" when any transactions identified by\n"),e("a",{attrs:{href:"https://docs.rs/lightning/*/lightning/chain/trait.Filter.html",target:"_blank",rel:"noopener noreferrer"}},[e("code",[t._v("chain::Filter")]),e("OutboundLink")],1),t._v("'s\n"),e("code",[t._v("register_tx")]),t._v("/"),e("code",[t._v("register_output")]),t._v(" methods are confirmed.")]),t._v(" "),e("p",[t._v("You also need to notify LDK of any transactions with insufficient confirmations\nthat have been reorganized out of the chain. Transactions that need to be monitored for such\nreorganization are returned by "),e("code",[t._v("Confirm::get_relevant_txids")]),t._v(". If any of these transactions become\nunconfirmed, you must call "),e("code",[t._v("Confirm::transaction_unconfirmed")]),t._v(".")]),t._v(" "),e("p",[t._v("Lastly, you must notify LDK whenever a new chain tip is available using\nthe "),e("code",[t._v("Confirm::best_block_updated")]),t._v(" method. See the documentation for a full\npicture of how this interface is intended to be used.")]),t._v(" "),e("div",{staticClass:"custom-block tip"},[e("p",{staticClass:"custom-block-title"},[t._v("Note")]),t._v(" "),e("p",[t._v("Note that the described methods of "),e("code",[t._v("Confirm")]),t._v(" must be called in accordance with the ordering requirements\ndescribed in the "),e("a",{attrs:{href:"https://docs.rs/lightning/*/lightning/chain/trait.Confirm.html#order",target:"_blank",rel:"noopener noreferrer"}},[e("code",[t._v("Confirm")]),t._v(" documentation"),e("OutboundLink")],1)])]),t._v(" "),e("div",{staticClass:"custom-block tip"},[e("p",{staticClass:"custom-block-title"},[t._v("Note")]),t._v(" "),e("p",[t._v("Note that the described methods of "),e("code",[t._v("Confirm")]),t._v(" must be called both on the\n"),e("code",[t._v("ChannelManager")]),t._v(" "),e("em",[t._v("and")]),t._v(" the "),e("code",[t._v("ChainMonitor")]),t._v(".")])]),t._v(" "),e("div",{staticClass:"custom-block tip"},[e("p",{staticClass:"custom-block-title"},[t._v("Note")]),t._v(" "),e("p",[t._v("Be advised that "),e("code",[t._v("chain::Confirm")]),t._v(" is a less mature interface than\n"),e("code",[t._v("chain::Listen")]),t._v(". As such, there is not yet a utility like\n"),e("code",[t._v("lightning-block-sync")]),t._v(" to use for interacting with clients like Electrum.")])])])}),[],!1,null,null,null);e.default=o.exports}}]); \ No newline at end of file +(window.webpackJsonp=window.webpackJsonp||[]).push([[39],{404:function(t,e,n){"use strict";n.r(e);var i=n(7),o=Object(i.a)({},(function(){var t=this,e=t._self._c;return e("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[e("h1",{attrs:{id:"confirmed-transactions"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#confirmed-transactions"}},[t._v("#")]),t._v(" Confirmed Transactions")]),t._v(" "),e("p",[t._v("Up until this point, we've explored how to notify LDK of chain activity using\nblocks. But what if you're sourcing chain activity from a place that doesn't\nprovide a block-centric interface, like Electrum?")]),t._v(" "),e("p",[t._v("LDK's "),e("code",[t._v("ChannelManager")]),t._v(" and "),e("code",[t._v("ChainMonitor")]),t._v(" implement a\n"),e("a",{attrs:{href:"https://docs.rs/lightning/*/lightning/chain/trait.Confirm.html",target:"_blank",rel:"noopener noreferrer"}},[e("code",[t._v("chain::Confirm")]),e("OutboundLink")],1),t._v("\ninterface to support this use case, analogous to the block-oriented\n"),e("a",{attrs:{href:"https://docs.rs/lightning/*/lightning/chain/trait.Listen.html",target:"_blank",rel:"noopener noreferrer"}},[e("code",[t._v("chain::Listen")]),e("OutboundLink")],1),t._v("\ninterface which we've been using up until now. With this alternative approach,\nyou still need to give LDK information about chain activity,\nbut only for transactions of interest. To this end, you must call\n"),e("code",[t._v("Confirm::transactions_confirmed")]),t._v(" when any transactions identified by\n"),e("a",{attrs:{href:"https://docs.rs/lightning/*/lightning/chain/trait.Filter.html",target:"_blank",rel:"noopener noreferrer"}},[e("code",[t._v("chain::Filter")]),e("OutboundLink")],1),t._v("'s\n"),e("code",[t._v("register_tx")]),t._v("/"),e("code",[t._v("register_output")]),t._v(" methods are confirmed.")]),t._v(" "),e("p",[t._v("You also need to notify LDK of any transactions with insufficient confirmations\nthat have been reorganized out of the chain. Transactions that need to be monitored for such\nreorganization are returned by "),e("code",[t._v("Confirm::get_relevant_txids")]),t._v(". If any of these transactions become\nunconfirmed, you must call "),e("code",[t._v("Confirm::transaction_unconfirmed")]),t._v(".")]),t._v(" "),e("p",[t._v("Lastly, you must notify LDK whenever a new chain tip is available using\nthe "),e("code",[t._v("Confirm::best_block_updated")]),t._v(" method. See the documentation for a full\npicture of how this interface is intended to be used.")]),t._v(" "),e("div",{staticClass:"custom-block tip"},[e("p",{staticClass:"custom-block-title"},[t._v("Note")]),t._v(" "),e("p",[t._v("Note that the described methods of "),e("code",[t._v("Confirm")]),t._v(" must be called in accordance with the ordering requirements\ndescribed in the "),e("a",{attrs:{href:"https://docs.rs/lightning/*/lightning/chain/trait.Confirm.html#order",target:"_blank",rel:"noopener noreferrer"}},[e("code",[t._v("Confirm")]),t._v(" documentation"),e("OutboundLink")],1)])]),t._v(" "),e("div",{staticClass:"custom-block tip"},[e("p",{staticClass:"custom-block-title"},[t._v("Note")]),t._v(" "),e("p",[t._v("Note that the described methods of "),e("code",[t._v("Confirm")]),t._v(" must be called both on the\n"),e("code",[t._v("ChannelManager")]),t._v(" "),e("em",[t._v("and")]),t._v(" the "),e("code",[t._v("ChainMonitor")]),t._v(".")])]),t._v(" "),e("div",{staticClass:"custom-block tip"},[e("p",{staticClass:"custom-block-title"},[t._v("Note")]),t._v(" "),e("p",[t._v("Be advised that "),e("code",[t._v("chain::Confirm")]),t._v(" is a less mature interface than\n"),e("code",[t._v("chain::Listen")]),t._v(". As such, there is not yet a utility like\n"),e("code",[t._v("lightning-block-sync")]),t._v(" to use for interacting with clients like Electrum.")])])])}),[],!1,null,null,null);e.default=o.exports}}]); \ No newline at end of file diff --git a/assets/js/40.19bc3e5e.js b/assets/js/40.b153dfa6.js similarity index 94% rename from assets/js/40.19bc3e5e.js rename to assets/js/40.b153dfa6.js index 0183dc1f2..b41286fc8 100644 --- a/assets/js/40.19bc3e5e.js +++ b/assets/js/40.b153dfa6.js @@ -1 +1 @@ -(window.webpackJsonp=window.webpackJsonp||[]).push([[40],{404:function(n,e,t){"use strict";t.r(e);var a=t(7),o=Object(a.a)({},(function(){var n=this,e=n._self._c;return e("ContentSlotsDistributor",{attrs:{"slot-key":n.$parent.slotKey}},[e("h1",{attrs:{id:"full-blocks"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#full-blocks"}},[n._v("#")]),n._v(" Full Blocks")]),n._v(" "),e("p",[n._v("If your Lightning node is backed by a Bitcoin full node, the operation is\nstraight forward: call the appropriate methods on "),e("code",[n._v("ChannelManager")]),n._v(" and\n"),e("code",[n._v("ChainMonitor")]),n._v(" as blocks are connected and disconnected. LDK will handle the\nrest!")]),n._v(" "),e("p",[n._v("So what happens? The "),e("code",[n._v("ChannelManager")]),n._v(" examines the block's transactions and\nupdates the internal channel state as needed. The "),e("code",[n._v("ChainMonitor")]),n._v(" will detect\nany spends of the channel funding transaction or any pertinent transaction\noutputs, tracking them as necessary.")]),n._v(" "),e("p",[n._v("If necessary, LDK will broadcast a transaction on your behalf. More on that\nlater. For now, let's look at the more interesting case of pre-filtered blocks.")])])}),[],!1,null,null,null);e.default=o.exports}}]); \ No newline at end of file +(window.webpackJsonp=window.webpackJsonp||[]).push([[40],{403:function(n,e,t){"use strict";t.r(e);var a=t(7),o=Object(a.a)({},(function(){var n=this,e=n._self._c;return e("ContentSlotsDistributor",{attrs:{"slot-key":n.$parent.slotKey}},[e("h1",{attrs:{id:"full-blocks"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#full-blocks"}},[n._v("#")]),n._v(" Full Blocks")]),n._v(" "),e("p",[n._v("If your Lightning node is backed by a Bitcoin full node, the operation is\nstraight forward: call the appropriate methods on "),e("code",[n._v("ChannelManager")]),n._v(" and\n"),e("code",[n._v("ChainMonitor")]),n._v(" as blocks are connected and disconnected. LDK will handle the\nrest!")]),n._v(" "),e("p",[n._v("So what happens? The "),e("code",[n._v("ChannelManager")]),n._v(" examines the block's transactions and\nupdates the internal channel state as needed. The "),e("code",[n._v("ChainMonitor")]),n._v(" will detect\nany spends of the channel funding transaction or any pertinent transaction\noutputs, tracking them as necessary.")]),n._v(" "),e("p",[n._v("If necessary, LDK will broadcast a transaction on your behalf. More on that\nlater. For now, let's look at the more interesting case of pre-filtered blocks.")])])}),[],!1,null,null,null);e.default=o.exports}}]); \ No newline at end of file diff --git a/assets/js/45.a29d7104.js b/assets/js/45.5fcf289f.js similarity index 99% rename from assets/js/45.a29d7104.js rename to assets/js/45.5fcf289f.js index ce9723a05..573b8c3b4 100644 --- a/assets/js/45.a29d7104.js +++ b/assets/js/45.5fcf289f.js @@ -1 +1 @@ -(window.webpackJsonp=window.webpackJsonp||[]).push([[45],{412:function(t,n,s){"use strict";s.r(n);var a=s(7),e=Object(a.a)({},(function(){var t=this,n=t._self._c;return n("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[n("h1",{attrs:{id:"handling-events"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#handling-events"}},[t._v("#")]),t._v(" Handling Events")]),t._v(" "),n("p",[t._v("LDK requires that you handle many different events throughout your app's life cycle. You can learn more by reading about our event-driven "),n("RouterLink",{attrs:{to:"/introduction/architecture/"}},[t._v("architecture")]),t._v(".")],1),t._v(" "),n("p",[t._v("To start handling events in your application, run:")]),t._v(" "),n("CodeSwitcher",{attrs:{languages:{rust:"Rust",kotlin:"Kotlin",swift:"Swift"}},scopedSlots:t._u([{key:"rust",fn:function(){return[n("div",{staticClass:"language-rust extra-class"},[n("pre",{pre:!0,attrs:{class:"language-rust"}},[n("code",[n("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("use")]),t._v(" "),n("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("lightning"),n("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),t._v("util"),n("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),t._v("events"),n("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),n("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),n("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Event")]),n("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),n("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),n("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// In the event handler passed to BackgroundProcessor::start")]),t._v("\n"),n("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("match")]),t._v(" event "),n("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),n("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Event")]),n("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),n("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("PaymentSent")]),t._v(" "),n("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" payment_preimage "),n("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),n("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),n("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),n("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Handle successful payment")]),t._v("\n "),n("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),n("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Event")]),n("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),n("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("PaymentFailed")]),t._v(" "),n("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" payment_hash"),n("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" rejected_by_dest "),n("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),n("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),n("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),n("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Handle failed payment")]),t._v("\n "),n("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),n("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Event")]),n("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),n("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("FundingGenerationReady")]),t._v(" "),n("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),n("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("..")]),t._v(" "),n("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),n("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),n("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),n("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Generate the funding transaction for the channel")]),t._v("\n "),n("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),n("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])])]},proxy:!0},{key:"kotlin",fn:function(){return[n("div",{staticClass:"language-kotlin extra-class"},[n("pre",{pre:!0,attrs:{class:"language-kotlin"}},[n("code",[n("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" org"),n("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("ldk"),n("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("structs"),n("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("Event\n\n"),n("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" "),n("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("event "),n("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("is")]),t._v(" Event"),n("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("PaymentSent"),n("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),n("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n"),n("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Handle successful payment")]),t._v("\n"),n("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),n("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" "),n("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("event "),n("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("is")]),t._v(" Event"),n("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("PaymentFailed"),n("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),n("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n"),n("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Handle failed payment")]),t._v("\n"),n("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),n("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" "),n("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("event "),n("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("is")]),t._v(" Event"),n("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("FundingGenerationReady"),n("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),n("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n"),n("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Create a funding tx to be broadcast")]),t._v("\n"),n("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n")])])])]},proxy:!0},{key:"swift",fn:function(){return[n("div",{staticClass:"language-Swift extra-class"},[n("pre",{pre:!0,attrs:{class:"language-swift"}},[n("code",[n("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" "),n("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("LightningDevKit")]),t._v("\n\n"),n("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" "),n("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" event "),n("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" event"),n("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),n("span",{pre:!0,attrs:{class:"token function"}},[t._v("getValueAsPaymentSent")]),n("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),n("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),n("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),n("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Handle successful payment")]),t._v("\n"),n("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),n("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" "),n("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" event "),n("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" event"),n("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),n("span",{pre:!0,attrs:{class:"token function"}},[t._v("getValueAsPaymentFailed")]),n("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),n("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),n("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),n("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Handle failed payment")]),t._v("\n"),n("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),n("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" "),n("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" event "),n("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" event"),n("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),n("span",{pre:!0,attrs:{class:"token function"}},[t._v("getValueAsFundingGenerationReady")]),n("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),n("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),n("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),n("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Create a funding tx to be broadcast")]),t._v("\n"),n("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])])]},proxy:!0}])}),t._v(" "),n("p",[t._v("References: "),n("a",{attrs:{href:"https://docs.rs/lightning/*/lightning/util/events/enum.Event.html",target:"_blank",rel:"noopener noreferrer"}},[t._v("Rust "),n("code",[t._v("Event")]),t._v(" docs"),n("OutboundLink")],1),t._v(", "),n("a",{attrs:{href:"https://github.com/lightningdevkit/ldk-garbagecollected/blob/main/src/main/java/org/ldk/structs/Event.java",target:"_blank",rel:"noopener noreferrer"}},[t._v("Java/Kotlin "),n("code",[t._v("Event")]),t._v(" bindings"),n("OutboundLink")],1)])],1)}),[],!1,null,null,null);n.default=e.exports}}]); \ No newline at end of file +(window.webpackJsonp=window.webpackJsonp||[]).push([[45],{410:function(t,n,s){"use strict";s.r(n);var a=s(7),e=Object(a.a)({},(function(){var t=this,n=t._self._c;return n("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[n("h1",{attrs:{id:"handling-events"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#handling-events"}},[t._v("#")]),t._v(" Handling Events")]),t._v(" "),n("p",[t._v("LDK requires that you handle many different events throughout your app's life cycle. You can learn more by reading about our event-driven "),n("RouterLink",{attrs:{to:"/introduction/architecture/"}},[t._v("architecture")]),t._v(".")],1),t._v(" "),n("p",[t._v("To start handling events in your application, run:")]),t._v(" "),n("CodeSwitcher",{attrs:{languages:{rust:"Rust",kotlin:"Kotlin",swift:"Swift"}},scopedSlots:t._u([{key:"rust",fn:function(){return[n("div",{staticClass:"language-rust extra-class"},[n("pre",{pre:!0,attrs:{class:"language-rust"}},[n("code",[n("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("use")]),t._v(" "),n("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("lightning"),n("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),t._v("util"),n("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),t._v("events"),n("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),n("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),n("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Event")]),n("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),n("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),n("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// In the event handler passed to BackgroundProcessor::start")]),t._v("\n"),n("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("match")]),t._v(" event "),n("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),n("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Event")]),n("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),n("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("PaymentSent")]),t._v(" "),n("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" payment_preimage "),n("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),n("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),n("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),n("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Handle successful payment")]),t._v("\n "),n("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),n("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Event")]),n("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),n("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("PaymentFailed")]),t._v(" "),n("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" payment_hash"),n("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" rejected_by_dest "),n("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),n("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),n("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),n("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Handle failed payment")]),t._v("\n "),n("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),n("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Event")]),n("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),n("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("FundingGenerationReady")]),t._v(" "),n("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),n("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("..")]),t._v(" "),n("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),n("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),n("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),n("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Generate the funding transaction for the channel")]),t._v("\n "),n("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),n("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])])]},proxy:!0},{key:"kotlin",fn:function(){return[n("div",{staticClass:"language-kotlin extra-class"},[n("pre",{pre:!0,attrs:{class:"language-kotlin"}},[n("code",[n("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" org"),n("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("ldk"),n("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("structs"),n("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("Event\n\n"),n("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" "),n("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("event "),n("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("is")]),t._v(" Event"),n("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("PaymentSent"),n("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),n("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n"),n("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Handle successful payment")]),t._v("\n"),n("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),n("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" "),n("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("event "),n("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("is")]),t._v(" Event"),n("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("PaymentFailed"),n("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),n("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n"),n("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Handle failed payment")]),t._v("\n"),n("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),n("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" "),n("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("event "),n("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("is")]),t._v(" Event"),n("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("FundingGenerationReady"),n("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),n("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n"),n("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Create a funding tx to be broadcast")]),t._v("\n"),n("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n")])])])]},proxy:!0},{key:"swift",fn:function(){return[n("div",{staticClass:"language-Swift extra-class"},[n("pre",{pre:!0,attrs:{class:"language-swift"}},[n("code",[n("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" "),n("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("LightningDevKit")]),t._v("\n\n"),n("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" "),n("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" event "),n("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" event"),n("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),n("span",{pre:!0,attrs:{class:"token function"}},[t._v("getValueAsPaymentSent")]),n("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),n("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),n("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),n("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Handle successful payment")]),t._v("\n"),n("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),n("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" "),n("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" event "),n("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" event"),n("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),n("span",{pre:!0,attrs:{class:"token function"}},[t._v("getValueAsPaymentFailed")]),n("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),n("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),n("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),n("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Handle failed payment")]),t._v("\n"),n("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),n("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" "),n("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" event "),n("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" event"),n("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),n("span",{pre:!0,attrs:{class:"token function"}},[t._v("getValueAsFundingGenerationReady")]),n("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),n("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),n("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),n("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Create a funding tx to be broadcast")]),t._v("\n"),n("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])])]},proxy:!0}])}),t._v(" "),n("p",[t._v("References: "),n("a",{attrs:{href:"https://docs.rs/lightning/*/lightning/util/events/enum.Event.html",target:"_blank",rel:"noopener noreferrer"}},[t._v("Rust "),n("code",[t._v("Event")]),t._v(" docs"),n("OutboundLink")],1),t._v(", "),n("a",{attrs:{href:"https://github.com/lightningdevkit/ldk-garbagecollected/blob/main/src/main/java/org/ldk/structs/Event.java",target:"_blank",rel:"noopener noreferrer"}},[t._v("Java/Kotlin "),n("code",[t._v("Event")]),t._v(" bindings"),n("OutboundLink")],1)])],1)}),[],!1,null,null,null);n.default=e.exports}}]); \ No newline at end of file diff --git a/assets/js/46.e511b353.js b/assets/js/46.41fa6e76.js similarity index 99% rename from assets/js/46.e511b353.js rename to assets/js/46.41fa6e76.js index d4ce4c679..f4e263b12 100644 --- a/assets/js/46.e511b353.js +++ b/assets/js/46.41fa6e76.js @@ -1 +1 @@ -(window.webpackJsonp=window.webpackJsonp||[]).push([[46],{410:function(t,s,n){"use strict";n.r(s);var a=n(7),e=Object(a.a)({},(function(){var t=this,s=t._self._c;return s("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[s("h1",{attrs:{id:"getting-started"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#getting-started"}},[t._v("#")]),t._v(" Getting started")]),t._v(" "),s("p",[t._v("Welcome to the Lightning Development Kit documentation!")]),t._v(" "),s("p",[t._v("If you have any questions about anything related to LDK, feel free to ask our community on "),s("a",{attrs:{href:"https://github.com/orgs/lightningdevkit/discussions",target:"_blank",rel:"noopener noreferrer"}},[t._v("GitHub Discussions"),s("OutboundLink")],1),t._v(" or join us on "),s("a",{attrs:{href:"https://discord.gg/xaYE3pDQpm",target:"_blank",rel:"noopener noreferrer"}},[t._v("Discord"),s("OutboundLink")],1),t._v(".")]),t._v(" "),s("h2",{attrs:{id:"installation"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#installation"}},[t._v("#")]),t._v(" Installation")]),t._v(" "),s("p",[t._v("Add LDK to a project by configuring the respective config files:")]),t._v(" "),s("CodeSwitcher",{attrs:{languages:{rust:"Rust",kotlin:"Kotlin"}},scopedSlots:t._u([{key:"rust",fn:function(){return[s("div",{staticClass:"language-toml extra-class"},[s("pre",{pre:!0,attrs:{class:"language-toml"}},[s("code",[t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("# Add the following dependencies to your cargo.toml and replace {VERSION} with the version number you want to use.")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token table class-name"}},[t._v("dependencies")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token key property"}},[t._v("lightning")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token key property"}},[t._v("version")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("VERSION"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token key property"}},[t._v("features")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"max_level_trace"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token key property"}},[t._v("lightning-block-sync")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token key property"}},[t._v("version")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("VERSION"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token key property"}},[t._v("features")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"rpc-client"')]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token key property"}},[t._v("lightning-invoice")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token key property"}},[t._v("version")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("VERSION"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token key property"}},[t._v("lightning-net-tokio")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token key property"}},[t._v("version")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("VERSION"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token key property"}},[t._v("lightning-persister")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token key property"}},[t._v("version")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("VERSION"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token key property"}},[t._v("lightning-background-processor")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token key property"}},[t._v("version")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("VERSION"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token key property"}},[t._v("lightning-rapid-gossip-sync")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token key property"}},[t._v("version")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("VERSION"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n")])])])]},proxy:!0},{key:"kotlin",fn:function(){return[s("div",{staticClass:"language-java extra-class"},[s("pre",{pre:!0,attrs:{class:"language-java"}},[s("code",[s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("/*\nFor Gradle, add the following dependency to your build.gradle and replace {VERSION} with\nthe version number you want to use.\n*/")]),t._v("\n\ndependencies "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// ...")]),t._v("\n implementation 'org"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("lightningdevkit"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v("ldk"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("-")]),t._v("java"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("VERSION")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("'\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// ...")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("/* To include the LDK Kotlin bindings in an Android project download the latest binary from https://github.com/lightningdevkit/ldk-garbagecollected/releases and place it in your libs directory.\nThen add to your build.gradle file:\n*/")]),t._v("\n\ndependencies "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// ...")]),t._v("\n implementation "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("fileTree")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("include"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token char"}},[t._v("'*.aar'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" dir"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token char"}},[t._v("'libs'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// ...")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])])]},proxy:!0}])}),t._v(" "),s("p",[t._v("Example usage after installation is complete:")]),t._v(" "),s("CodeSwitcher",{attrs:{languages:{rust:"Rust",kotlin:"Kotlin"}},scopedSlots:t._u([{key:"rust",fn:function(){return[s("div",{staticClass:"language-rust extra-class"},[s("pre",{pre:!0,attrs:{class:"language-rust"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("use")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("lightning"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),t._v("chain"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),t._v("chaininterface"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("FeeEstimator")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])])]},proxy:!0},{key:"kotlin",fn:function(){return[s("div",{staticClass:"language-java extra-class"},[s("pre",{pre:!0,attrs:{class:"language-java"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("org"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("ldk"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("structs"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")])]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("FeeEstimator")]),t._v("\n")])])])]},proxy:!0}])}),t._v(" "),s("div",{staticClass:"custom-block tip"},[s("p",{staticClass:"custom-block-title"},[t._v("Installing LDK Swift")]),t._v(" "),s("p",[t._v("Add ldk-swift package using the Swift Package Manager.")]),t._v(" "),s("p",[t._v("To import the package, use: "),s("code",[t._v("import LightningDevKit")])])])],1)}),[],!1,null,null,null);s.default=e.exports}}]); \ No newline at end of file +(window.webpackJsonp=window.webpackJsonp||[]).push([[46],{411:function(t,s,n){"use strict";n.r(s);var a=n(7),e=Object(a.a)({},(function(){var t=this,s=t._self._c;return s("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[s("h1",{attrs:{id:"getting-started"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#getting-started"}},[t._v("#")]),t._v(" Getting started")]),t._v(" "),s("p",[t._v("Welcome to the Lightning Development Kit documentation!")]),t._v(" "),s("p",[t._v("If you have any questions about anything related to LDK, feel free to ask our community on "),s("a",{attrs:{href:"https://github.com/orgs/lightningdevkit/discussions",target:"_blank",rel:"noopener noreferrer"}},[t._v("GitHub Discussions"),s("OutboundLink")],1),t._v(" or join us on "),s("a",{attrs:{href:"https://discord.gg/xaYE3pDQpm",target:"_blank",rel:"noopener noreferrer"}},[t._v("Discord"),s("OutboundLink")],1),t._v(".")]),t._v(" "),s("h2",{attrs:{id:"installation"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#installation"}},[t._v("#")]),t._v(" Installation")]),t._v(" "),s("p",[t._v("Add LDK to a project by configuring the respective config files:")]),t._v(" "),s("CodeSwitcher",{attrs:{languages:{rust:"Rust",kotlin:"Kotlin"}},scopedSlots:t._u([{key:"rust",fn:function(){return[s("div",{staticClass:"language-toml extra-class"},[s("pre",{pre:!0,attrs:{class:"language-toml"}},[s("code",[t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("# Add the following dependencies to your cargo.toml and replace {VERSION} with the version number you want to use.")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token table class-name"}},[t._v("dependencies")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token key property"}},[t._v("lightning")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token key property"}},[t._v("version")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("VERSION"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token key property"}},[t._v("features")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"max_level_trace"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token key property"}},[t._v("lightning-block-sync")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token key property"}},[t._v("version")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("VERSION"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token key property"}},[t._v("features")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"rpc-client"')]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token key property"}},[t._v("lightning-invoice")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token key property"}},[t._v("version")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("VERSION"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token key property"}},[t._v("lightning-net-tokio")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token key property"}},[t._v("version")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("VERSION"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token key property"}},[t._v("lightning-persister")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token key property"}},[t._v("version")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("VERSION"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token key property"}},[t._v("lightning-background-processor")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token key property"}},[t._v("version")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("VERSION"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token key property"}},[t._v("lightning-rapid-gossip-sync")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token key property"}},[t._v("version")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("VERSION"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n")])])])]},proxy:!0},{key:"kotlin",fn:function(){return[s("div",{staticClass:"language-java extra-class"},[s("pre",{pre:!0,attrs:{class:"language-java"}},[s("code",[s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("/*\nFor Gradle, add the following dependency to your build.gradle and replace {VERSION} with\nthe version number you want to use.\n*/")]),t._v("\n\ndependencies "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// ...")]),t._v("\n implementation 'org"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("lightningdevkit"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v("ldk"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("-")]),t._v("java"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("VERSION")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("'\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// ...")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("/* To include the LDK Kotlin bindings in an Android project download the latest binary from https://github.com/lightningdevkit/ldk-garbagecollected/releases and place it in your libs directory.\nThen add to your build.gradle file:\n*/")]),t._v("\n\ndependencies "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// ...")]),t._v("\n implementation "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("fileTree")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("include"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token char"}},[t._v("'*.aar'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" dir"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token char"}},[t._v("'libs'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// ...")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])])]},proxy:!0}])}),t._v(" "),s("p",[t._v("Example usage after installation is complete:")]),t._v(" "),s("CodeSwitcher",{attrs:{languages:{rust:"Rust",kotlin:"Kotlin"}},scopedSlots:t._u([{key:"rust",fn:function(){return[s("div",{staticClass:"language-rust extra-class"},[s("pre",{pre:!0,attrs:{class:"language-rust"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("use")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("lightning"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),t._v("chain"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),t._v("chaininterface"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("FeeEstimator")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])])]},proxy:!0},{key:"kotlin",fn:function(){return[s("div",{staticClass:"language-java extra-class"},[s("pre",{pre:!0,attrs:{class:"language-java"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("org"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("ldk"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("structs"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")])]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("FeeEstimator")]),t._v("\n")])])])]},proxy:!0}])}),t._v(" "),s("div",{staticClass:"custom-block tip"},[s("p",{staticClass:"custom-block-title"},[t._v("Installing LDK Swift")]),t._v(" "),s("p",[t._v("Add ldk-swift package using the Swift Package Manager.")]),t._v(" "),s("p",[t._v("To import the package, use: "),s("code",[t._v("import LightningDevKit")])])])],1)}),[],!1,null,null,null);s.default=e.exports}}]); \ No newline at end of file diff --git a/assets/js/47.6ac08a58.js b/assets/js/47.d00cd330.js similarity index 98% rename from assets/js/47.6ac08a58.js rename to assets/js/47.d00cd330.js index e5abfe381..8da8cf29d 100644 --- a/assets/js/47.6ac08a58.js +++ b/assets/js/47.d00cd330.js @@ -1 +1 @@ -(window.webpackJsonp=window.webpackJsonp||[]).push([[47],{411:function(t,n,e){"use strict";e.r(n);var r=e(7),o=Object(r.a)({},(function(){var t=this,n=t._self._c;return n("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[n("h1",{attrs:{id:"building-a-node-with-ldk"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#building-a-node-with-ldk"}},[t._v("#")]),t._v(" Building a Node with LDK")]),t._v(" "),n("h2",{attrs:{id:"learn-how-to-build-a-basic-ldk-node-from-scratch"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#learn-how-to-build-a-basic-ldk-node-from-scratch"}},[t._v("#")]),t._v(" Learn how to build a basic LDK node from scratch")]),t._v(" "),n("div",{staticClass:"custom-block tip"},[n("p",{staticClass:"custom-block-title"},[t._v("Note")]),t._v(" "),n("p",[t._v("For an integrated example of an LDK node in Rust, see the "),n("a",{attrs:{href:"https://github.com/lightningdevkit/ldk-sample",target:"_blank",rel:"noopener noreferrer"}},[t._v("Sample Node"),n("OutboundLink")],1)])]),t._v(" "),n("p",[t._v("The following tutorials will show you how to build the simplest lightning node using LDK, that fufills the following tasks:")]),t._v(" "),n("ol",[n("li",[n("strong",[t._v("Connecting to Peers")])]),t._v(" "),n("li",[n("strong",[t._v("Opening Channels")])]),t._v(" "),n("li",[n("strong",[t._v("Sending Payments")])]),t._v(" "),n("li",[n("strong",[t._v("Receiving Payments")])]),t._v(" "),n("li",[n("strong",[t._v("Closing Channels")])])]),t._v(" "),n("h3",{attrs:{id:"foundational-components"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#foundational-components"}},[t._v("#")]),t._v(" Foundational Components")]),t._v(" "),n("p",[t._v("Let's start by looking at the core components we'll need to make this node work for the tasks we outlined above.")]),t._v(" "),n("ol",[n("li",[t._v("A "),n("a",{attrs:{href:"https://docs.rs/lightning/*/lightning/ln/channelmanager/struct.ChannelManager.html",target:"_blank",rel:"noopener noreferrer"}},[n("code",[t._v("ChannelManager")]),n("OutboundLink")],1),t._v(", to open and close channels.")]),t._v(" "),n("li",[t._v("A networking stack (https://docs.rs/lightning-net-tokio/*/lightning_net_tokio/index.html), for establishing TCP/IP connections to other nodes on the lightning network.")]),t._v(" "),n("li",[t._v("Payments & routing, ability to create and pay invoices.")])]),t._v(" "),n("p",[t._v("To make the above work we also need to setup a series of supporting modules, including:")]),t._v(" "),n("ol",[n("li",[t._v("A "),n("a",{attrs:{href:"https://docs.rs/lightning/*/lightning/chain/chaininterface/trait.FeeEstimator.html",target:"_blank",rel:"noopener noreferrer"}},[n("code",[t._v("FeeEstimator")]),n("OutboundLink")],1)]),t._v(" "),n("li",[t._v("A "),n("a",{attrs:{href:"https://docs.rs/lightning/*/lightning/util/logger/index.html",target:"_blank",rel:"noopener noreferrer"}},[n("code",[t._v("Logger")]),n("OutboundLink")],1)]),t._v(" "),n("li",[t._v("A Transaction "),n("a",{attrs:{href:"https://docs.rs/lightning/*/lightning/chain/chaininterface/trait.BroadcasterInterface.html",target:"_blank",rel:"noopener noreferrer"}},[n("code",[t._v("Broadcaster")]),n("OutboundLink")],1)]),t._v(" "),n("li",[t._v("A "),n("a",{attrs:{href:"https://docs.rs/lightning/*/lightning/routing/gossip/struct.NetworkGraph.html",target:"_blank",rel:"noopener noreferrer"}},[n("code",[t._v("NetworkGraph")]),n("OutboundLink")],1)]),t._v(" "),n("li",[t._v("A "),n("a",{attrs:{href:"https://docs.rs/lightning/*/lightning/util/persist/trait.Persister.html",target:"_blank",rel:"noopener noreferrer"}},[n("code",[t._v("Persister")]),n("OutboundLink")],1)]),t._v(" "),n("li",[t._v("An "),n("a",{attrs:{href:"https://docs.rs/lightning/*/lightning/events/trait.EventHandler.html",target:"_blank",rel:"noopener noreferrer"}},[n("code",[t._v("EventHandler")]),n("OutboundLink")],1)]),t._v(" "),n("li",[t._v("A Transaction "),n("a",{attrs:{href:"https://docs.rs/lightning/*/lightning/chain/trait.Filter.html",target:"_blank",rel:"noopener noreferrer"}},[n("code",[t._v("Filter")]),n("OutboundLink")],1)]),t._v(" "),n("li",[t._v("A "),n("a",{attrs:{href:"https://docs.rs/lightning/*/lightning/chain/chainmonitor/index.html",target:"_blank",rel:"noopener noreferrer"}},[n("code",[t._v("ChainMonitor")]),n("OutboundLink")],1)]),t._v(" "),n("li",[t._v("A "),n("a",{attrs:{href:"https://docs.rs/lightning/*/lightning/sign/struct.KeysManager.html",target:"_blank",rel:"noopener noreferrer"}},[n("code",[t._v("KeysManager")]),n("OutboundLink")],1)]),t._v(" "),n("li",[t._v("A "),n("a",{attrs:{href:"https://docs.rs/lightning/*/lightning/routing/scoring/index.html",target:"_blank",rel:"noopener noreferrer"}},[n("code",[t._v("Scorer")]),n("OutboundLink")],1)])])])}),[],!1,null,null,null);n.default=o.exports}}]); \ No newline at end of file +(window.webpackJsonp=window.webpackJsonp||[]).push([[47],{412:function(t,n,e){"use strict";e.r(n);var r=e(7),o=Object(r.a)({},(function(){var t=this,n=t._self._c;return n("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[n("h1",{attrs:{id:"building-a-node-with-ldk"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#building-a-node-with-ldk"}},[t._v("#")]),t._v(" Building a Node with LDK")]),t._v(" "),n("h2",{attrs:{id:"learn-how-to-build-a-basic-ldk-node-from-scratch"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#learn-how-to-build-a-basic-ldk-node-from-scratch"}},[t._v("#")]),t._v(" Learn how to build a basic LDK node from scratch")]),t._v(" "),n("div",{staticClass:"custom-block tip"},[n("p",{staticClass:"custom-block-title"},[t._v("Note")]),t._v(" "),n("p",[t._v("For an integrated example of an LDK node in Rust, see the "),n("a",{attrs:{href:"https://github.com/lightningdevkit/ldk-sample",target:"_blank",rel:"noopener noreferrer"}},[t._v("Sample Node"),n("OutboundLink")],1)])]),t._v(" "),n("p",[t._v("The following tutorials will show you how to build the simplest lightning node using LDK, that fufills the following tasks:")]),t._v(" "),n("ol",[n("li",[n("strong",[t._v("Connecting to Peers")])]),t._v(" "),n("li",[n("strong",[t._v("Opening Channels")])]),t._v(" "),n("li",[n("strong",[t._v("Sending Payments")])]),t._v(" "),n("li",[n("strong",[t._v("Receiving Payments")])]),t._v(" "),n("li",[n("strong",[t._v("Closing Channels")])])]),t._v(" "),n("h3",{attrs:{id:"foundational-components"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#foundational-components"}},[t._v("#")]),t._v(" Foundational Components")]),t._v(" "),n("p",[t._v("Let's start by looking at the core components we'll need to make this node work for the tasks we outlined above.")]),t._v(" "),n("ol",[n("li",[t._v("A "),n("a",{attrs:{href:"https://docs.rs/lightning/*/lightning/ln/channelmanager/struct.ChannelManager.html",target:"_blank",rel:"noopener noreferrer"}},[n("code",[t._v("ChannelManager")]),n("OutboundLink")],1),t._v(", to open and close channels.")]),t._v(" "),n("li",[t._v("A networking stack (https://docs.rs/lightning-net-tokio/*/lightning_net_tokio/index.html), for establishing TCP/IP connections to other nodes on the lightning network.")]),t._v(" "),n("li",[t._v("Payments & routing, ability to create and pay invoices.")])]),t._v(" "),n("p",[t._v("To make the above work we also need to setup a series of supporting modules, including:")]),t._v(" "),n("ol",[n("li",[t._v("A "),n("a",{attrs:{href:"https://docs.rs/lightning/*/lightning/chain/chaininterface/trait.FeeEstimator.html",target:"_blank",rel:"noopener noreferrer"}},[n("code",[t._v("FeeEstimator")]),n("OutboundLink")],1)]),t._v(" "),n("li",[t._v("A "),n("a",{attrs:{href:"https://docs.rs/lightning/*/lightning/util/logger/index.html",target:"_blank",rel:"noopener noreferrer"}},[n("code",[t._v("Logger")]),n("OutboundLink")],1)]),t._v(" "),n("li",[t._v("A Transaction "),n("a",{attrs:{href:"https://docs.rs/lightning/*/lightning/chain/chaininterface/trait.BroadcasterInterface.html",target:"_blank",rel:"noopener noreferrer"}},[n("code",[t._v("Broadcaster")]),n("OutboundLink")],1)]),t._v(" "),n("li",[t._v("A "),n("a",{attrs:{href:"https://docs.rs/lightning/*/lightning/routing/gossip/struct.NetworkGraph.html",target:"_blank",rel:"noopener noreferrer"}},[n("code",[t._v("NetworkGraph")]),n("OutboundLink")],1)]),t._v(" "),n("li",[t._v("A "),n("a",{attrs:{href:"https://docs.rs/lightning/*/lightning/util/persist/trait.Persister.html",target:"_blank",rel:"noopener noreferrer"}},[n("code",[t._v("Persister")]),n("OutboundLink")],1)]),t._v(" "),n("li",[t._v("An "),n("a",{attrs:{href:"https://docs.rs/lightning/*/lightning/events/trait.EventHandler.html",target:"_blank",rel:"noopener noreferrer"}},[n("code",[t._v("EventHandler")]),n("OutboundLink")],1)]),t._v(" "),n("li",[t._v("A Transaction "),n("a",{attrs:{href:"https://docs.rs/lightning/*/lightning/chain/trait.Filter.html",target:"_blank",rel:"noopener noreferrer"}},[n("code",[t._v("Filter")]),n("OutboundLink")],1)]),t._v(" "),n("li",[t._v("A "),n("a",{attrs:{href:"https://docs.rs/lightning/*/lightning/chain/chainmonitor/index.html",target:"_blank",rel:"noopener noreferrer"}},[n("code",[t._v("ChainMonitor")]),n("OutboundLink")],1)]),t._v(" "),n("li",[t._v("A "),n("a",{attrs:{href:"https://docs.rs/lightning/*/lightning/sign/struct.KeysManager.html",target:"_blank",rel:"noopener noreferrer"}},[n("code",[t._v("KeysManager")]),n("OutboundLink")],1)]),t._v(" "),n("li",[t._v("A "),n("a",{attrs:{href:"https://docs.rs/lightning/*/lightning/routing/scoring/index.html",target:"_blank",rel:"noopener noreferrer"}},[n("code",[t._v("Scorer")]),n("OutboundLink")],1)])])])}),[],!1,null,null,null);n.default=o.exports}}]); \ No newline at end of file diff --git a/assets/js/50.bcdfd20e.js b/assets/js/50.58c5025e.js similarity index 99% rename from assets/js/50.bcdfd20e.js rename to assets/js/50.58c5025e.js index 955ab6396..785f54e53 100644 --- a/assets/js/50.bcdfd20e.js +++ b/assets/js/50.58c5025e.js @@ -1 +1 @@ -(window.webpackJsonp=window.webpackJsonp||[]).push([[50],{415:function(t,a,s){"use strict";s.r(a);var n=s(7),e=Object(n.a)({},(function(){var t=this,a=t._self._c;return a("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[a("h1",{attrs:{id:"sending-payments"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#sending-payments"}},[t._v("#")]),t._v(" Sending Payments")]),t._v(" "),a("p",[t._v("Lightning payments are used to pay invoices, which are typically encoded as a\nstring in accordance with BOLT 11. After parsing the invoice, you'll need to\nfind a route from your node to the recipient and then make the payment using\n"),a("code",[t._v("ChannelManager")]),t._v(".")]),t._v(" "),a("CodeSwitcher",{attrs:{languages:{rust:"Rust",kotlin:"Kotlin",swift:"Swift"}},scopedSlots:t._u([{key:"rust",fn:function(){return[a("div",{staticClass:"language-rust extra-class"},[a("pre",{pre:!0,attrs:{class:"language-rust"}},[a("code",[a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Parse the invoice.")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" invoice "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Invoice")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("from_str")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("encoded_invoice"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n\t"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("expect")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"ERROR: failed to parse invoice"')]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" amt_pico_btc "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" invoice"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("amount_pico_btc")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n\t"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("expect")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"ERROR: invalid invoice: must contain amount to pay"')]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" amt_msat "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" amt_pico_btc "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("/")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("10")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" payer_pubkey "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" channel_manager"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("get_our_node_id")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" network_graph "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" router"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("network_graph"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("read")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("unwrap")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" payee_pubkey "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" invoice"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("recover_payee_pub_key")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" payee_features "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" invoice"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("features")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("cloned")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" first_hops "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" channel_manager"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("list_usable_channels")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" last_hops "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" invoice"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("route_hints")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" final_cltv "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" invoice"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("min_final_cltv_expiry")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("as")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("u32")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Find a route and send the payment.")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" route "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("router"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("get_route")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n\t"),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v("payer_pubkey"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v("network_graph"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v("payee_pubkey"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" payee_features"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n\t"),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Some")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v("first_hops"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("iter")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("collect")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Vec")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),t._v("_"),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">>")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v("last_hops"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n\tamt_msat"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" final_cltv"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" logger"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("clone")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("expect")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"ERROR: failed to find route"')]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" payment_hash "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("PaymentHash")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("invoice"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("payment_hash")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("clone")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("into_inner")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" payment_secret "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" invoice"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("payment_secret")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("cloned")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\nchannel_manager"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("send_payment")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v("route"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" payment_hash"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v("payment_secret"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n\t"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("expect")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"ERROR: failed to send payment"')]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])])]},proxy:!0},{key:"kotlin",fn:function(){return[a("div",{staticClass:"language-java extra-class"},[a("pre",{pre:!0,attrs:{class:"language-java"}},[a("code",[a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Get an invoice from the recipient/payee")]),t._v("\nval invoice "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Bolt11Invoice")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("from_str")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("recipientInvoice"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\nval invoiceResult "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("invoice as "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Result_Bolt11InvoiceParseOrSemanticErrorZ"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("Result_Bolt11InvoiceParseOrSemanticErrorZ_OK")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("res\nval paymentParams "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("UtilMethods")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("payment_parameters_from_invoice")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("invoiceResult"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\nval paymentParamsResult "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("paymentParams as "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Result_C3Tuple_ThirtyTwoBytesRecipientOnionFieldsRouteParametersZNoneZ"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("Result_C3Tuple_ThirtyTwoBytesRecipientOnionFieldsRouteParametersZNoneZ_OK")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("res\n\nval paymentHash "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" paymentParamsResult"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("_a\nval recipientOnion "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" paymentParamsResult"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("_b\nval paymentId "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" paymentParamsResult"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("_a\nval routeParams "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" paymentParamsResult"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("_c\n\nval res "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" channelManager"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("send_payment")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("paymentHash"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" recipientOnion"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" paymentId"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" routeParams"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Retry")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("attempts")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("5")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("res"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("is_ok"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Payment success")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])])]},proxy:!0},{key:"swift",fn:function(){return[a("div",{staticClass:"language-Swift extra-class"},[a("pre",{pre:!0,attrs:{class:"language-swift"}},[a("code",[a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" invoiceStr "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// get an invoice from the payee")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" parsedInvoice "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Bolt11Invoice")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("fromStr")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("s"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" invoiceStr"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" invoiceVal "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" parsedInvoice"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("getValue")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" invoicePaymentResult "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Bindings")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("paymentParametersFromInvoice")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("invoice"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" invoiceVal"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("guard")]),t._v(" invoicePaymentResult"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("isOk")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("else")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token boolean"}},[t._v("false")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("paymentHash"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" recipientOnion"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" routeParams"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Bindings")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("paymentParametersFromInvoice")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("invoice"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" invoiceVal"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("getValue")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("!")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" paymentId "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" invoice"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("paymentHash")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("!")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" res "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" channelManager"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("sendPayment")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n paymentHash"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" paymentHash"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" \n recipientOnion"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" recipientOnion"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" \n paymentId"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" paymentId"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" \n routeParams"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" routeParams"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" \n retryStrategy"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("initWithTimeout")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("a"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("15")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" res"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("isOk")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Payment Sent")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])])]},proxy:!0}])}),t._v(" "),a("h1",{attrs:{id:"paymentsent-paymentfailed-event-handling"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#paymentsent-paymentfailed-event-handling"}},[t._v("#")]),t._v(" PaymentSent & PaymentFailed Event Handling")]),t._v(" "),a("p",[t._v("An event is generated once a payment has completed. Successful payments result\nin a "),a("code",[t._v("PaymentSent")]),t._v(" event with the preimage of the payment hash. Be sure to look\nout for a "),a("code",[t._v("PaymentFailed")]),t._v(" event, if the payment fails for some reason, and act\naccordingly.")]),t._v(" "),a("CodeSwitcher",{attrs:{languages:{rust:"Rust",kotlin:"Kotlin",swift:"Swift"}},scopedSlots:t._u([{key:"rust",fn:function(){return[a("div",{staticClass:"language-rust extra-class"},[a("pre",{pre:!0,attrs:{class:"language-rust"}},[a("code",[a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// In the event handler passed to BackgroundProcessor::start")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("match")]),t._v(" event "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n\t"),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Event")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("PaymentSent")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" payment_preimage "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n\t\t"),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Handle successful payment")]),t._v("\n\t"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\t"),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Event")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("PaymentFailed")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" payment_hash"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" rejected_by_dest "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n\t\t"),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Handle failed payment")]),t._v("\n\t"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\t"),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// ...")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])])]},proxy:!0},{key:"kotlin",fn:function(){return[a("div",{staticClass:"language-java extra-class"},[a("pre",{pre:!0,attrs:{class:"language-java"}},[a("code",[a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// In the `handleEvent` method of ChannelManagerPersister implementation")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("event is "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Event"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("PaymentSent")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Handle successful payment")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("event is "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Event"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("PaymentFailed")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Handle failed payment")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])])]},proxy:!0},{key:"swift",fn:function(){return[a("div",{staticClass:"language-Swift extra-class"},[a("pre",{pre:!0,attrs:{class:"language-swift"}},[a("code",[a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// In the `handleEvent` method of ChannelManagerPersister implementation")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" paymentSentEvent "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" event"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("getValueAsPaymentSent")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Handle successful payment")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("else")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" paymentFailedEvent "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" event"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("getValueAsPaymentFailed")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Handle failed payment")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])])]},proxy:!0}])}),t._v(" "),a("p",[a("strong",[t._v("References:")]),t._v(" "),a("a",{attrs:{href:"https://docs.rs/lightning/*/lightning/events/enum.Event.html#variant.PaymentSent",target:"_blank",rel:"noopener noreferrer"}},[t._v("Rust "),a("code",[t._v("PaymentSent")]),t._v(" docs"),a("OutboundLink")],1),t._v(","),a("a",{attrs:{href:"https://docs.rs/lightning/*/lightning/events/enum.Event.html#variant.PaymentFailed",target:"_blank",rel:"noopener noreferrer"}},[t._v("Rust "),a("code",[t._v("PaymentFailed")]),t._v(" docs"),a("OutboundLink")],1),t._v(", "),a("a",{attrs:{href:"https://github.com/lightningdevkit/ldk-garbagecollected/blob/main/src/main/java/org/ldk/structs/Event.java#L464",target:"_blank",rel:"noopener noreferrer"}},[t._v("Java/Kotlin "),a("code",[t._v("PaymentSent")]),t._v(" bindings"),a("OutboundLink")],1),t._v(", "),a("a",{attrs:{href:"https://github.com/lightningdevkit/ldk-garbagecollected/blob/main/src/main/java/org/ldk/structs/Event.java#L512",target:"_blank",rel:"noopener noreferrer"}},[t._v("Java/Kotlin "),a("code",[t._v("PaymentFailed")]),t._v(" bindings"),a("OutboundLink")],1)])],1)}),[],!1,null,null,null);a.default=e.exports}}]); \ No newline at end of file +(window.webpackJsonp=window.webpackJsonp||[]).push([[50],{417:function(t,a,s){"use strict";s.r(a);var n=s(7),e=Object(n.a)({},(function(){var t=this,a=t._self._c;return a("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[a("h1",{attrs:{id:"sending-payments"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#sending-payments"}},[t._v("#")]),t._v(" Sending Payments")]),t._v(" "),a("p",[t._v("Lightning payments are used to pay invoices, which are typically encoded as a\nstring in accordance with BOLT 11. After parsing the invoice, you'll need to\nfind a route from your node to the recipient and then make the payment using\n"),a("code",[t._v("ChannelManager")]),t._v(".")]),t._v(" "),a("CodeSwitcher",{attrs:{languages:{rust:"Rust",kotlin:"Kotlin",swift:"Swift"}},scopedSlots:t._u([{key:"rust",fn:function(){return[a("div",{staticClass:"language-rust extra-class"},[a("pre",{pre:!0,attrs:{class:"language-rust"}},[a("code",[a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Parse the invoice.")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" invoice "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Invoice")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("from_str")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("encoded_invoice"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n\t"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("expect")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"ERROR: failed to parse invoice"')]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" amt_pico_btc "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" invoice"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("amount_pico_btc")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n\t"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("expect")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"ERROR: invalid invoice: must contain amount to pay"')]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" amt_msat "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" amt_pico_btc "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("/")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("10")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" payer_pubkey "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" channel_manager"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("get_our_node_id")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" network_graph "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" router"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("network_graph"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("read")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("unwrap")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" payee_pubkey "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" invoice"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("recover_payee_pub_key")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" payee_features "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" invoice"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("features")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("cloned")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" first_hops "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" channel_manager"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("list_usable_channels")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" last_hops "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" invoice"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("route_hints")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" final_cltv "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" invoice"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("min_final_cltv_expiry")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("as")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("u32")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Find a route and send the payment.")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" route "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("router"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("get_route")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n\t"),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v("payer_pubkey"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v("network_graph"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v("payee_pubkey"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" payee_features"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n\t"),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Some")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v("first_hops"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("iter")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("collect")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Vec")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),t._v("_"),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">>")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v("last_hops"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n\tamt_msat"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" final_cltv"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" logger"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("clone")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("expect")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"ERROR: failed to find route"')]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" payment_hash "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("PaymentHash")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("invoice"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("payment_hash")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("clone")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("into_inner")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" payment_secret "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" invoice"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("payment_secret")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("cloned")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\nchannel_manager"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("send_payment")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v("route"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" payment_hash"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v("payment_secret"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n\t"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("expect")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"ERROR: failed to send payment"')]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])])]},proxy:!0},{key:"kotlin",fn:function(){return[a("div",{staticClass:"language-java extra-class"},[a("pre",{pre:!0,attrs:{class:"language-java"}},[a("code",[a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Get an invoice from the recipient/payee")]),t._v("\nval invoice "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Bolt11Invoice")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("from_str")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("recipientInvoice"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\nval invoiceResult "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("invoice as "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Result_Bolt11InvoiceParseOrSemanticErrorZ"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("Result_Bolt11InvoiceParseOrSemanticErrorZ_OK")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("res\nval paymentParams "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("UtilMethods")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("payment_parameters_from_invoice")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("invoiceResult"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\nval paymentParamsResult "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("paymentParams as "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Result_C3Tuple_ThirtyTwoBytesRecipientOnionFieldsRouteParametersZNoneZ"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("Result_C3Tuple_ThirtyTwoBytesRecipientOnionFieldsRouteParametersZNoneZ_OK")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("res\n\nval paymentHash "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" paymentParamsResult"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("_a\nval recipientOnion "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" paymentParamsResult"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("_b\nval paymentId "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" paymentParamsResult"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("_a\nval routeParams "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" paymentParamsResult"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("_c\n\nval res "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" channelManager"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("send_payment")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("paymentHash"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" recipientOnion"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" paymentId"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" routeParams"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Retry")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("attempts")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("5")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("res"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("is_ok"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Payment success")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])])]},proxy:!0},{key:"swift",fn:function(){return[a("div",{staticClass:"language-Swift extra-class"},[a("pre",{pre:!0,attrs:{class:"language-swift"}},[a("code",[a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" invoiceStr "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// get an invoice from the payee")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" parsedInvoice "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Bolt11Invoice")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("fromStr")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("s"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" invoiceStr"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" invoiceVal "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" parsedInvoice"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("getValue")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" invoicePaymentResult "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Bindings")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("paymentParametersFromInvoice")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("invoice"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" invoiceVal"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("guard")]),t._v(" invoicePaymentResult"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("isOk")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("else")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token boolean"}},[t._v("false")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("paymentHash"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" recipientOnion"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" routeParams"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Bindings")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("paymentParametersFromInvoice")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("invoice"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" invoiceVal"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("getValue")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("!")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" paymentId "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" invoice"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("paymentHash")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("!")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" res "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" channelManager"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("sendPayment")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n paymentHash"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" paymentHash"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" \n recipientOnion"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" recipientOnion"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" \n paymentId"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" paymentId"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" \n routeParams"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" routeParams"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" \n retryStrategy"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("initWithTimeout")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("a"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("15")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" res"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("isOk")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Payment Sent")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])])]},proxy:!0}])}),t._v(" "),a("h1",{attrs:{id:"paymentsent-paymentfailed-event-handling"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#paymentsent-paymentfailed-event-handling"}},[t._v("#")]),t._v(" PaymentSent & PaymentFailed Event Handling")]),t._v(" "),a("p",[t._v("An event is generated once a payment has completed. Successful payments result\nin a "),a("code",[t._v("PaymentSent")]),t._v(" event with the preimage of the payment hash. Be sure to look\nout for a "),a("code",[t._v("PaymentFailed")]),t._v(" event, if the payment fails for some reason, and act\naccordingly.")]),t._v(" "),a("CodeSwitcher",{attrs:{languages:{rust:"Rust",kotlin:"Kotlin",swift:"Swift"}},scopedSlots:t._u([{key:"rust",fn:function(){return[a("div",{staticClass:"language-rust extra-class"},[a("pre",{pre:!0,attrs:{class:"language-rust"}},[a("code",[a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// In the event handler passed to BackgroundProcessor::start")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("match")]),t._v(" event "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n\t"),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Event")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("PaymentSent")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" payment_preimage "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n\t\t"),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Handle successful payment")]),t._v("\n\t"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\t"),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Event")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("PaymentFailed")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" payment_hash"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" rejected_by_dest "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n\t\t"),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Handle failed payment")]),t._v("\n\t"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\t"),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// ...")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])])]},proxy:!0},{key:"kotlin",fn:function(){return[a("div",{staticClass:"language-java extra-class"},[a("pre",{pre:!0,attrs:{class:"language-java"}},[a("code",[a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// In the `handleEvent` method of ChannelManagerPersister implementation")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("event is "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Event"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("PaymentSent")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Handle successful payment")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("event is "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Event"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("PaymentFailed")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Handle failed payment")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])])]},proxy:!0},{key:"swift",fn:function(){return[a("div",{staticClass:"language-Swift extra-class"},[a("pre",{pre:!0,attrs:{class:"language-swift"}},[a("code",[a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// In the `handleEvent` method of ChannelManagerPersister implementation")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" paymentSentEvent "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" event"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("getValueAsPaymentSent")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Handle successful payment")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("else")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" paymentFailedEvent "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" event"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("getValueAsPaymentFailed")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Handle failed payment")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])])]},proxy:!0}])}),t._v(" "),a("p",[a("strong",[t._v("References:")]),t._v(" "),a("a",{attrs:{href:"https://docs.rs/lightning/*/lightning/events/enum.Event.html#variant.PaymentSent",target:"_blank",rel:"noopener noreferrer"}},[t._v("Rust "),a("code",[t._v("PaymentSent")]),t._v(" docs"),a("OutboundLink")],1),t._v(","),a("a",{attrs:{href:"https://docs.rs/lightning/*/lightning/events/enum.Event.html#variant.PaymentFailed",target:"_blank",rel:"noopener noreferrer"}},[t._v("Rust "),a("code",[t._v("PaymentFailed")]),t._v(" docs"),a("OutboundLink")],1),t._v(", "),a("a",{attrs:{href:"https://github.com/lightningdevkit/ldk-garbagecollected/blob/main/src/main/java/org/ldk/structs/Event.java#L464",target:"_blank",rel:"noopener noreferrer"}},[t._v("Java/Kotlin "),a("code",[t._v("PaymentSent")]),t._v(" bindings"),a("OutboundLink")],1),t._v(", "),a("a",{attrs:{href:"https://github.com/lightningdevkit/ldk-garbagecollected/blob/main/src/main/java/org/ldk/structs/Event.java#L512",target:"_blank",rel:"noopener noreferrer"}},[t._v("Java/Kotlin "),a("code",[t._v("PaymentFailed")]),t._v(" bindings"),a("OutboundLink")],1)])],1)}),[],!1,null,null,null);a.default=e.exports}}]); \ No newline at end of file diff --git a/assets/js/51.ef2675ae.js b/assets/js/51.c8821592.js similarity index 99% rename from assets/js/51.ef2675ae.js rename to assets/js/51.c8821592.js index bc174efcf..589df6d81 100644 --- a/assets/js/51.ef2675ae.js +++ b/assets/js/51.c8821592.js @@ -1 +1 @@ -(window.webpackJsonp=window.webpackJsonp||[]).push([[51],{417:function(t,s,a){"use strict";a.r(s);var n=a(7),e=Object(n.a)({},(function(){var t=this,s=t._self._c;return s("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[s("h1",{attrs:{id:"setting-up-a-channelmanager"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#setting-up-a-channelmanager"}},[t._v("#")]),t._v(" Setting up a ChannelManager")]),t._v(" "),s("p",[t._v("The "),s("code",[t._v("ChannelManager")]),t._v(" is responsible for several tasks related to managing channel state. This includes keeping track of many channels, sending messages to appropriate channels, creating channels and more.")]),t._v(" "),s("h2",{attrs:{id:"adding-a-channelmanager"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#adding-a-channelmanager"}},[t._v("#")]),t._v(" Adding a ChannelManager")]),t._v(" "),s("p",[t._v("Adding a "),s("code",[t._v("ChannelManager")]),t._v(" to your application should look something like this:")]),t._v(" "),s("CodeSwitcher",{attrs:{languages:{rust:"Rust",kotlin:"Kotlin",swift:"Swift"}},scopedSlots:t._u([{key:"rust",fn:function(){return[s("div",{staticClass:"language-rust extra-class"},[s("pre",{pre:!0,attrs:{class:"language-rust"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("use")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("lightning"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),t._v("ln"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),t._v("channelmanager"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" channel_manager "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("ChannelManager")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("new")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v("fee_estimator"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v("chain_monitor"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v("broadcaster"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v("router"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v("logger"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v("entropy_source"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v("node_signer"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v("signer_provider"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n user_config"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n chain_params"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n current_timestamp\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])])]},proxy:!0},{key:"kotlin",fn:function(){return[s("div",{staticClass:"language-kotlin extra-class"},[s("pre",{pre:!0,attrs:{class:"language-kotlin"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" org"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("ldk"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("batteries"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("ChannelManagerConstructor\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" channelManagerConstructor "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("ChannelManagerConstructor")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n Network"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("LDKNetwork_Regtest"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n userConfig"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n latestBlockHash"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n latestBlockHeight"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n keysManager"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("as_EntropySource")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n keysManager"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("as_NodeSigner")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n keysManager"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("as_SignerProvider")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n feeEstimator"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n chainMonitor"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n router"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n scoringParams"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n routerWrapper"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// optional")]),t._v("\n txBroadcaster"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n logger\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n")])])])]},proxy:!0},{key:"swift",fn:function(){return[s("div",{staticClass:"language-Swift extra-class"},[s("pre",{pre:!0,attrs:{class:"language-swift"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("LightningDevKit")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" channelManagerConstructionParameters "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("ChannelManagerConstructionParameters")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n config"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" userConfig"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n entropySource"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" keysManager"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("asEntropySource")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n nodeSigner"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" keysManager"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("asNodeSigner")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n signerProvider"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" keysManager"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("asSignerProvider")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n feeEstimator"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" feeEstimator"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n chainMonitor"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" chainMonitor"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n txBroadcaster"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" broadcaster"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n logger"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" logger"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n enableP2PGossip"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token boolean"}},[t._v("true")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n scorer"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" scorer\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" channelManagerConstructor "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("ChannelManagerConstructor")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n network"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" network"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n currentBlockchainTipHash"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" latestBlockHash"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n currentBlockchainTipHeight"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" latestBlockHeight"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n netGraph"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" netGraph"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n params"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" channelManagerConstructionParameters\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n")])])])]},proxy:!0}])}),t._v(" "),s("p",[t._v("There are a few dependencies needed to get this working. Let's walk through setting up each one so we can plug them into our "),s("code",[t._v("ChannelManager")]),t._v(".")]),t._v(" "),s("h3",{attrs:{id:"initialize-the-feeestimator"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#initialize-the-feeestimator"}},[t._v("#")]),t._v(" Initialize the "),s("code",[t._v("FeeEstimator")])]),t._v(" "),s("p",[s("strong",[t._v("What it's used for:")]),t._v(" estimating fees for on-chain transactions that LDK wants broadcasted.")]),t._v(" "),s("CodeSwitcher",{attrs:{languages:{rust:"Rust",kotlin:"Kotlin",swift:"Swift"}},scopedSlots:t._u([{key:"rust",fn:function(){return[s("div",{staticClass:"language-rust extra-class"},[s("pre",{pre:!0,attrs:{class:"language-rust"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("struct")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token type-definition class-name"}},[t._v("YourFeeEstimator")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("impl")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("FeeEstimator")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("for")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("YourFeeEstimator")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("fn")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function-definition function"}},[t._v("get_est_sat_per_1000_weight")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("self")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" confirmation_target"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("ConfirmationTarget")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("->")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("u32")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("match")]),t._v(" confirmation_target "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("ConfirmationTarget")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Background")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Fetch background feerate,")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// You can add the code here for this case")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("ConfirmationTarget")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Normal")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Fetch normal feerate (~6 blocks)")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// You can add the code here for this case")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("ConfirmationTarget")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("HighPriority")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Fetch high priority feerate")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// You can add the code here for this case")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" fee_estimator "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("YourFeeEstimator")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])])]},proxy:!0},{key:"kotlin",fn:function(){return[s("div",{staticClass:"language-java extra-class"},[s("pre",{pre:!0,attrs:{class:"language-java"}},[s("code",[t._v("object "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("YourFeeEstimator")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("FeeEstimatorInterface")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n override fun "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("get_est_sat_per_1000_weight")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("confirmationTarget"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("ConfirmationTarget")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Int")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("confirmationTarget "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("==")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("ConfirmationTarget"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("LDKConfirmationTarget_Background")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// ")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("confirmationTarget "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("==")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("ConfirmationTarget"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("LDKConfirmationTarget_Normal")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// ")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("confirmationTarget "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("==")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("ConfirmationTarget"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("LDKConfirmationTarget_HighPriority")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// ")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// return default fee rate")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\nval feeEstimator"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("FeeEstimator")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("FeeEstimator")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("new_impl")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("YourFeeEstimator")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n")])])])]},proxy:!0},{key:"swift",fn:function(){return[s("div",{staticClass:"language-Swift extra-class"},[s("pre",{pre:!0,attrs:{class:"language-swift"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("MyFeeEstimator")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("FeeEstimator")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("override")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("func")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function-definition function"}},[t._v("getEstSatPer1000Weight")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("confirmationTarget"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Bindings")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("ConfirmationTarget")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("UInt32")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" confirmationTarget "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("==")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("MinAllowedNonAnchorChannelRemoteFee")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("253")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("else")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" confirmationTarget "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("==")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("ChannelCloseMinimum")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1000")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("else")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" confirmationTarget "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("==")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("NonAnchorChannelFee")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("7500")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("else")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" confirmationTarget "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("==")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("OnChainSweep")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("7500")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("7500")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" feeEstimator "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("MyFeeEstimator")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n\n")])])])]},proxy:!0}])}),t._v(" "),s("p",[s("strong",[t._v("Implementation notes:")])]),t._v(" "),s("ol",[s("li",[t._v("Fees must be returned in: satoshis per 1000 weight units")]),t._v(" "),s("li",[t._v("Fees must be no smaller than 253 (equivalent to 1 satoshi/vbyte, rounded up)")]),t._v(" "),s("li",[t._v("To reduce network traffic, you may want to cache fee results rather than\nretrieving fresh ones every time")])]),t._v(" "),s("p",[s("strong",[t._v("Dependencies:")]),t._v(" "),s("em",[t._v("none")])]),t._v(" "),s("p",[s("strong",[t._v("References:")]),t._v(" "),s("a",{attrs:{href:"https://docs.rs/lightning/*/lightning/chain/chaininterface/trait.FeeEstimator.html",target:"_blank",rel:"noopener noreferrer"}},[t._v("Rust "),s("code",[t._v("FeeEstimator")]),t._v(" docs"),s("OutboundLink")],1),t._v(", "),s("a",{attrs:{href:"https://github.com/lightningdevkit/ldk-garbagecollected/blob/main/src/main/java/org/ldk/structs/FeeEstimator.java",target:"_blank",rel:"noopener noreferrer"}},[t._v("Java/Kotlin "),s("code",[t._v("FeeEstimator")]),t._v(" bindings"),s("OutboundLink")],1)]),t._v(" "),s("h3",{attrs:{id:"initialize-the-router"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#initialize-the-router"}},[t._v("#")]),t._v(" Initialize the "),s("code",[t._v("Router")])]),t._v(" "),s("p",[s("strong",[t._v("What it's used for:")]),t._v(" Finds a Route for a payment between the given payer and a payee.")]),t._v(" "),s("CodeSwitcher",{attrs:{languages:{rust:"Rust",kotlin:"Kotlin",swift:"Swift"}},scopedSlots:t._u([{key:"rust",fn:function(){return[s("div",{staticClass:"language-rust extra-class"},[s("pre",{pre:!0,attrs:{class:"language-rust"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" router "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("DefaultRouter")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("new")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n network_graph"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("clone")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n logger"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("clone")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n keys_manager"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("get_secure_random_bytes")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n scorer"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("clone")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("ProbabilisticScoringFeeParameters")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("default")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n\n")])])])]},proxy:!0},{key:"kotlin",fn:function(){return[s("div",{staticClass:"language-kotlin extra-class"},[s("pre",{pre:!0,attrs:{class:"language-kotlin"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" networkGraph "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" NetworkGraph"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("of")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("Network"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("LDKNetwork_Regtest"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" logger"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n")])])])]},proxy:!0},{key:"swift",fn:function(){return[s("div",{staticClass:"language-Swift extra-class"},[s("pre",{pre:!0,attrs:{class:"language-swift"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" netGraph "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("NetworkGraph")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("network"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Regtest")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" logger"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" logger"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n")])])])]},proxy:!0}])}),t._v(" "),s("p",[s("strong",[t._v("Dependencies:")]),t._v(" "),s("code",[t._v("P2PGossipSync")]),t._v(", "),s("code",[t._v("Logger")]),t._v(", "),s("code",[t._v("KeysManager")]),t._v(", "),s("code",[t._v("Scorer")])]),t._v(" "),s("p",[s("strong",[t._v("References:")]),t._v(" "),s("a",{attrs:{href:"https://docs.rs/lightning/*/lightning/routing/router/trait.Router.html",target:"_blank",rel:"noopener noreferrer"}},[t._v("Rust "),s("code",[t._v("Router")]),t._v(" docs"),s("OutboundLink")],1),t._v(", "),s("a",{attrs:{href:"https://github.com/lightningdevkit/ldk-garbagecollected/blob/main/src/main/java/org/ldk/structs/Router.java",target:"_blank",rel:"noopener noreferrer"}},[t._v("Java/Kotlin "),s("code",[t._v("Router")]),t._v(" bindings"),s("OutboundLink")],1)]),t._v(" "),s("h3",{attrs:{id:"initialize-the-logger"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#initialize-the-logger"}},[t._v("#")]),t._v(" Initialize the "),s("code",[t._v("Logger")])]),t._v(" "),s("p",[s("strong",[t._v("What it's used for:")]),t._v(" LDK logging")]),t._v(" "),s("CodeSwitcher",{attrs:{languages:{rust:"Rust",kotlin:"Kotlin",swift:"Swift"}},scopedSlots:t._u([{key:"rust",fn:function(){return[s("div",{staticClass:"language-rust extra-class"},[s("pre",{pre:!0,attrs:{class:"language-rust"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("struct")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token type-definition class-name"}},[t._v("YourLogger")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("impl")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Logger")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("for")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("YourLogger")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("fn")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function-definition function"}},[t._v("log")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("self")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" record"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Record")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" raw_log "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" record"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("args"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("to_string")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" log "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token macro property"}},[t._v("format!")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"{} {:<5} [{}:{}] {}\\n"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("OffsetDateTime")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("now_utc")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("format")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"%F %T"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n record"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("level"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("to_string")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n record"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("module_path"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n record"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("line"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n raw_log\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// ")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" logger "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("YourLogger")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])])]},proxy:!0},{key:"kotlin",fn:function(){return[s("div",{staticClass:"language-kotlin extra-class"},[s("pre",{pre:!0,attrs:{class:"language-kotlin"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("object")]),t._v(" YourLogger "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" LoggerInterface "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("override")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("fun")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("log")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("record"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" Record"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// ")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" logger"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" Logger "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" Logger"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("new_impl")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("YourLogger"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n")])])])]},proxy:!0},{key:"swift",fn:function(){return[s("div",{staticClass:"language-Swift extra-class"},[s("pre",{pre:!0,attrs:{class:"language-swift"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("MyLogger")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Logger")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("override")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("func")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function-definition function"}},[t._v("log")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("record"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Bindings")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Record")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Print and/or write the log to a file")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" logger "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("MyLogger")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n\n")])])])]},proxy:!0}])}),t._v(" "),s("p",[s("strong",[t._v("Implementation notes:")]),t._v(" you'll likely want to write the logs to a file for debugging purposes.")]),t._v(" "),s("p",[s("strong",[t._v("Dependencies:")]),t._v(" "),s("em",[t._v("none")])]),t._v(" "),s("p",[s("strong",[t._v("References:")]),t._v(" "),s("a",{attrs:{href:"https://docs.rs/lightning/*/lightning/util/logger/trait.Logger.html",target:"_blank",rel:"noopener noreferrer"}},[t._v("Rust "),s("code",[t._v("Logger")]),t._v(" docs"),s("OutboundLink")],1),t._v(", "),s("a",{attrs:{href:"https://github.com/lightningdevkit/ldk-garbagecollected/blob/main/src/main/java/org/ldk/structs/Logger.java",target:"_blank",rel:"noopener noreferrer"}},[t._v("Java/Kotlin "),s("code",[t._v("Logger")]),t._v(" bindings"),s("OutboundLink")],1)]),t._v(" "),s("h3",{attrs:{id:"initialize-the-broadcasterinterface"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#initialize-the-broadcasterinterface"}},[t._v("#")]),t._v(" Initialize the "),s("code",[t._v("BroadcasterInterface")])]),t._v(" "),s("p",[s("strong",[t._v("What it's used for:")]),t._v(" broadcasting various transactions to the bitcoin network")]),t._v(" "),s("CodeSwitcher",{attrs:{languages:{rust:"Rust",kotlin:"Kotlin",swift:"Swift"}},scopedSlots:t._u([{key:"rust",fn:function(){return[s("div",{staticClass:"language-rust extra-class"},[s("pre",{pre:!0,attrs:{class:"language-rust"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("struct")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token type-definition class-name"}},[t._v("YourTxBroadcaster")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("impl")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("BroadcasterInterface")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("for")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("YourTxBroadcaster")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("fn")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function-definition function"}},[t._v("broadcast_transactions")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("self")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" txs"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Transaction")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// ")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" broadcaster "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("YourTxBroadcaster")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])])]},proxy:!0},{key:"kotlin",fn:function(){return[s("div",{staticClass:"language-kotlin extra-class"},[s("pre",{pre:!0,attrs:{class:"language-kotlin"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("object")]),t._v(" YourTxBroadcaster"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" BroadcasterInterface"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("BroadcasterInterfaceInterface")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("override")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("fun")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("broadcast_transactions")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("txs"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" Array"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("out")]),t._v(" ByteArray"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// ")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" txBroadcaster"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" BroadcasterInterface "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" BroadcasterInterface"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("new_impl")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("YourTxBroadcaster"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n\n")])])])]},proxy:!0},{key:"swift",fn:function(){return[s("div",{staticClass:"language-Swift extra-class"},[s("pre",{pre:!0,attrs:{class:"language-swift"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("YourTxBroacaster")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("BroadcasterInterface")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("override")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("func")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function-definition function"}},[t._v("broadcastTransactions")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("txs"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("UInt8")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Insert code to broadcast a list of transactions")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" broadcaster "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("YourTxBroacaster")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n")])])])]},proxy:!0}])}),t._v(" "),s("p",[s("strong",[t._v("Dependencies:")]),t._v(" "),s("em",[t._v("none")])]),t._v(" "),s("p",[s("strong",[t._v("References:")]),t._v(" "),s("a",{attrs:{href:"https://docs.rs/lightning/*/lightning/chain/chaininterface/trait.BroadcasterInterface.html",target:"_blank",rel:"noopener noreferrer"}},[t._v("Rust "),s("code",[t._v("BroadcasterInterface")]),t._v(" docs"),s("OutboundLink")],1),t._v(", "),s("a",{attrs:{href:"https://github.com/lightningdevkit/ldk-garbagecollected/blob/main/src/main/java/org/ldk/structs/BroadcasterInterface.java",target:"_blank",rel:"noopener noreferrer"}},[t._v("Java/Kotlin "),s("code",[t._v("BroadcasterInterface")]),t._v(" bindings"),s("OutboundLink")],1)]),t._v(" "),s("h3",{attrs:{id:"initialize-persist"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#initialize-persist"}},[t._v("#")]),t._v(" Initialize "),s("code",[t._v("Persist")])]),t._v(" "),s("p",[s("strong",[t._v("What it's used for:")]),t._v(" persisting "),s("code",[t._v("ChannelMonitor")]),t._v("s, which contain crucial channel data, in a timely manner")]),t._v(" "),s("CodeSwitcher",{attrs:{languages:{rust:"Rust",kotlin:"Kotlin",swift:"Swift"}},scopedSlots:t._u([{key:"rust",fn:function(){return[s("div",{staticClass:"language-rust extra-class"},[s("pre",{pre:!0,attrs:{class:"language-rust"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("struct")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token type-definition class-name"}},[t._v("YourPersister")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("impl")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("ChannelSigner")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Sign")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Persist")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("for")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("YourPersister")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("fn")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function-definition function"}},[t._v("persist_new_channel")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("self")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" id"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("OutPoint")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" data"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("ChannelMonitor")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("ChannelSigner")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("->")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Result")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("ChannelMonitorUpdateErr")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// ")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Note that monitor.encode() will get you the ChannelMonitor as a")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Vec.")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("fn")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function-definition function"}},[t._v("update_persisted_channel")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("self")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n id"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("OutPoint")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n update"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("ChannelMonitorUpdate")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n data"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("ChannelMonitor")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("ChannelSigner")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("->")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Result")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("ChannelMonitorUpdateErr")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// ")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" persister "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("YourPersister")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])])]},proxy:!0},{key:"kotlin",fn:function(){return[s("div",{staticClass:"language-kotlin extra-class"},[s("pre",{pre:!0,attrs:{class:"language-kotlin"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("object")]),t._v(" YourPersister"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" Persist"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("PersistInterface")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("override")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("fun")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("persist_new_channel")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n id"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" OutPoint"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("data")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" ChannelMonitor"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" updateId"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" MonitorUpdateId"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" Result_NoneChannelMonitorUpdateErrZ"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// ")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("override")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("fun")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("update_persisted_channel")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n id"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" OutPoint"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" update"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" ChannelMonitorUpdate"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("data")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" ChannelMonitor"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n updateId"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" MonitorUpdateId\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" Result_NoneChannelMonitorUpdateErrZ"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// ")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" persister"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" Persist "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" Persist"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("new_impl")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("YourPersister"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n")])])])]},proxy:!0},{key:"swift",fn:function(){return[s("div",{staticClass:"language-Swift extra-class"},[s("pre",{pre:!0,attrs:{class:"language-swift"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("MyPersister")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Persist")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("override")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("func")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function-definition function"}},[t._v("persistNewChannel")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("channelId"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("OutPoint")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" data"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("ChannelMonitor")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" updateId"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("MonitorUpdateId")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Bindings")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("ChannelMonitorUpdateStatus")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Insert the code to persist the ChannelMonitor to disk")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("override")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("func")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function-definition function"}},[t._v("updatePersistedChannel")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("channelId"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("OutPoint")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" update"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("ChannelMonitorUpdate")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" data"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("ChannelMonitor")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" updateId"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("MonitorUpdateId")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("ChannelMonitorUpdateStatus")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Insert the code to persist either ChannelMonitor or ChannelMonitorUpdate to disk")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" persister "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("MyPersister")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n")])])])]},proxy:!0}])}),t._v(" "),s("CodeSwitcher",{attrs:{languages:{rust:"Using LDK Sample Filesystem Persistence Crate in Rust"}},scopedSlots:t._u([{key:"rust",fn:function(){return[s("div",{staticClass:"language-rust extra-class"},[s("pre",{pre:!0,attrs:{class:"language-rust"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("use")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("lightning_persister"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("FilesystemPersister")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// import LDK sample persist crate")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" persister "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("FilesystemPersister")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("new")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("ldk_data_dir_path"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])])]},proxy:!0}])}),t._v(" "),s("p",[s("strong",[t._v("Implementation notes:")])]),t._v(" "),s("ul",[s("li",[s("code",[t._v("ChannelMonitor")]),t._v("s are objects which are capable of\nresponding to on-chain events for a given channel. Thus, you will have one\n"),s("code",[t._v("ChannelMonitor")]),t._v(" per channel. They are persisted in real-time and the "),s("code",[t._v("Persist")]),t._v("\nmethods will block progress on sending or receiving payments until they return.\nYou must ensure that "),s("code",[t._v("ChannelMonitor")]),t._v("s are durably persisted to disk before\nreturning or you may lose funds.")]),t._v(" "),s("li",[t._v("If you implement a custom persister, it's important to read the trait docs (linked in References) to make sure you satisfy the API requirements, particularly for "),s("code",[t._v("update_persisted_channel")])])]),t._v(" "),s("p",[s("strong",[t._v("Dependencies:")]),t._v(" "),s("em",[t._v("none")])]),t._v(" "),s("p",[s("strong",[t._v("References:")]),t._v(" "),s("a",{attrs:{href:"https://docs.rs/lightning/*/lightning/chain/chainmonitor/trait.Persist.html",target:"_blank",rel:"noopener noreferrer"}},[t._v("Rust "),s("code",[t._v("Persister")]),t._v(" docs"),s("OutboundLink")],1),t._v(", "),s("a",{attrs:{href:"https://github.com/lightningdevkit/ldk-garbagecollected/blob/main/src/main/java/org/ldk/structs/Persist.java",target:"_blank",rel:"noopener noreferrer"}},[t._v("Java/Kotlin "),s("code",[t._v("Persister")]),t._v(" bindings"),s("OutboundLink")],1)]),t._v(" "),s("h3",{attrs:{id:"start-background-processing"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#start-background-processing"}},[t._v("#")]),t._v(" Start Background Processing")]),t._v(" "),s("p",[s("strong",[t._v("What it's used for:")]),t._v(" running tasks periodically in the background to keep LDK operational.")]),t._v(" "),s("CodeSwitcher",{attrs:{languages:{rust:"Rust"}},scopedSlots:t._u([{key:"rust",fn:function(){return[s("div",{staticClass:"language-rust extra-class"},[s("pre",{pre:!0,attrs:{class:"language-rust"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" background_processor "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("BackgroundProcessor")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("start")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n persister"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Arc")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("clone")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v("invoice_payer"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Arc")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("clone")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v("chain_monitor"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Arc")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("clone")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v("channel_manager"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Arc")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("clone")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v("net_graph_msg_handler"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Arc")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("clone")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v("peer_manager"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Arc")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("clone")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v("logger"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])])]},proxy:!0}])}),t._v(" "),s("p",[s("strong",[t._v("Dependencies:")]),t._v(" "),s("code",[t._v("ChannelManager")]),t._v(", "),s("code",[t._v("ChainMonitor")]),t._v(", "),s("code",[t._v("PeerManager")]),t._v(", "),s("code",[t._v("Logger")])]),t._v(" "),s("p",[s("strong",[t._v("References:")]),t._v(" "),s("a",{attrs:{href:"https://docs.rs/lightning-background-processor/*/lightning_background_processor/struct.BackgroundProcessor.html#method.start",target:"_blank",rel:"noopener noreferrer"}},[t._v("Rust "),s("code",[t._v("BackgroundProcessor::Start")]),t._v(" docs"),s("OutboundLink")],1)]),t._v(" "),s("h3",{attrs:{id:"regularly-broadcast-node-announcement"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#regularly-broadcast-node-announcement"}},[t._v("#")]),t._v(" Regularly Broadcast Node Announcement")]),t._v(" "),s("p",[s("strong",[t._v("What it's used for:")]),t._v(" if you have 1 or more public channels, you may need to announce your node and its channels occasionally. LDK will automatically announce channels when they are created, but there are no guarantees you have connected peers at that time or that your peers will propagate such announcements. The broader node-announcement message is not automatically broadcast.")]),t._v(" "),s("CodeSwitcher",{attrs:{languages:{rust:"Rust"}},scopedSlots:t._u([{key:"rust",fn:function(){return[s("div",{staticClass:"language-rust extra-class"},[s("pre",{pre:!0,attrs:{class:"language-rust"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("mut")]),t._v(" interval "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("tokio"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),t._v("time"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("interval")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Duration")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("from_secs")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("60")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("loop")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n\tinterval"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("tick")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\tchannel_manager"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("broadcast_node_announcement")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n\t\t"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("3")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// insert your node's RGB color")]),t._v("\n\t\tnode_alias"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n\t\t"),s("span",{pre:!0,attrs:{class:"token macro property"}},[t._v("vec!")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("ldk_announced_listen_addr"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n\t"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])])]},proxy:!0}])}),t._v(" "),s("p",[s("strong",[t._v("Dependencies:")]),t._v(" "),s("code",[t._v("Peer Manager")])]),t._v(" "),s("p",[s("strong",[t._v("References:")]),t._v(" "),s("a",{attrs:{href:"https://docs.rs/lightning/*/lightning/ln/peer_handler/struct.PeerManager.html#method.broadcast_node_announcement",target:"_blank",rel:"noopener noreferrer"}},[s("code",[t._v("PeerManager::broadcast_node_announcement")]),t._v(" docs"),s("OutboundLink")],1)]),t._v(" "),s("h3",{attrs:{id:"optional-initialize-the-transaction-filter"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#optional-initialize-the-transaction-filter"}},[t._v("#")]),t._v(" Optional: Initialize the Transaction "),s("code",[t._v("Filter")])]),t._v(" "),s("p",[s("strong",[t._v("You must follow this step if:")]),t._v(" you are "),s("em",[t._v("not")]),t._v(" providing full blocks to LDK,\ni.e. if you're using BIP 157/158 or Electrum as your chain backend")]),t._v(" "),s("p",[s("strong",[t._v("What it's used for:")]),t._v(" if you are not providing full blocks, LDK uses this\nobject to tell you what transactions and outputs to watch for on-chain.")]),t._v(" "),s("CodeSwitcher",{attrs:{languages:{rust:"Rust",kotlin:"Kotlin",swift:"Swift"}},scopedSlots:t._u([{key:"rust",fn:function(){return[s("div",{staticClass:"language-rust extra-class"},[s("pre",{pre:!0,attrs:{class:"language-rust"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("struct")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token type-definition class-name"}},[t._v("YourTxFilter")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("impl")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Filter")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("for")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("YourTxFilter")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("fn")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function-definition function"}},[t._v("register_tx")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("self")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" txid"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Txid")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" script_pubkey"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Script")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// ")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("fn")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function-definition function"}},[t._v("register_output")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("self")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" output"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("WatchedOutput")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("->")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Option")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("usize")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Transaction")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// ")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" filter "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("YourTxFilter")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])])]},proxy:!0},{key:"kotlin",fn:function(){return[s("div",{staticClass:"language-java extra-class"},[s("pre",{pre:!0,attrs:{class:"language-java"}},[s("code",[t._v("object "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("YourTxFilter")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Filter"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("FilterInterface")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n override fun "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("register_tx")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("txid"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("ByteArray")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" script_pubkey"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("ByteArray")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// ")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n override fun "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("register_output")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("output"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("WatchedOutput")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// ")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\nval txFilter"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Filter")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Filter")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("new_impl")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("YourTxFilter")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n")])])])]},proxy:!0},{key:"swift",fn:function(){return[s("div",{staticClass:"language-Swift extra-class"},[s("pre",{pre:!0,attrs:{class:"language-swift"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("MyFilter")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Filter")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("override")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("func")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function-definition function"}},[t._v("registerTx")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("txid"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("UInt8")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" scriptPubkey"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("UInt8")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Insert code to watch this transaction")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("override")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("func")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function-definition function"}},[t._v("registerOutput")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("output"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Bindings")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("WatchedOutput")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Insert code to watch for any transaction that spend this output")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" filter "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("MyFilter")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n")])])])]},proxy:!0}])}),t._v(" "),s("p",[s("strong",[t._v("Implementation notes:")]),t._v(" see the "),s("RouterLink",{attrs:{to:"/blockchain_data/introduction/"}},[t._v("Blockchain Data")]),t._v(" guide for more info")],1),t._v(" "),s("p",[s("strong",[t._v("Dependencies:")]),t._v(" "),s("em",[t._v("none")])]),t._v(" "),s("p",[s("strong",[t._v("References:")]),t._v(" "),s("a",{attrs:{href:"https://docs.rs/lightning/*/lightning/chain/trait.Filter.html",target:"_blank",rel:"noopener noreferrer"}},[t._v("Rust "),s("code",[t._v("Filter")]),t._v(" docs"),s("OutboundLink")],1),t._v(", "),s("a",{attrs:{href:"https://github.com/lightningdevkit/ldk-garbagecollected/blob/main/src/main/java/org/ldk/structs/Filter.java",target:"_blank",rel:"noopener noreferrer"}},[t._v("Java/Kotlin "),s("code",[t._v("Filter")]),t._v(" bindings"),s("OutboundLink")],1)]),t._v(" "),s("h3",{attrs:{id:"initialize-the-chainmonitor"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#initialize-the-chainmonitor"}},[t._v("#")]),t._v(" Initialize the "),s("code",[t._v("ChainMonitor")])]),t._v(" "),s("p",[s("strong",[t._v("What it's used for:")]),t._v(" tracking one or more "),s("code",[t._v("ChannelMonitor")]),t._v("s and using them to monitor the chain for lighting transactions that are relevant to our node, and broadcasting transactions if need be.")]),t._v(" "),s("CodeSwitcher",{attrs:{languages:{rust:"Rust",kotlin:"Kotlin",swift:"Swift"}},scopedSlots:t._u([{key:"rust",fn:function(){return[s("div",{staticClass:"language-rust extra-class"},[s("pre",{pre:!0,attrs:{class:"language-rust"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" filter"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Option")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Box")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("dyn")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Filter")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// leave this as None or insert the Filter trait object")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" chain_monitor "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("ChainMonitor")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("new")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("filter"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v("broadcaster"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v("logger"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v("fee_estimator"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v("persister"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])])]},proxy:!0},{key:"kotlin",fn:function(){return[s("div",{staticClass:"language-java extra-class"},[s("pre",{pre:!0,attrs:{class:"language-java"}},[s("code",[t._v("val filter "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Filter")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// leave this as `null` or insert the Filter object.")]),t._v("\n\nval chainMonitor "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("ChainMonitor")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("of")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("filter"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" txBroadcaster"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" logger"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" feeEstimator"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" persister"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n")])])])]},proxy:!0},{key:"swift",fn:function(){return[s("div",{staticClass:"language-Swift extra-class"},[s("pre",{pre:!0,attrs:{class:"language-swift"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" filter"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Filter")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// leave this as `nil` or insert the Filter object.")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" chainMonitor "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("ChainMonitor")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n chainSource"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" filter"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n broadcaster"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" broadcaster"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n logger"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" logger"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n feeest"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" feeEstimator"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n persister"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" persister\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n")])])])]},proxy:!0}])}),t._v(" "),s("p",[s("strong",[t._v("Implementation notes:")]),t._v(" "),s("code",[t._v("Filter")]),t._v(" must be non-"),s("code",[t._v("None")]),t._v(" if you're using Electrum or BIP 157/158 as your chain backend")]),t._v(" "),s("p",[s("strong",[t._v("Dependencies:")]),t._v(" "),s("code",[t._v("FeeEstimator")]),t._v(", "),s("code",[t._v("Logger")]),t._v(", "),s("code",[t._v("BroadcasterInterface")]),t._v(", "),s("code",[t._v("Persist")])]),t._v(" "),s("p",[s("strong",[t._v("Optional dependency:")]),t._v(" "),s("code",[t._v("Filter")])]),t._v(" "),s("p",[s("strong",[t._v("References:")]),t._v(" "),s("a",{attrs:{href:"https://docs.rs/lightning/*/lightning/chain/chainmonitor/struct.ChainMonitor.html",target:"_blank",rel:"noopener noreferrer"}},[t._v("Rust "),s("code",[t._v("ChainMonitor")]),t._v(" docs"),s("OutboundLink")],1),t._v(", "),s("a",{attrs:{href:"https://github.com/lightningdevkit/ldk-garbagecollected/blob/main/src/main/java/org/ldk/structs/ChainMonitor.java",target:"_blank",rel:"noopener noreferrer"}},[t._v("Java/Kotlin "),s("code",[t._v("ChainMonitor")]),t._v(" bindings"),s("OutboundLink")],1)]),t._v(" "),s("h3",{attrs:{id:"initialize-the-keysmanager"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#initialize-the-keysmanager"}},[t._v("#")]),t._v(" Initialize the "),s("code",[t._v("KeysManager")])]),t._v(" "),s("p",[s("strong",[t._v("What it's used for:")]),t._v(" providing keys for signing Lightning transactions")]),t._v(" "),s("CodeSwitcher",{attrs:{languages:{rust:"Rust",kotlin:"Kotlin",swift:"Swift"}},scopedSlots:t._u([{key:"rust",fn:function(){return[s("div",{staticClass:"language-rust extra-class"},[s("pre",{pre:!0,attrs:{class:"language-rust"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" keys_seed_path "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token macro property"}},[t._v("format!")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"{}/keys_seed"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" ldk_data_dir"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("clone")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// If we're restarting and already have a key seed, read it from disk. Else,")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// create a new one.")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" keys_seed "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Ok")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("seed"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("fs"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("read")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("keys_seed_path"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("clone")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token macro property"}},[t._v("assert_eq!")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("seed"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("len")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("32")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("mut")]),t._v(" key "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("32")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n key"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("copy_from_slice")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v("seed"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n key\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("else")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("mut")]),t._v(" key "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("32")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("thread_rng")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("fill_bytes")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("mut")]),t._v(" key"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("match")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("File")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("create")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("keys_seed_path"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("clone")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Ok")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("mut")]),t._v(" f"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n f"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("write_all")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v("key"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("expect")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Failed to write node keys seed to disk"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n f"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("sync_all")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("expect")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Failed to sync node keys seed to disk"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Err")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("e"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token macro property"}},[t._v("println!")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"ERROR: Unable to create keys seed file {}: {}"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n keys_seed_path"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" e\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n key\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" cur "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("SystemTime")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("now")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("duration_since")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("SystemTime")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("UNIX_EPOCH")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("unwrap")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" keys_manager "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("KeysManager")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("new")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v("keys_seed"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" cur"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("as_secs")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" cur"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("subsec_nanos")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n")])])])]},proxy:!0},{key:"kotlin",fn:function(){return[s("div",{staticClass:"language-java extra-class"},[s("pre",{pre:!0,attrs:{class:"language-java"}},[s("code",[t._v("val keySeed "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("ByteArray")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("32")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// ")]),t._v("\nval keysManager "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("KeysManager")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("of")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n keySeed"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("System")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("currentTimeMillis")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("/")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1000")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("System")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("currentTimeMillis")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1000")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("toInt")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n")])])])]},proxy:!0},{key:"swift",fn:function(){return[s("div",{staticClass:"language-Swift extra-class"},[s("pre",{pre:!0,attrs:{class:"language-swift"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" seed "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Insert code to create seed with random bytes or if restarting, reload the seed from disk")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" timestampSeconds "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("UInt64")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("NSDate")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("timeIntervalSince1970"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" timestampNanos "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("UInt32")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("init")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("truncating"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("NSNumber")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("value"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" timestampSeconds "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1000")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1000")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" keysManager "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("KeysManager")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("seed"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" seed"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" startingTimeSecs"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" timestampSeconds"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" startingTimeNanos"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" timestampNanos"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n")])])])]},proxy:!0}])}),t._v(" "),s("p",[s("strong",[t._v("Implementation notes:")])]),t._v(" "),s("ul",[s("li",[t._v("See the "),s("RouterLink",{attrs:{to:"/key_management/"}},[t._v("Key Management")]),t._v(" guide for more info")],1),t._v(" "),s("li",[t._v("Note that you must write the "),s("code",[t._v("key_seed")]),t._v(" you give to the "),s("code",[t._v("KeysManager")]),t._v(" on\nstartup to disk, and keep using it to initialize the "),s("code",[t._v("KeysManager")]),t._v(" every time\nyou restart. This "),s("code",[t._v("key_seed")]),t._v(" is used to derive your node's secret key (which\ncorresponds to its node pubkey) and all other secret key material.")]),t._v(" "),s("li",[t._v("The current time is part of the "),s("code",[t._v("KeysManager")]),t._v("'s parameters because it is used to derive\nrandom numbers from the seed where required, to ensure all random\ngeneration is unique across restarts.")])]),t._v(" "),s("p",[s("strong",[t._v("Dependencies:")]),t._v(" random bytes")]),t._v(" "),s("p",[s("strong",[t._v("References:")]),t._v(" "),s("a",{attrs:{href:"https://docs.rs/lightning/*/lightning/sign/struct.KeysManager.html",target:"_blank",rel:"noopener noreferrer"}},[t._v("Rust "),s("code",[t._v("KeysManager")]),t._v(" docs"),s("OutboundLink")],1),t._v(", "),s("a",{attrs:{href:"https://github.com/lightningdevkit/ldk-garbagecollected/blob/main/src/main/java/org/ldk/structs/KeysManager.java",target:"_blank",rel:"noopener noreferrer"}},[t._v("Java/Kotlin "),s("code",[t._v("KeysManager")]),t._v(" bindings"),s("OutboundLink")],1)]),t._v(" "),s("h3",{attrs:{id:"read-channelmonitor-state-from-disk"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#read-channelmonitor-state-from-disk"}},[t._v("#")]),t._v(" Read "),s("code",[t._v("ChannelMonitor")]),t._v(" state from disk")]),t._v(" "),s("p",[s("strong",[t._v("What it's used for:")]),t._v(" if LDK is restarting and has at least 1 channel, its "),s("code",[t._v("ChannelMonitor")]),t._v("s will need to be (1) fed to the "),s("code",[t._v("ChannelManager")]),t._v(" and (2) synced to chain.")]),t._v(" "),s("CodeSwitcher",{attrs:{languages:{rust:"Rust",kotlin:"Kotlin",swift:"Swift"}},scopedSlots:t._u([{key:"rust",fn:function(){return[s("div",{staticClass:"language-rust extra-class"},[s("pre",{pre:!0,attrs:{class:"language-rust"}},[s("code",[s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Use LDK's sample persister crate provided method")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("mut")]),t._v(" channel_monitors "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v("\n persister"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("read_channelmonitors")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("keys_manager"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("clone")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("unwrap")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// If you are using Electrum or BIP 157/158, you must call load_outputs_to_watch")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// on each ChannelMonitor to prepare for chain synchronization.")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("for")]),t._v(" chan_mon "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("in")]),t._v(" channel_monitors"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("iter")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n chan_mon"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("load_outputs_to_watch")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v("filter"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])])]},proxy:!0},{key:"kotlin",fn:function(){return[s("div",{staticClass:"language-java extra-class"},[s("pre",{pre:!0,attrs:{class:"language-java"}},[s("code",[s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Initialize the hashmap where we'll store the `ChannelMonitor`s read from disk.")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// This hashmap will later be given to the `ChannelManager` on initialization.")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("var")]),t._v(" channelMonitors "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" arrayOf"),s("span",{pre:!0,attrs:{class:"token generics"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("ByteArray")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\nval channelMonitorList "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("ArrayList")]),s("span",{pre:!0,attrs:{class:"token generics"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("ByteArray")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\nchannelMonitorFiles"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("iterator")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("forEach "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n val channelMonitorBytes "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" it"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("hexStringToByteArray")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n channelMonitorList"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("add")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("channelMonitorBytes"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\nchannelMonitors "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" channelMonitorList"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("toTypedArray")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])])]},proxy:!0},{key:"swift",fn:function(){return[s("div",{staticClass:"language-Swift extra-class"},[s("pre",{pre:!0,attrs:{class:"language-swift"}},[s("code",[s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Initialize the array where we'll store the `ChannelMonitor`s read from disk.")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// This array will later be given to the `ChannelManagerConstructor` on initialization.")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("var")]),t._v(" serializedChannelMonitors"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("UInt8")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" allChannels "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Insert code to get a list of persisted channels")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("for")]),t._v(" channel "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("in")]),t._v(" allChannels "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" channelData "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("try")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Data")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("contentsOf"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" channel"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" channelBytes "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("UInt8")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("channelData"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n serializedChannelMonitors"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("append")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("channelBytes"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])])]},proxy:!0}])}),t._v(" "),s("p",[s("strong",[t._v("Dependencies:")]),t._v(" "),s("code",[t._v("KeysManager")])]),t._v(" "),s("p",[s("strong",[t._v("References:")]),t._v(" "),s("a",{attrs:{href:"https://docs.rs/lightning/*/lightning/chain/channelmonitor/struct.ChannelMonitor.html#method.load_outputs_to_watch",target:"_blank",rel:"noopener noreferrer"}},[t._v("Rust "),s("code",[t._v("load_outputs_to_watch")]),t._v(" docs"),s("OutboundLink")],1)]),t._v(" "),s("h3",{attrs:{id:"initialize-the-channelmanager"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#initialize-the-channelmanager"}},[t._v("#")]),t._v(" Initialize the "),s("code",[t._v("ChannelManager")])]),t._v(" "),s("p",[s("strong",[t._v("What it's used for:")]),t._v(" managing channel state")]),t._v(" "),s("CodeSwitcher",{attrs:{languages:{rust:"Rust",kotlin:"Kotlin",swift:"Swift"}},scopedSlots:t._u([{key:"rust",fn:function(){return[s("div",{staticClass:"language-rust extra-class"},[s("pre",{pre:!0,attrs:{class:"language-rust"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" user_config "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("UserConfig")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("default")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("/* RESTARTING */")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("channel_manager_blockhash"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("mut")]),t._v(" channel_manager"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" channel_manager_file "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("fs"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("File")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("open")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token macro property"}},[t._v("format!")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"{}/manager"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" ldk_data_dir"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("clone")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("unwrap")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Use the `ChannelMonitors` we read from disk.")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("mut")]),t._v(" channel_monitor_mut_references "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Vec")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("new")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("for")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("_"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" channel_monitor"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("in")]),t._v(" channel_monitors"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("iter_mut")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n channel_monitor_mut_references"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("push")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("channel_monitor"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" read_args "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("ChannelManagerReadArgs")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("new")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v("keys_manager"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v("fee_estimator"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v("chain_monitor"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v("broadcaster"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v("logger"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n user_config"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n channel_monitor_mut_references"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("BlockHash")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("ChannelManager")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("read")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("mut")]),t._v(" channel_manager_file"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" read_args"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("unwrap")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("/* FRESH CHANNELMANAGER */")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("channel_manager_blockhash"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("mut")]),t._v(" channel_manager"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" best_blockhash "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// insert the best blockhash you know of")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" best_chain_height "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// insert the height corresponding to best_blockhash")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" chain_params "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("ChainParameters")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n network"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Network")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Testnet")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// substitute this with your network")]),t._v("\n best_block"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("BestBlock")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("new")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("best_blockhash"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" best_chain_height"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" fresh_channel_manager "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("ChannelManager")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("new")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v("fee_estimator"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v("chain_monitor"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v("broadcaster"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v("router"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v("logger"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v("entropy_source"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v("node_signer"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v("signer_provider"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n user_config"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n chain_params"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n current_timestamp\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("best_blockhash"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" fresh_channel_manager"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n")])])])]},proxy:!0},{key:"kotlin",fn:function(){return[s("div",{staticClass:"language-kotlin extra-class"},[s("pre",{pre:!0,attrs:{class:"language-kotlin"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("serializedChannelManager "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("!=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("null")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&&")]),t._v(" serializedChannelManager"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("isNotEmpty")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Loading from disk (restarting)")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" channelManagerConstructor "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("ChannelManagerConstructor")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n serializedChannelManager"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n serializedChannelMonitors"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n userConfig"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n keysManager"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("!!")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("inner"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("as_EntropySource")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n keysManager"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("!!")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("inner"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("as_NodeSigner")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n SignerProvider"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("new_impl")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("keysManager"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("!!")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("signerProvider"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n feeEstimator"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n chainMonitor"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n txFilter"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n networkGraph"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("!!")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("write")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n ProbabilisticScoringDecayParameters"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("with_default")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n ProbabilisticScoringFeeParameters"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("with_default")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n scorer"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("!!")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("write")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("null")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n txBroadcaster"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n logger\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("else")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Fresh start")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" channelManagerConstructor "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("ChannelManagerConstructor")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n Network"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("LDKNetwork_Regtest"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n userConfig"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n latestBlockHash"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("toByteArray")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n latestBlockHeight"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n keysManager"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("!!")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("inner"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("as_EntropySource")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n keysManager"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("!!")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("inner"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("as_NodeSigner")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n SignerProvider"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("new_impl")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("keysManager"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("!!")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("signerProvider"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n feeEstimator"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n chainMonitor"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n networkGraph"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n ProbabilisticScoringDecayParameters"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("with_default")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n ProbabilisticScoringFeeParameters"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("with_default")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("null")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n txBroadcaster"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n logger\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n")])])])]},proxy:!0},{key:"swift",fn:function(){return[s("div",{staticClass:"language-Swift extra-class"},[s("pre",{pre:!0,attrs:{class:"language-swift"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" serializedChannelManager "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("!=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token nil constant"}},[t._v("nil")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&&")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("!")]),t._v("serializedChannelManager"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("!")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("isEmpty "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("do")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" channelManagerConstructor "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("try")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("ChannelManagerConstructor")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n channelManagerSerialized"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" serializedChannelManager"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("!")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n channelMonitorsSerialized"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" serializedChannelMonitors"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n networkGraph"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("NetworkGraphArgument")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("instance")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("netGraph"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n filter"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" filter"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n params"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" channelManagerConstructionParameters\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("catch")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" channelManagerConstructor "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("ChannelManagerConstructor")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n network"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" network"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n currentBlockchainTipHash"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" latestBlockHash"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("!")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n currentBlockchainTipHeight"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" latestBlockHeight"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("!")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n netGraph"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" netGraph"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n params"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" channelManagerConstructionParameters\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("else")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" channelManagerConstructor "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("ChannelManagerConstructor")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n network"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" network"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n currentBlockchainTipHash"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" latestBlockHash"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("!")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n currentBlockchainTipHeight"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" latestBlockHeight"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("!")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n netGraph"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" netGraph"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n params"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" channelManagerConstructionParameters\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n")])])])]},proxy:!0}])}),t._v(" "),s("p",[s("strong",[t._v("Implementation notes:")]),t._v(" No methods should be called on "),s("code",[t._v("ChannelManager")]),t._v(" until\n"),s("em",[t._v("after")]),t._v(" the "),s("code",[t._v("ChannelMonitor")]),t._v("s and "),s("code",[t._v("ChannelManager")]),t._v(" are synced to the chain tip (next step).")]),t._v(" "),s("p",[s("strong",[t._v("Dependencies:")]),t._v(" "),s("code",[t._v("KeysManager")]),t._v(", "),s("code",[t._v("FeeEstimator")]),t._v(", "),s("code",[t._v("ChainMonitor")]),t._v(", "),s("code",[t._v("BroadcasterInterface")]),t._v(", "),s("code",[t._v("Logger")])]),t._v(" "),s("p",[s("strong",[t._v("References:")]),t._v(" "),s("a",{attrs:{href:"https://docs.rs/lightning/*/lightning/ln/channelmanager/struct.ChannelManager.html",target:"_blank",rel:"noopener noreferrer"}},[t._v("Rust "),s("code",[t._v("ChannelManager")]),t._v(" docs"),s("OutboundLink")],1),t._v(", "),s("a",{attrs:{href:"https://github.com/lightningdevkit/ldk-garbagecollected/blob/main/src/main/java/org/ldk/structs/ChannelManager.java",target:"_blank",rel:"noopener noreferrer"}},[t._v("Java/Kotlin "),s("code",[t._v("ChannelManager")]),t._v(" bindings"),s("OutboundLink")],1)]),t._v(" "),s("h3",{attrs:{id:"sync-channelmonitors-and-channelmanager-to-chain-tip"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#sync-channelmonitors-and-channelmanager-to-chain-tip"}},[t._v("#")]),t._v(" Sync "),s("code",[t._v("ChannelMonitor")]),t._v("s and "),s("code",[t._v("ChannelManager")]),t._v(" to chain tip")]),t._v(" "),s("p",[s("strong",[t._v("What it's used for:")]),t._v(" this step is only necessary if you're restarting and have open channels. This step ensures that LDK channel state is up-to-date with the bitcoin blockchain")]),t._v(" "),s("p",[s("strong",[t._v("Example:")])]),t._v(" "),s("CodeSwitcher",{attrs:{languages:{rust:"Rust",kotlin:"Kotlin",swift:"Swift"}},scopedSlots:t._u([{key:"rust",fn:function(){return[s("div",{staticClass:"language-rust extra-class"},[s("pre",{pre:!0,attrs:{class:"language-rust"}},[s("code",[s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Full Blocks or BIP 157/158")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("use")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("lightning_block_sync"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),t._v("init"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("use")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("lightning_block_sync"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),t._v("poll"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("use")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("lightning_block_sync"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("UnboundedCache")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("impl")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("lightning_block_sync"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("BlockSource")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("for")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("YourChainBackend")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("fn")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function-definition function"}},[t._v("get_header")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token lifetime-annotation symbol"}},[t._v("'a")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),s("span",{pre:!0,attrs:{class:"token lifetime-annotation symbol"}},[t._v("'a")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("mut")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("self")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" header_hash"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),s("span",{pre:!0,attrs:{class:"token lifetime-annotation symbol"}},[t._v("'a")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("BlockHash")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" height_hint"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Option")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("u32")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("->")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("AsyncBlockSourceResult")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token lifetime-annotation symbol"}},[t._v("'a")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("BlockHeaderData")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// ")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("fn")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function-definition function"}},[t._v("get_block")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token lifetime-annotation symbol"}},[t._v("'a")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),s("span",{pre:!0,attrs:{class:"token lifetime-annotation symbol"}},[t._v("'a")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("mut")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("self")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" header_hash"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),s("span",{pre:!0,attrs:{class:"token lifetime-annotation symbol"}},[t._v("'a")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("BlockHash")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("->")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("AsyncBlockSourceResult")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token lifetime-annotation symbol"}},[t._v("'a")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Block")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// ")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("fn")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function-definition function"}},[t._v("get_best_block")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token lifetime-annotation symbol"}},[t._v("'a")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),s("span",{pre:!0,attrs:{class:"token lifetime-annotation symbol"}},[t._v("'a")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("mut")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("self")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("->")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("AsyncBlockSourceResult")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("BlockHash")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Option")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("u32")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// ")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" block_source "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("YourChainBackend")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("new")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("mut")]),t._v(" chain_listener_channel_monitors "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Vec")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("new")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("mut")]),t._v(" cache "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("UnboundedCache")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("new")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("mut")]),t._v(" chain_tip"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Option")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("poll"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("ValidatedBlockHeader")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("None")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("mut")]),t._v(" chain_listeners "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token macro property"}},[t._v("vec!")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n channel_manager_blockhash"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("mut")]),t._v(" channel_manager "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("as")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("mut")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("dyn")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("chain"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Listen")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("for")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("blockhash"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" channel_monitor"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("in")]),t._v(" channel_monitors"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("drain")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("..")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" outpoint "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" channel_monitor"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("get_funding_txo")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n chain_listener_channel_monitors"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("push")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n blockhash"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n channel_monitor"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v("broadcaster"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v("fee_estimator"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v("logger"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n outpoint"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("for")]),t._v(" monitor_listener_info "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("in")]),t._v(" chain_listener_channel_monitors"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("iter_mut")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n chain_listeners"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("push")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n monitor_listener_info"),s("span",{pre:!0,attrs:{class:"token number"}},[t._v(".0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("mut")]),t._v(" monitor_listener_info"),s("span",{pre:!0,attrs:{class:"token number"}},[t._v(".1")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("as")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("mut")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("dyn")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("chain"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Listen")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Save the chain tip to be used in future steps")]),t._v("\nchain_tip "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Some")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("init"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("synchronize_listeners")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("mut")]),t._v(" block_source"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Network")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Testnet")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("mut")]),t._v(" cache"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n chain_listeners"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("unwrap")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n\n")])])])]},proxy:!0},{key:"kotlin",fn:function(){return[s("div",{staticClass:"language-java extra-class"},[s("pre",{pre:!0,attrs:{class:"language-java"}},[s("code",[s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Electrum/Esplora")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Retrieve transaction IDs to check the chain for un-confirmation.")]),t._v("\nval relevantTxIdsFromChannelManager"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Array")]),s("span",{pre:!0,attrs:{class:"token generics"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("ByteArray")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" channelManager "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("as_Confirm")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("get_relevant_txids")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\nval relevantTxIdsFromChannelManager"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Array")]),s("span",{pre:!0,attrs:{class:"token generics"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("ByteArray")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" chainMonitor"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("as_Confirm")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("get_relevant_txids")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\nval relevantTxIds "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" relevantTxIdsFromChannelManager "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+")]),t._v(" relevantTxIdsFromChainMonitor\n\nval unconfirmedTxs"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Array")]),s("span",{pre:!0,attrs:{class:"token generics"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("ByteArray")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// ")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("for")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("txid in unconfirmedTxs"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n channelManager "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("transaction_unconfirmed")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("txid"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n chainMonitor"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("transaction_unconfirmed")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("txid"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Retrieve transactions and outputs that were registered through the `Filter`")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// interface.")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// If any of these txs/outputs were confirmed on-chain, then:")]),t._v("\nval header"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Array")]),s("span",{pre:!0,attrs:{class:"token generics"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("ByteArray")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// insert block header from the block with confirmed tx/output")]),t._v("\nval height"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Int")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// insert block height of `header`")]),t._v("\nval txIndex"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Long")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// insert tx index in block")]),t._v("\nval serializedTx"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Array")]),s("span",{pre:!0,attrs:{class:"token generics"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("ByteArray")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// insert tx hex as byte array")]),t._v("\nval tx"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("TwoTuple_usizeTransactionZ")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("TwoTuple_usizeTransactionZ")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("of")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("txIndex"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" serializedTx"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Marshall all TwoTuples you built right above into an array")]),t._v("\nval txList "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" arrayOf"),s("span",{pre:!0,attrs:{class:"token generics"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("TwoTuple_usizeTransactionZ")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("TwoTuple_usizeTransactionZ")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("of")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("tx"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\nchannelManager"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("transactions_confirmed")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("header"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" height"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" txList"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\nchainMonitor"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("transactions_confirmed")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("header"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" height"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" txList"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\nval bestHeader"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Array")]),s("span",{pre:!0,attrs:{class:"token generics"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("ByteArray")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// ")]),t._v("\nval bestHeight"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Int")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// ")]),t._v("\nchannelManager"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("update_best_block")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("bestHeader"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" bestHeight"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\nchainMonitor"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("update_best_block")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("bestHeader"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" bestHeight"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Finally, tell LDK that chain sync is complete. This will also spawn several")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// background threads to handle networking and event processing.")]),t._v("\nchannelManagerConstructor"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("chain_sync_completed")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("customEventHandler"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])])]},proxy:!0},{key:"swift",fn:function(){return[s("div",{staticClass:"language-Swift extra-class"},[s("pre",{pre:!0,attrs:{class:"language-swift"}},[s("code",[s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Electrum/Esplora")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Retrieve transaction IDs to check the chain for un-confirmation.")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" relevantTxIds1 "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" channelManager"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("asConfirm")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("getRelevantTxids")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("??")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" relevantTxIds2 "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" chainMonitor"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("asConfirm")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("getRelevantTxids")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("??")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("var")]),t._v(" relevantTxIds"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("UInt8")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("UInt8")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("for")]),t._v(" tx "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("in")]),t._v(" relevantTxIds1 "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n relevantTxIds"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("append")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("tx"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("for")]),t._v(" tx "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("in")]),t._v(" relevantTxIds2 "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n relevantTxIds"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("append")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("tx"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("var")]),t._v(" unconfirmedTx"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("UInt8")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Insert code to find out from your chain source")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// if any of relevantTxIds have been reorged out")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// of the chain")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("for")]),t._v(" txid "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("in")]),t._v(" unconfirmedTx "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n channelManager"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("asConfirm")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("transactionUnconfirmed")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("txid"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" txid"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n chainMonitor"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("asConfirm")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("transactionUnconfirmed")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("txid"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" txid"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Retrieve transactions and outputs that were registered through the `Filter` interface.")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("var")]),t._v(" confirmedTx"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("UInt8")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Insert code to find out from your chain source")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// if any of the `Filter` txs/outputs were confirmed")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// on-chain")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("for")]),t._v(" txid "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("in")]),t._v(" confirmedTx "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" header"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("UInt8")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Insert code to fetch header")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" height"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("UInt32")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Insert code to fetch height of the header")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" tx"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("UInt8")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Insert code to fetch tx")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" txIndex"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("UInt")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Insert code to fetch tx index")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("var")]),t._v(" twoTuple"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("UInt")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("UInt8")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v("\n twoTuple"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("append")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("UInt")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("UInt8")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("txIndex"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" tx"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n channelManager"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("asConfirm")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("transactionsConfirmed")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("header"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" header"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" txdata"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" twoTuple"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" height"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" height"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n chainMonitor"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("asConfirm")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("transactionsConfirmed")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("header"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" header"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" txdata"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" twoTuple"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" height"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" height"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" bestHeader "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Insert code to fetch best header")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" bestHeight "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Insert code to fetch best height")]),t._v("\n\nchannelManager"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("asConfirm")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("bestBlockUpdated")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("header"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" bestHeader"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" height"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" bestHeight"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\nchainMonitor"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("asConfirm")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("bestBlockUpdated")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("header"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" bestHeader"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" height"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" bestHeight"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Finally, tell LDK that chain sync is complete. This will also spawn several")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// background threads to handle networking and event processing.")]),t._v("\nchannelManagerConstructor"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("chainSyncCompleted")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("persister"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" channelManagerPersister"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n")])])])]},proxy:!0}])}),t._v(" "),s("p",[s("strong",[t._v("Implementation notes:")])]),t._v(" "),s("p",[t._v("There are 2 main options for synchronizing to chain on startup:")]),t._v(" "),s("p",[s("strong",[t._v("Full Blocks or BIP 157/158")])]),t._v(" "),s("p",[t._v("If you are connecting full blocks or using BIP 157/158, then it is recommended to use\nLDK's "),s("code",[t._v("lightning_block_sync")]),t._v(" crate as in the example above: the high-level steps that must be done for both "),s("code",[t._v("ChannelManager")]),t._v(" and each "),s("code",[t._v("ChannelMonitor")]),t._v(" are as follows:")]),t._v(" "),s("ol",[s("li",[t._v("Get the last blockhash that each object saw.\n"),s("ul",[s("li",[t._v("Receive the latest block hash when through "),s("a",{attrs:{href:"https://docs.rs/lightning/*/lightning/ln/channelmanager/struct.ChannelManagerReadArgs.html",target:"_blank",rel:"noopener noreferrer"}},[t._v("deserializtion"),s("OutboundLink")],1),t._v(" of the "),s("code",[t._v("ChannelManager")]),t._v(" via "),s("code",[t._v("read()")])]),t._v(" "),s("li",[t._v("Each "),s("code",[t._v("ChannelMonitor")]),t._v("'s is in "),s("code",[t._v("channel_manager.channel_monitors")]),t._v(", as the 2nd element in each tuple")])])]),t._v(" "),s("li",[t._v("For each object, if its latest known blockhash has been reorged out of the chain, then disconnect blocks using "),s("code",[t._v("channel_manager.as_Listen().block_disconnected(..)")]),t._v(" or "),s("code",[t._v("channel_monitor.block_disconnected(..)")]),t._v(" until you reach the last common ancestor with the main chain.")]),t._v(" "),s("li",[t._v("For each object, reconnect blocks starting from the common ancestor until it gets to your best known chain tip using "),s("code",[t._v("channel_manager.as_Listen().block_connected(..)")]),t._v(" and/or "),s("code",[t._v("channel_monitor.block_connected(..)")]),t._v(".")]),t._v(" "),s("li",[t._v("Call "),s("code",[t._v("channel_manager.chain_sync_completed(..)")]),t._v(" to complete the initial sync process.")])]),t._v(" "),s("p",[s("strong",[t._v("Electrum/Esplora")])]),t._v(" "),s("p",[t._v("Alternatively, you can use LDK's "),s("code",[t._v("lightning-transaction-sync")]),t._v(" crate. This provides utilities for syncing LDK via the transaction-based "),s("code",[t._v("Confirm")]),t._v(" interface.")]),t._v(" "),s("h3",{attrs:{id:"optional-initialize-p2pgossipsync-or-rapidgossipsync"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#optional-initialize-p2pgossipsync-or-rapidgossipsync"}},[t._v("#")]),t._v(" Optional: Initialize "),s("code",[t._v("P2PGossipSync or RapidGossipSync")])]),t._v(" "),s("p",[s("strong",[t._v("You must follow this step if:")]),t._v(" you need LDK to provide routes for sending payments (i.e. you are "),s("em",[t._v("not")]),t._v(" providing your own routes)")]),t._v(" "),s("p",[s("strong",[t._v("What it's used for:")]),t._v(" generating routes to send payments over")]),t._v(" "),s("CodeSwitcher",{attrs:{languages:{rust:"Rust",kotlin:"Kotlin",swift:"Swift"}},scopedSlots:t._u([{key:"rust",fn:function(){return[s("div",{staticClass:"language-rust extra-class"},[s("pre",{pre:!0,attrs:{class:"language-rust"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" genesis "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("genesis_block")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Network")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Testnet")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("header"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("block_hash")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" network_graph_path "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token macro property"}},[t._v("format!")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"{}/network_graph"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" ldk_data_dir"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("clone")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" network_graph "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Arc")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("new")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("disk"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("read_network")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Path")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("new")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v("network_graph_path"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" genesis"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" logger"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("clone")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" gossip_sync "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Arc")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("new")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("P2PGossipSync")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("new")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Arc")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("clone")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v("network_graph"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("None")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Arc")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("dyn")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("chain"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Access")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Send")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Sync")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">>")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n logger"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("clone")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])])]},proxy:!0},{key:"kotlin",fn:function(){return[s("div",{staticClass:"language-java extra-class"},[s("pre",{pre:!0,attrs:{class:"language-java"}},[s("code",[t._v("val genesisBlock "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("BestBlock")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("BestBlock")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("from_genesis")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Network"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("LDKNetwork_Testnet")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\nval genesisBlockHash "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("String")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("byteArrayToHex")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("genesisBlock"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("block_hash")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n\nval serializedNetworkGraph "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Read network graph bytes from file")]),t._v("\nval networkGraph "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("NetworkGraph")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("NetworkGraph")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("read")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("serializedNetworkGraph"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" logger"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\nval p2pGossip "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("P2PGossipSync")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("P2PGossipSync")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("of")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("networkGraph"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Option_AccessZ")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("none")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" logger"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n")])])])]},proxy:!0},{key:"swift",fn:function(){return[s("div",{staticClass:"language-Swift extra-class"},[s("pre",{pre:!0,attrs:{class:"language-swift"}},[s("code",[s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// If Network Graph exists, then read from disk")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" serializedNetworkGraph "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Read Network Graph bytes from file")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" readResult "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("NetworkGraph")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("read")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("ser"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" serializedNetworkGraph"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" arg"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" logger"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" readResult"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("isOk")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n netGraph "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" readResult"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("getValue")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("!")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// If Network Graph does not exist, create a new one")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" netGraph "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("NetworkGraph")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("network"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" network"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" logger"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" logger"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Initialise RGS")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" rgs "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("RapidGossipSync")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("networkGraph"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" netGraph"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" logger"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" logger"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" lastSync "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" netGraph"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("getLastRapidGossipSyncTimestamp")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" snapshot "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("getSnapshot")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("lastSyncTimeStamp"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" lastSync"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" timestampSeconds "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("UInt64")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("NSDate")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("timeIntervalSince1970"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" res "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" rgs"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("updateNetworkGraphNoStd")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("updateData"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" snapshot"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" currentTimeUnix"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" timestampSeconds"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" res"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("isOk")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("print")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string-literal"}},[s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"RGS updated"')])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("else")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" snapshot "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("getSnapshot")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("lastSyncTimeStamp"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Use lastSyncTimeStamp as 0 for first Sync")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" timestampSeconds "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("UInt64")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("NSDate")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("timeIntervalSince1970"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" res "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" rgs"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("updateNetworkGraphNoStd")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("updateData"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" snapshot"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" currentTimeUnix"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" timestampSeconds"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" res"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("isOk")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("print")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string-literal"}},[s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"RGS initialized for the first time"')])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Get current snapshot from the RGS Server")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("func")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function-definition function"}},[t._v("getSnapshot")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("lastSyncTimeStamp"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("UInt32")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("UInt8")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Use LDK's RGS Server or use your own Server")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" url"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("URL")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("URL")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("string"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string-literal"}},[s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"https://rapidsync.lightningdevkit.org/snapshot/')]),s("span",{pre:!0,attrs:{class:"token interpolation-punctuation punctuation"}},[t._v("\\(")]),s("span",{pre:!0,attrs:{class:"token interpolation"}},[t._v("lastSyncTimeStamp")]),s("span",{pre:!0,attrs:{class:"token interpolation-punctuation punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"')])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("!")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" data "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Use the url to get the data")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" data "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" data "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("UInt8")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("data"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token nil constant"}},[t._v("nil")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])])]},proxy:!0}])}),t._v(" "),s("p",[s("strong",[t._v("Implementation notes:")]),t._v(" this struct is not required if you are providing your own routes. It will be used internally in "),s("code",[t._v("ChannelManager")]),t._v(" to build a "),s("code",[t._v("NetworkGraph")]),t._v(". Network options include: "),s("code",[t._v("Mainnet")]),t._v(","),s("code",[t._v("Regtest")]),t._v(","),s("code",[t._v("Testnet")]),t._v(","),s("code",[t._v("Signet")])]),t._v(" "),s("p",[s("strong",[t._v("Dependencies:")]),t._v(" "),s("code",[t._v("Logger")])]),t._v(" "),s("p",[s("strong",[t._v("Optional dependency:")]),t._v(" "),s("code",[t._v("Access")]),t._v(", a source of chain information. Recommended to be able to verify channels before adding them to the internal network graph.")]),t._v(" "),s("p",[s("strong",[t._v("References:")]),t._v(" "),s("a",{attrs:{href:"https://docs.rs/lightning/*/lightning/routing/gossip/struct.P2PGossipSync.html",target:"_blank",rel:"noopener noreferrer"}},[t._v("Rust "),s("code",[t._v("P2PGossipSync")]),t._v(" docs"),s("OutboundLink")],1),t._v(", "),s("a",{attrs:{href:"https://docs.rs/lightning/*/lightning/chain/trait.Access.html",target:"_blank",rel:"noopener noreferrer"}},[s("code",[t._v("Access")]),t._v(" docs"),s("OutboundLink")],1),t._v(", "),s("a",{attrs:{href:"https://github.com/lightningdevkit/ldk-garbagecollected/blob/main/src/main/java/org/ldk/structs/P2PGossipSync.java",target:"_blank",rel:"noopener noreferrer"}},[t._v("Java/Kotlin "),s("code",[t._v("P2PGossipSync")]),t._v(" bindings"),s("OutboundLink")],1),t._v(", "),s("a",{attrs:{href:"https://docs.rs/lightning-rapid-gossip-sync/*/lightning_rapid_gossip_sync/",target:"_blank",rel:"noopener noreferrer"}},[t._v("Rust "),s("code",[t._v("RapidGossipSync")]),t._v(" docs"),s("OutboundLink")],1),t._v(", "),s("a",{attrs:{href:"https://github.com/lightningdevkit/ldk-garbagecollected/blob/main/src/main/java/org/ldk/structs/RapidGossipSync.java",target:"_blank",rel:"noopener noreferrer"}},[t._v("Java/Kotlin "),s("code",[t._v("RapidGossipSync")]),t._v(" bindings"),s("OutboundLink")],1)]),t._v(" "),s("h3",{attrs:{id:"optional-initialize-probabilistic-scorer"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#optional-initialize-probabilistic-scorer"}},[t._v("#")]),t._v(" Optional: Initialize "),s("code",[t._v("Probabilistic Scorer")])]),t._v(" "),s("p",[s("strong",[t._v("What it's used for")]),t._v(": to find a suitable payment path to reach the destination.")]),t._v(" "),s("CodeSwitcher",{attrs:{languages:{rust:"Rust",kotlin:"Kotlin",swift:"Swift"}},scopedSlots:t._u([{key:"rust",fn:function(){return[s("div",{staticClass:"language-rust extra-class"},[s("pre",{pre:!0,attrs:{class:"language-rust"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" network_graph_path "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token macro property"}},[t._v("format!")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"{}/network_graph"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" ldk_data_dir"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("clone")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" network_graph "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Arc")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("new")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("disk"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("read_network")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Path")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("new")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v("network_graph_path"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" args"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("network"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" logger"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("clone")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" scorer_path "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token macro property"}},[t._v("format!")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"{}/scorer"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" ldk_data_dir"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("clone")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" scorer "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Arc")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("new")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("RwLock")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("new")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("disk"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("read_scorer")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Path")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("new")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v("scorer_path"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Arc")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("clone")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v("network_graph"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Arc")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("clone")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v("logger"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n")])])])]},proxy:!0},{key:"kotlin",fn:function(){return[s("div",{staticClass:"language-kotlin extra-class"},[s("pre",{pre:!0,attrs:{class:"language-kotlin"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("scorerFile"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("exists")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" scorerReaderResult "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" ProbabilisticScorer"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("read")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("scorerFile"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("readBytes")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" ProbabilisticScoringDecayParameters"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("with_default")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" networkGraph"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" logger"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("scorerReaderResult"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("is_ok"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" probabilisticScorer "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("scorerReaderResult "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("as")]),t._v(" Result_ProbabilisticScorerDecodeErrorZ"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("Result_ProbabilisticScorerDecodeErrorZ_OK"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("res\n scorer "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" MultiThreadedLockableScore"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("of")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("probabilisticScorer"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("as_Score")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n Log"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("i")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("LDKTAG"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string-literal singleline"}},[s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"LDK: Probabilistic Scorer loaded and running"')])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("else")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n Log"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("i")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("LDKTAG"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string-literal singleline"}},[s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"LDK: Couldn\'t load Probabilistic Scorer"')])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" decayParams "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" ProbabilisticScoringDecayParameters"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("with_default")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" probabilisticScorer "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" ProbabilisticScorer"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("of")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("decayParams"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" networkGraph"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" logger"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n scorer "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" MultiThreadedLockableScore"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("of")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("probabilisticScorer"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("as_Score")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n Log"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("i")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("LDKTAG"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string-literal singleline"}},[s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"LDK: Creating a new Probabilistic Scorer"')])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("else")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" decayParams "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" ProbabilisticScoringDecayParameters"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("with_default")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" probabilisticScorer "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" ProbabilisticScorer"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("of")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("decayParams"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" networkGraph"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" logger"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n scorer "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" MultiThreadedLockableScore"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("of")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("probabilisticScorer"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("as_Score")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])])]},proxy:!0},{key:"swift",fn:function(){return[s("div",{staticClass:"language-Swift extra-class"},[s("pre",{pre:!0,attrs:{class:"language-swift"}},[s("code",[s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// If Scorer exists, then read from disk")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" serializedScorer "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Read Scorer bytes from file")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" decayParams "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("ProbabilisticScoringDecayParameters")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("initWithDefault")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" serializedProbabilisticScorer "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("ProbabilisticScorer")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("read")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n ser"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" serializedScorer"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n argA"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" decayParams"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n argB"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" netGraph"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n argC"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" logger\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" res "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" serializedProbabilisticScorer"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("getValue")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" probabilisticScorer "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" res\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" score "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" probabilisticScorer"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("asScore")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Scorer loaded")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" scorer "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("MultiThreadedLockableScore")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("score"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" score"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// If Scorer does not exist, create a new one")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" decayParams "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("ProbabilisticScoringDecayParameters")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("initWithDefault")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" probabilisticScorer "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("ProbabilisticScorer")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n decayParams"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" decayParams"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n networkGraph"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" netGraph"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n logger"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" logger\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" score "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" probabilisticScorer"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("asScore")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Scorer loaded")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" scorer "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("MultiThreadedLockableScore")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("score"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" score"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n")])])])]},proxy:!0}])}),t._v(" "),s("p",[s("strong",[t._v("Dependencies:")]),t._v(" "),s("code",[t._v("NetworkGraph")])]),t._v(" "),s("p",[s("strong",[t._v("References:")]),t._v(" "),s("a",{attrs:{href:"https://docs.rs/lightning/*/lightning/routing/scoring/struct.ProbabilisticScorer.html",target:"_blank",rel:"noopener noreferrer"}},[t._v("Rust "),s("code",[t._v("ProbabilisticScorer")]),t._v(" docs"),s("OutboundLink")],1),t._v(", "),s("a",{attrs:{href:"https://github.com/lightningdevkit/ldk-garbagecollected/blob/main/src/main/java/org/ldk/structs/ProbabilisticScorer.java",target:"_blank",rel:"noopener noreferrer"}},[t._v("Java/Kotlin "),s("code",[t._v("ProbabilisticScorer")]),t._v(" docs"),s("OutboundLink")],1)])],1)}),[],!1,null,null,null);s.default=e.exports}}]); \ No newline at end of file +(window.webpackJsonp=window.webpackJsonp||[]).push([[51],{415:function(t,s,a){"use strict";a.r(s);var n=a(7),e=Object(n.a)({},(function(){var t=this,s=t._self._c;return s("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[s("h1",{attrs:{id:"setting-up-a-channelmanager"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#setting-up-a-channelmanager"}},[t._v("#")]),t._v(" Setting up a ChannelManager")]),t._v(" "),s("p",[t._v("The "),s("code",[t._v("ChannelManager")]),t._v(" is responsible for several tasks related to managing channel state. This includes keeping track of many channels, sending messages to appropriate channels, creating channels and more.")]),t._v(" "),s("h2",{attrs:{id:"adding-a-channelmanager"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#adding-a-channelmanager"}},[t._v("#")]),t._v(" Adding a ChannelManager")]),t._v(" "),s("p",[t._v("Adding a "),s("code",[t._v("ChannelManager")]),t._v(" to your application should look something like this:")]),t._v(" "),s("CodeSwitcher",{attrs:{languages:{rust:"Rust",kotlin:"Kotlin",swift:"Swift"}},scopedSlots:t._u([{key:"rust",fn:function(){return[s("div",{staticClass:"language-rust extra-class"},[s("pre",{pre:!0,attrs:{class:"language-rust"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("use")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("lightning"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),t._v("ln"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),t._v("channelmanager"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" channel_manager "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("ChannelManager")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("new")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v("fee_estimator"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v("chain_monitor"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v("broadcaster"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v("router"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v("logger"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v("entropy_source"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v("node_signer"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v("signer_provider"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n user_config"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n chain_params"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n current_timestamp\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])])]},proxy:!0},{key:"kotlin",fn:function(){return[s("div",{staticClass:"language-kotlin extra-class"},[s("pre",{pre:!0,attrs:{class:"language-kotlin"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" org"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("ldk"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("batteries"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("ChannelManagerConstructor\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" channelManagerConstructor "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("ChannelManagerConstructor")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n Network"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("LDKNetwork_Regtest"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n userConfig"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n latestBlockHash"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n latestBlockHeight"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n keysManager"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("as_EntropySource")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n keysManager"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("as_NodeSigner")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n keysManager"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("as_SignerProvider")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n feeEstimator"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n chainMonitor"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n router"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n scoringParams"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n routerWrapper"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// optional")]),t._v("\n txBroadcaster"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n logger\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n")])])])]},proxy:!0},{key:"swift",fn:function(){return[s("div",{staticClass:"language-Swift extra-class"},[s("pre",{pre:!0,attrs:{class:"language-swift"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("LightningDevKit")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" channelManagerConstructionParameters "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("ChannelManagerConstructionParameters")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n config"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" userConfig"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n entropySource"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" keysManager"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("asEntropySource")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n nodeSigner"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" keysManager"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("asNodeSigner")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n signerProvider"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" keysManager"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("asSignerProvider")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n feeEstimator"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" feeEstimator"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n chainMonitor"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" chainMonitor"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n txBroadcaster"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" broadcaster"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n logger"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" logger"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n enableP2PGossip"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token boolean"}},[t._v("true")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n scorer"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" scorer\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" channelManagerConstructor "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("ChannelManagerConstructor")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n network"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" network"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n currentBlockchainTipHash"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" latestBlockHash"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n currentBlockchainTipHeight"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" latestBlockHeight"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n netGraph"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" netGraph"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n params"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" channelManagerConstructionParameters\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n")])])])]},proxy:!0}])}),t._v(" "),s("p",[t._v("There are a few dependencies needed to get this working. Let's walk through setting up each one so we can plug them into our "),s("code",[t._v("ChannelManager")]),t._v(".")]),t._v(" "),s("h3",{attrs:{id:"initialize-the-feeestimator"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#initialize-the-feeestimator"}},[t._v("#")]),t._v(" Initialize the "),s("code",[t._v("FeeEstimator")])]),t._v(" "),s("p",[s("strong",[t._v("What it's used for:")]),t._v(" estimating fees for on-chain transactions that LDK wants broadcasted.")]),t._v(" "),s("CodeSwitcher",{attrs:{languages:{rust:"Rust",kotlin:"Kotlin",swift:"Swift"}},scopedSlots:t._u([{key:"rust",fn:function(){return[s("div",{staticClass:"language-rust extra-class"},[s("pre",{pre:!0,attrs:{class:"language-rust"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("struct")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token type-definition class-name"}},[t._v("YourFeeEstimator")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("impl")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("FeeEstimator")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("for")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("YourFeeEstimator")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("fn")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function-definition function"}},[t._v("get_est_sat_per_1000_weight")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("self")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" confirmation_target"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("ConfirmationTarget")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("->")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("u32")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("match")]),t._v(" confirmation_target "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("ConfirmationTarget")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Background")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Fetch background feerate,")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// You can add the code here for this case")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("ConfirmationTarget")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Normal")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Fetch normal feerate (~6 blocks)")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// You can add the code here for this case")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("ConfirmationTarget")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("HighPriority")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Fetch high priority feerate")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// You can add the code here for this case")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" fee_estimator "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("YourFeeEstimator")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])])]},proxy:!0},{key:"kotlin",fn:function(){return[s("div",{staticClass:"language-java extra-class"},[s("pre",{pre:!0,attrs:{class:"language-java"}},[s("code",[t._v("object "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("YourFeeEstimator")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("FeeEstimatorInterface")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n override fun "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("get_est_sat_per_1000_weight")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("confirmationTarget"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("ConfirmationTarget")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Int")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("confirmationTarget "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("==")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("ConfirmationTarget"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("LDKConfirmationTarget_Background")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// ")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("confirmationTarget "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("==")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("ConfirmationTarget"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("LDKConfirmationTarget_Normal")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// ")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("confirmationTarget "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("==")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("ConfirmationTarget"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("LDKConfirmationTarget_HighPriority")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// ")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// return default fee rate")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\nval feeEstimator"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("FeeEstimator")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("FeeEstimator")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("new_impl")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("YourFeeEstimator")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n")])])])]},proxy:!0},{key:"swift",fn:function(){return[s("div",{staticClass:"language-Swift extra-class"},[s("pre",{pre:!0,attrs:{class:"language-swift"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("MyFeeEstimator")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("FeeEstimator")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("override")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("func")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function-definition function"}},[t._v("getEstSatPer1000Weight")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("confirmationTarget"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Bindings")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("ConfirmationTarget")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("UInt32")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" confirmationTarget "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("==")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("MinAllowedNonAnchorChannelRemoteFee")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("253")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("else")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" confirmationTarget "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("==")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("ChannelCloseMinimum")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1000")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("else")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" confirmationTarget "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("==")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("NonAnchorChannelFee")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("7500")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("else")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" confirmationTarget "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("==")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("OnChainSweep")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("7500")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("7500")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" feeEstimator "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("MyFeeEstimator")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n\n")])])])]},proxy:!0}])}),t._v(" "),s("p",[s("strong",[t._v("Implementation notes:")])]),t._v(" "),s("ol",[s("li",[t._v("Fees must be returned in: satoshis per 1000 weight units")]),t._v(" "),s("li",[t._v("Fees must be no smaller than 253 (equivalent to 1 satoshi/vbyte, rounded up)")]),t._v(" "),s("li",[t._v("To reduce network traffic, you may want to cache fee results rather than\nretrieving fresh ones every time")])]),t._v(" "),s("p",[s("strong",[t._v("Dependencies:")]),t._v(" "),s("em",[t._v("none")])]),t._v(" "),s("p",[s("strong",[t._v("References:")]),t._v(" "),s("a",{attrs:{href:"https://docs.rs/lightning/*/lightning/chain/chaininterface/trait.FeeEstimator.html",target:"_blank",rel:"noopener noreferrer"}},[t._v("Rust "),s("code",[t._v("FeeEstimator")]),t._v(" docs"),s("OutboundLink")],1),t._v(", "),s("a",{attrs:{href:"https://github.com/lightningdevkit/ldk-garbagecollected/blob/main/src/main/java/org/ldk/structs/FeeEstimator.java",target:"_blank",rel:"noopener noreferrer"}},[t._v("Java/Kotlin "),s("code",[t._v("FeeEstimator")]),t._v(" bindings"),s("OutboundLink")],1)]),t._v(" "),s("h3",{attrs:{id:"initialize-the-router"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#initialize-the-router"}},[t._v("#")]),t._v(" Initialize the "),s("code",[t._v("Router")])]),t._v(" "),s("p",[s("strong",[t._v("What it's used for:")]),t._v(" Finds a Route for a payment between the given payer and a payee.")]),t._v(" "),s("CodeSwitcher",{attrs:{languages:{rust:"Rust",kotlin:"Kotlin",swift:"Swift"}},scopedSlots:t._u([{key:"rust",fn:function(){return[s("div",{staticClass:"language-rust extra-class"},[s("pre",{pre:!0,attrs:{class:"language-rust"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" router "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("DefaultRouter")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("new")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n network_graph"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("clone")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n logger"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("clone")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n keys_manager"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("get_secure_random_bytes")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n scorer"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("clone")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("ProbabilisticScoringFeeParameters")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("default")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n\n")])])])]},proxy:!0},{key:"kotlin",fn:function(){return[s("div",{staticClass:"language-kotlin extra-class"},[s("pre",{pre:!0,attrs:{class:"language-kotlin"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" networkGraph "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" NetworkGraph"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("of")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("Network"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("LDKNetwork_Regtest"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" logger"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n")])])])]},proxy:!0},{key:"swift",fn:function(){return[s("div",{staticClass:"language-Swift extra-class"},[s("pre",{pre:!0,attrs:{class:"language-swift"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" netGraph "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("NetworkGraph")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("network"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Regtest")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" logger"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" logger"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n")])])])]},proxy:!0}])}),t._v(" "),s("p",[s("strong",[t._v("Dependencies:")]),t._v(" "),s("code",[t._v("P2PGossipSync")]),t._v(", "),s("code",[t._v("Logger")]),t._v(", "),s("code",[t._v("KeysManager")]),t._v(", "),s("code",[t._v("Scorer")])]),t._v(" "),s("p",[s("strong",[t._v("References:")]),t._v(" "),s("a",{attrs:{href:"https://docs.rs/lightning/*/lightning/routing/router/trait.Router.html",target:"_blank",rel:"noopener noreferrer"}},[t._v("Rust "),s("code",[t._v("Router")]),t._v(" docs"),s("OutboundLink")],1),t._v(", "),s("a",{attrs:{href:"https://github.com/lightningdevkit/ldk-garbagecollected/blob/main/src/main/java/org/ldk/structs/Router.java",target:"_blank",rel:"noopener noreferrer"}},[t._v("Java/Kotlin "),s("code",[t._v("Router")]),t._v(" bindings"),s("OutboundLink")],1)]),t._v(" "),s("h3",{attrs:{id:"initialize-the-logger"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#initialize-the-logger"}},[t._v("#")]),t._v(" Initialize the "),s("code",[t._v("Logger")])]),t._v(" "),s("p",[s("strong",[t._v("What it's used for:")]),t._v(" LDK logging")]),t._v(" "),s("CodeSwitcher",{attrs:{languages:{rust:"Rust",kotlin:"Kotlin",swift:"Swift"}},scopedSlots:t._u([{key:"rust",fn:function(){return[s("div",{staticClass:"language-rust extra-class"},[s("pre",{pre:!0,attrs:{class:"language-rust"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("struct")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token type-definition class-name"}},[t._v("YourLogger")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("impl")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Logger")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("for")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("YourLogger")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("fn")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function-definition function"}},[t._v("log")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("self")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" record"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Record")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" raw_log "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" record"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("args"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("to_string")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" log "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token macro property"}},[t._v("format!")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"{} {:<5} [{}:{}] {}\\n"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("OffsetDateTime")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("now_utc")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("format")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"%F %T"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n record"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("level"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("to_string")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n record"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("module_path"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n record"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("line"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n raw_log\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// ")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" logger "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("YourLogger")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])])]},proxy:!0},{key:"kotlin",fn:function(){return[s("div",{staticClass:"language-kotlin extra-class"},[s("pre",{pre:!0,attrs:{class:"language-kotlin"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("object")]),t._v(" YourLogger "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" LoggerInterface "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("override")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("fun")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("log")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("record"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" Record"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// ")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" logger"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" Logger "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" Logger"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("new_impl")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("YourLogger"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n")])])])]},proxy:!0},{key:"swift",fn:function(){return[s("div",{staticClass:"language-Swift extra-class"},[s("pre",{pre:!0,attrs:{class:"language-swift"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("MyLogger")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Logger")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("override")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("func")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function-definition function"}},[t._v("log")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("record"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Bindings")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Record")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Print and/or write the log to a file")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" logger "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("MyLogger")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n\n")])])])]},proxy:!0}])}),t._v(" "),s("p",[s("strong",[t._v("Implementation notes:")]),t._v(" you'll likely want to write the logs to a file for debugging purposes.")]),t._v(" "),s("p",[s("strong",[t._v("Dependencies:")]),t._v(" "),s("em",[t._v("none")])]),t._v(" "),s("p",[s("strong",[t._v("References:")]),t._v(" "),s("a",{attrs:{href:"https://docs.rs/lightning/*/lightning/util/logger/trait.Logger.html",target:"_blank",rel:"noopener noreferrer"}},[t._v("Rust "),s("code",[t._v("Logger")]),t._v(" docs"),s("OutboundLink")],1),t._v(", "),s("a",{attrs:{href:"https://github.com/lightningdevkit/ldk-garbagecollected/blob/main/src/main/java/org/ldk/structs/Logger.java",target:"_blank",rel:"noopener noreferrer"}},[t._v("Java/Kotlin "),s("code",[t._v("Logger")]),t._v(" bindings"),s("OutboundLink")],1)]),t._v(" "),s("h3",{attrs:{id:"initialize-the-broadcasterinterface"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#initialize-the-broadcasterinterface"}},[t._v("#")]),t._v(" Initialize the "),s("code",[t._v("BroadcasterInterface")])]),t._v(" "),s("p",[s("strong",[t._v("What it's used for:")]),t._v(" broadcasting various transactions to the bitcoin network")]),t._v(" "),s("CodeSwitcher",{attrs:{languages:{rust:"Rust",kotlin:"Kotlin",swift:"Swift"}},scopedSlots:t._u([{key:"rust",fn:function(){return[s("div",{staticClass:"language-rust extra-class"},[s("pre",{pre:!0,attrs:{class:"language-rust"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("struct")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token type-definition class-name"}},[t._v("YourTxBroadcaster")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("impl")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("BroadcasterInterface")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("for")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("YourTxBroadcaster")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("fn")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function-definition function"}},[t._v("broadcast_transactions")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("self")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" txs"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Transaction")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// ")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" broadcaster "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("YourTxBroadcaster")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])])]},proxy:!0},{key:"kotlin",fn:function(){return[s("div",{staticClass:"language-kotlin extra-class"},[s("pre",{pre:!0,attrs:{class:"language-kotlin"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("object")]),t._v(" YourTxBroadcaster"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" BroadcasterInterface"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("BroadcasterInterfaceInterface")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("override")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("fun")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("broadcast_transactions")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("txs"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" Array"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("out")]),t._v(" ByteArray"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// ")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" txBroadcaster"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" BroadcasterInterface "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" BroadcasterInterface"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("new_impl")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("YourTxBroadcaster"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n\n")])])])]},proxy:!0},{key:"swift",fn:function(){return[s("div",{staticClass:"language-Swift extra-class"},[s("pre",{pre:!0,attrs:{class:"language-swift"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("YourTxBroacaster")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("BroadcasterInterface")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("override")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("func")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function-definition function"}},[t._v("broadcastTransactions")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("txs"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("UInt8")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Insert code to broadcast a list of transactions")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" broadcaster "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("YourTxBroacaster")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n")])])])]},proxy:!0}])}),t._v(" "),s("p",[s("strong",[t._v("Dependencies:")]),t._v(" "),s("em",[t._v("none")])]),t._v(" "),s("p",[s("strong",[t._v("References:")]),t._v(" "),s("a",{attrs:{href:"https://docs.rs/lightning/*/lightning/chain/chaininterface/trait.BroadcasterInterface.html",target:"_blank",rel:"noopener noreferrer"}},[t._v("Rust "),s("code",[t._v("BroadcasterInterface")]),t._v(" docs"),s("OutboundLink")],1),t._v(", "),s("a",{attrs:{href:"https://github.com/lightningdevkit/ldk-garbagecollected/blob/main/src/main/java/org/ldk/structs/BroadcasterInterface.java",target:"_blank",rel:"noopener noreferrer"}},[t._v("Java/Kotlin "),s("code",[t._v("BroadcasterInterface")]),t._v(" bindings"),s("OutboundLink")],1)]),t._v(" "),s("h3",{attrs:{id:"initialize-persist"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#initialize-persist"}},[t._v("#")]),t._v(" Initialize "),s("code",[t._v("Persist")])]),t._v(" "),s("p",[s("strong",[t._v("What it's used for:")]),t._v(" persisting "),s("code",[t._v("ChannelMonitor")]),t._v("s, which contain crucial channel data, in a timely manner")]),t._v(" "),s("CodeSwitcher",{attrs:{languages:{rust:"Rust",kotlin:"Kotlin",swift:"Swift"}},scopedSlots:t._u([{key:"rust",fn:function(){return[s("div",{staticClass:"language-rust extra-class"},[s("pre",{pre:!0,attrs:{class:"language-rust"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("struct")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token type-definition class-name"}},[t._v("YourPersister")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("impl")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("ChannelSigner")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Sign")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Persist")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("for")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("YourPersister")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("fn")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function-definition function"}},[t._v("persist_new_channel")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("self")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" id"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("OutPoint")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" data"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("ChannelMonitor")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("ChannelSigner")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("->")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Result")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("ChannelMonitorUpdateErr")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// ")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Note that monitor.encode() will get you the ChannelMonitor as a")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Vec.")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("fn")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function-definition function"}},[t._v("update_persisted_channel")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("self")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n id"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("OutPoint")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n update"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("ChannelMonitorUpdate")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n data"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("ChannelMonitor")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("ChannelSigner")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("->")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Result")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("ChannelMonitorUpdateErr")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// ")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" persister "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("YourPersister")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])])]},proxy:!0},{key:"kotlin",fn:function(){return[s("div",{staticClass:"language-kotlin extra-class"},[s("pre",{pre:!0,attrs:{class:"language-kotlin"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("object")]),t._v(" YourPersister"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" Persist"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("PersistInterface")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("override")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("fun")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("persist_new_channel")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n id"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" OutPoint"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("data")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" ChannelMonitor"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" updateId"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" MonitorUpdateId"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" Result_NoneChannelMonitorUpdateErrZ"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// ")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("override")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("fun")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("update_persisted_channel")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n id"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" OutPoint"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" update"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" ChannelMonitorUpdate"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("data")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" ChannelMonitor"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n updateId"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" MonitorUpdateId\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" Result_NoneChannelMonitorUpdateErrZ"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// ")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" persister"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" Persist "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" Persist"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("new_impl")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("YourPersister"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n")])])])]},proxy:!0},{key:"swift",fn:function(){return[s("div",{staticClass:"language-Swift extra-class"},[s("pre",{pre:!0,attrs:{class:"language-swift"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("MyPersister")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Persist")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("override")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("func")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function-definition function"}},[t._v("persistNewChannel")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("channelId"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("OutPoint")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" data"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("ChannelMonitor")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" updateId"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("MonitorUpdateId")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Bindings")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("ChannelMonitorUpdateStatus")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Insert the code to persist the ChannelMonitor to disk")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("override")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("func")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function-definition function"}},[t._v("updatePersistedChannel")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("channelId"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("OutPoint")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" update"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("ChannelMonitorUpdate")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" data"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("ChannelMonitor")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" updateId"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("MonitorUpdateId")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("ChannelMonitorUpdateStatus")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Insert the code to persist either ChannelMonitor or ChannelMonitorUpdate to disk")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" persister "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("MyPersister")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n")])])])]},proxy:!0}])}),t._v(" "),s("CodeSwitcher",{attrs:{languages:{rust:"Using LDK Sample Filesystem Persistence Crate in Rust"}},scopedSlots:t._u([{key:"rust",fn:function(){return[s("div",{staticClass:"language-rust extra-class"},[s("pre",{pre:!0,attrs:{class:"language-rust"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("use")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("lightning_persister"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("FilesystemPersister")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// import LDK sample persist crate")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" persister "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("FilesystemPersister")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("new")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("ldk_data_dir_path"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])])]},proxy:!0}])}),t._v(" "),s("p",[s("strong",[t._v("Implementation notes:")])]),t._v(" "),s("ul",[s("li",[s("code",[t._v("ChannelMonitor")]),t._v("s are objects which are capable of\nresponding to on-chain events for a given channel. Thus, you will have one\n"),s("code",[t._v("ChannelMonitor")]),t._v(" per channel. They are persisted in real-time and the "),s("code",[t._v("Persist")]),t._v("\nmethods will block progress on sending or receiving payments until they return.\nYou must ensure that "),s("code",[t._v("ChannelMonitor")]),t._v("s are durably persisted to disk before\nreturning or you may lose funds.")]),t._v(" "),s("li",[t._v("If you implement a custom persister, it's important to read the trait docs (linked in References) to make sure you satisfy the API requirements, particularly for "),s("code",[t._v("update_persisted_channel")])])]),t._v(" "),s("p",[s("strong",[t._v("Dependencies:")]),t._v(" "),s("em",[t._v("none")])]),t._v(" "),s("p",[s("strong",[t._v("References:")]),t._v(" "),s("a",{attrs:{href:"https://docs.rs/lightning/*/lightning/chain/chainmonitor/trait.Persist.html",target:"_blank",rel:"noopener noreferrer"}},[t._v("Rust "),s("code",[t._v("Persister")]),t._v(" docs"),s("OutboundLink")],1),t._v(", "),s("a",{attrs:{href:"https://github.com/lightningdevkit/ldk-garbagecollected/blob/main/src/main/java/org/ldk/structs/Persist.java",target:"_blank",rel:"noopener noreferrer"}},[t._v("Java/Kotlin "),s("code",[t._v("Persister")]),t._v(" bindings"),s("OutboundLink")],1)]),t._v(" "),s("h3",{attrs:{id:"start-background-processing"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#start-background-processing"}},[t._v("#")]),t._v(" Start Background Processing")]),t._v(" "),s("p",[s("strong",[t._v("What it's used for:")]),t._v(" running tasks periodically in the background to keep LDK operational.")]),t._v(" "),s("CodeSwitcher",{attrs:{languages:{rust:"Rust"}},scopedSlots:t._u([{key:"rust",fn:function(){return[s("div",{staticClass:"language-rust extra-class"},[s("pre",{pre:!0,attrs:{class:"language-rust"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" background_processor "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("BackgroundProcessor")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("start")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n persister"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Arc")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("clone")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v("invoice_payer"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Arc")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("clone")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v("chain_monitor"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Arc")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("clone")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v("channel_manager"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Arc")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("clone")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v("net_graph_msg_handler"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Arc")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("clone")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v("peer_manager"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Arc")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("clone")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v("logger"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])])]},proxy:!0}])}),t._v(" "),s("p",[s("strong",[t._v("Dependencies:")]),t._v(" "),s("code",[t._v("ChannelManager")]),t._v(", "),s("code",[t._v("ChainMonitor")]),t._v(", "),s("code",[t._v("PeerManager")]),t._v(", "),s("code",[t._v("Logger")])]),t._v(" "),s("p",[s("strong",[t._v("References:")]),t._v(" "),s("a",{attrs:{href:"https://docs.rs/lightning-background-processor/*/lightning_background_processor/struct.BackgroundProcessor.html#method.start",target:"_blank",rel:"noopener noreferrer"}},[t._v("Rust "),s("code",[t._v("BackgroundProcessor::Start")]),t._v(" docs"),s("OutboundLink")],1)]),t._v(" "),s("h3",{attrs:{id:"regularly-broadcast-node-announcement"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#regularly-broadcast-node-announcement"}},[t._v("#")]),t._v(" Regularly Broadcast Node Announcement")]),t._v(" "),s("p",[s("strong",[t._v("What it's used for:")]),t._v(" if you have 1 or more public channels, you may need to announce your node and its channels occasionally. LDK will automatically announce channels when they are created, but there are no guarantees you have connected peers at that time or that your peers will propagate such announcements. The broader node-announcement message is not automatically broadcast.")]),t._v(" "),s("CodeSwitcher",{attrs:{languages:{rust:"Rust"}},scopedSlots:t._u([{key:"rust",fn:function(){return[s("div",{staticClass:"language-rust extra-class"},[s("pre",{pre:!0,attrs:{class:"language-rust"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("mut")]),t._v(" interval "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("tokio"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),t._v("time"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("interval")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Duration")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("from_secs")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("60")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("loop")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n\tinterval"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("tick")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\tchannel_manager"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("broadcast_node_announcement")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n\t\t"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("3")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// insert your node's RGB color")]),t._v("\n\t\tnode_alias"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n\t\t"),s("span",{pre:!0,attrs:{class:"token macro property"}},[t._v("vec!")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("ldk_announced_listen_addr"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n\t"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])])]},proxy:!0}])}),t._v(" "),s("p",[s("strong",[t._v("Dependencies:")]),t._v(" "),s("code",[t._v("Peer Manager")])]),t._v(" "),s("p",[s("strong",[t._v("References:")]),t._v(" "),s("a",{attrs:{href:"https://docs.rs/lightning/*/lightning/ln/peer_handler/struct.PeerManager.html#method.broadcast_node_announcement",target:"_blank",rel:"noopener noreferrer"}},[s("code",[t._v("PeerManager::broadcast_node_announcement")]),t._v(" docs"),s("OutboundLink")],1)]),t._v(" "),s("h3",{attrs:{id:"optional-initialize-the-transaction-filter"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#optional-initialize-the-transaction-filter"}},[t._v("#")]),t._v(" Optional: Initialize the Transaction "),s("code",[t._v("Filter")])]),t._v(" "),s("p",[s("strong",[t._v("You must follow this step if:")]),t._v(" you are "),s("em",[t._v("not")]),t._v(" providing full blocks to LDK,\ni.e. if you're using BIP 157/158 or Electrum as your chain backend")]),t._v(" "),s("p",[s("strong",[t._v("What it's used for:")]),t._v(" if you are not providing full blocks, LDK uses this\nobject to tell you what transactions and outputs to watch for on-chain.")]),t._v(" "),s("CodeSwitcher",{attrs:{languages:{rust:"Rust",kotlin:"Kotlin",swift:"Swift"}},scopedSlots:t._u([{key:"rust",fn:function(){return[s("div",{staticClass:"language-rust extra-class"},[s("pre",{pre:!0,attrs:{class:"language-rust"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("struct")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token type-definition class-name"}},[t._v("YourTxFilter")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("impl")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Filter")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("for")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("YourTxFilter")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("fn")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function-definition function"}},[t._v("register_tx")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("self")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" txid"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Txid")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" script_pubkey"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Script")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// ")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("fn")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function-definition function"}},[t._v("register_output")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("self")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" output"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("WatchedOutput")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("->")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Option")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("usize")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Transaction")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// ")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" filter "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("YourTxFilter")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])])]},proxy:!0},{key:"kotlin",fn:function(){return[s("div",{staticClass:"language-java extra-class"},[s("pre",{pre:!0,attrs:{class:"language-java"}},[s("code",[t._v("object "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("YourTxFilter")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Filter"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("FilterInterface")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n override fun "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("register_tx")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("txid"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("ByteArray")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" script_pubkey"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("ByteArray")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// ")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n override fun "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("register_output")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("output"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("WatchedOutput")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// ")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\nval txFilter"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Filter")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Filter")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("new_impl")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("YourTxFilter")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n")])])])]},proxy:!0},{key:"swift",fn:function(){return[s("div",{staticClass:"language-Swift extra-class"},[s("pre",{pre:!0,attrs:{class:"language-swift"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("MyFilter")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Filter")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("override")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("func")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function-definition function"}},[t._v("registerTx")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("txid"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("UInt8")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" scriptPubkey"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("UInt8")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Insert code to watch this transaction")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("override")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("func")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function-definition function"}},[t._v("registerOutput")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("output"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Bindings")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("WatchedOutput")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Insert code to watch for any transaction that spend this output")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" filter "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("MyFilter")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n")])])])]},proxy:!0}])}),t._v(" "),s("p",[s("strong",[t._v("Implementation notes:")]),t._v(" see the "),s("RouterLink",{attrs:{to:"/blockchain_data/introduction/"}},[t._v("Blockchain Data")]),t._v(" guide for more info")],1),t._v(" "),s("p",[s("strong",[t._v("Dependencies:")]),t._v(" "),s("em",[t._v("none")])]),t._v(" "),s("p",[s("strong",[t._v("References:")]),t._v(" "),s("a",{attrs:{href:"https://docs.rs/lightning/*/lightning/chain/trait.Filter.html",target:"_blank",rel:"noopener noreferrer"}},[t._v("Rust "),s("code",[t._v("Filter")]),t._v(" docs"),s("OutboundLink")],1),t._v(", "),s("a",{attrs:{href:"https://github.com/lightningdevkit/ldk-garbagecollected/blob/main/src/main/java/org/ldk/structs/Filter.java",target:"_blank",rel:"noopener noreferrer"}},[t._v("Java/Kotlin "),s("code",[t._v("Filter")]),t._v(" bindings"),s("OutboundLink")],1)]),t._v(" "),s("h3",{attrs:{id:"initialize-the-chainmonitor"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#initialize-the-chainmonitor"}},[t._v("#")]),t._v(" Initialize the "),s("code",[t._v("ChainMonitor")])]),t._v(" "),s("p",[s("strong",[t._v("What it's used for:")]),t._v(" tracking one or more "),s("code",[t._v("ChannelMonitor")]),t._v("s and using them to monitor the chain for lighting transactions that are relevant to our node, and broadcasting transactions if need be.")]),t._v(" "),s("CodeSwitcher",{attrs:{languages:{rust:"Rust",kotlin:"Kotlin",swift:"Swift"}},scopedSlots:t._u([{key:"rust",fn:function(){return[s("div",{staticClass:"language-rust extra-class"},[s("pre",{pre:!0,attrs:{class:"language-rust"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" filter"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Option")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Box")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("dyn")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Filter")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// leave this as None or insert the Filter trait object")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" chain_monitor "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("ChainMonitor")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("new")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("filter"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v("broadcaster"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v("logger"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v("fee_estimator"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v("persister"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])])]},proxy:!0},{key:"kotlin",fn:function(){return[s("div",{staticClass:"language-java extra-class"},[s("pre",{pre:!0,attrs:{class:"language-java"}},[s("code",[t._v("val filter "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Filter")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// leave this as `null` or insert the Filter object.")]),t._v("\n\nval chainMonitor "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("ChainMonitor")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("of")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("filter"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" txBroadcaster"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" logger"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" feeEstimator"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" persister"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n")])])])]},proxy:!0},{key:"swift",fn:function(){return[s("div",{staticClass:"language-Swift extra-class"},[s("pre",{pre:!0,attrs:{class:"language-swift"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" filter"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Filter")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// leave this as `nil` or insert the Filter object.")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" chainMonitor "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("ChainMonitor")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n chainSource"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" filter"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n broadcaster"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" broadcaster"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n logger"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" logger"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n feeest"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" feeEstimator"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n persister"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" persister\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n")])])])]},proxy:!0}])}),t._v(" "),s("p",[s("strong",[t._v("Implementation notes:")]),t._v(" "),s("code",[t._v("Filter")]),t._v(" must be non-"),s("code",[t._v("None")]),t._v(" if you're using Electrum or BIP 157/158 as your chain backend")]),t._v(" "),s("p",[s("strong",[t._v("Dependencies:")]),t._v(" "),s("code",[t._v("FeeEstimator")]),t._v(", "),s("code",[t._v("Logger")]),t._v(", "),s("code",[t._v("BroadcasterInterface")]),t._v(", "),s("code",[t._v("Persist")])]),t._v(" "),s("p",[s("strong",[t._v("Optional dependency:")]),t._v(" "),s("code",[t._v("Filter")])]),t._v(" "),s("p",[s("strong",[t._v("References:")]),t._v(" "),s("a",{attrs:{href:"https://docs.rs/lightning/*/lightning/chain/chainmonitor/struct.ChainMonitor.html",target:"_blank",rel:"noopener noreferrer"}},[t._v("Rust "),s("code",[t._v("ChainMonitor")]),t._v(" docs"),s("OutboundLink")],1),t._v(", "),s("a",{attrs:{href:"https://github.com/lightningdevkit/ldk-garbagecollected/blob/main/src/main/java/org/ldk/structs/ChainMonitor.java",target:"_blank",rel:"noopener noreferrer"}},[t._v("Java/Kotlin "),s("code",[t._v("ChainMonitor")]),t._v(" bindings"),s("OutboundLink")],1)]),t._v(" "),s("h3",{attrs:{id:"initialize-the-keysmanager"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#initialize-the-keysmanager"}},[t._v("#")]),t._v(" Initialize the "),s("code",[t._v("KeysManager")])]),t._v(" "),s("p",[s("strong",[t._v("What it's used for:")]),t._v(" providing keys for signing Lightning transactions")]),t._v(" "),s("CodeSwitcher",{attrs:{languages:{rust:"Rust",kotlin:"Kotlin",swift:"Swift"}},scopedSlots:t._u([{key:"rust",fn:function(){return[s("div",{staticClass:"language-rust extra-class"},[s("pre",{pre:!0,attrs:{class:"language-rust"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" keys_seed_path "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token macro property"}},[t._v("format!")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"{}/keys_seed"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" ldk_data_dir"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("clone")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// If we're restarting and already have a key seed, read it from disk. Else,")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// create a new one.")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" keys_seed "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Ok")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("seed"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("fs"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("read")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("keys_seed_path"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("clone")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token macro property"}},[t._v("assert_eq!")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("seed"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("len")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("32")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("mut")]),t._v(" key "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("32")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n key"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("copy_from_slice")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v("seed"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n key\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("else")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("mut")]),t._v(" key "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("32")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("thread_rng")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("fill_bytes")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("mut")]),t._v(" key"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("match")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("File")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("create")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("keys_seed_path"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("clone")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Ok")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("mut")]),t._v(" f"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n f"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("write_all")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v("key"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("expect")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Failed to write node keys seed to disk"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n f"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("sync_all")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("expect")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Failed to sync node keys seed to disk"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Err")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("e"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token macro property"}},[t._v("println!")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"ERROR: Unable to create keys seed file {}: {}"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n keys_seed_path"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" e\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n key\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" cur "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("SystemTime")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("now")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("duration_since")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("SystemTime")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("UNIX_EPOCH")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("unwrap")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" keys_manager "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("KeysManager")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("new")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v("keys_seed"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" cur"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("as_secs")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" cur"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("subsec_nanos")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n")])])])]},proxy:!0},{key:"kotlin",fn:function(){return[s("div",{staticClass:"language-java extra-class"},[s("pre",{pre:!0,attrs:{class:"language-java"}},[s("code",[t._v("val keySeed "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("ByteArray")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("32")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// ")]),t._v("\nval keysManager "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("KeysManager")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("of")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n keySeed"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("System")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("currentTimeMillis")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("/")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1000")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("System")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("currentTimeMillis")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1000")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("toInt")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n")])])])]},proxy:!0},{key:"swift",fn:function(){return[s("div",{staticClass:"language-Swift extra-class"},[s("pre",{pre:!0,attrs:{class:"language-swift"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" seed "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Insert code to create seed with random bytes or if restarting, reload the seed from disk")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" timestampSeconds "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("UInt64")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("NSDate")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("timeIntervalSince1970"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" timestampNanos "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("UInt32")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("init")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("truncating"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("NSNumber")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("value"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" timestampSeconds "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1000")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1000")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" keysManager "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("KeysManager")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("seed"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" seed"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" startingTimeSecs"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" timestampSeconds"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" startingTimeNanos"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" timestampNanos"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n")])])])]},proxy:!0}])}),t._v(" "),s("p",[s("strong",[t._v("Implementation notes:")])]),t._v(" "),s("ul",[s("li",[t._v("See the "),s("RouterLink",{attrs:{to:"/key_management/"}},[t._v("Key Management")]),t._v(" guide for more info")],1),t._v(" "),s("li",[t._v("Note that you must write the "),s("code",[t._v("key_seed")]),t._v(" you give to the "),s("code",[t._v("KeysManager")]),t._v(" on\nstartup to disk, and keep using it to initialize the "),s("code",[t._v("KeysManager")]),t._v(" every time\nyou restart. This "),s("code",[t._v("key_seed")]),t._v(" is used to derive your node's secret key (which\ncorresponds to its node pubkey) and all other secret key material.")]),t._v(" "),s("li",[t._v("The current time is part of the "),s("code",[t._v("KeysManager")]),t._v("'s parameters because it is used to derive\nrandom numbers from the seed where required, to ensure all random\ngeneration is unique across restarts.")])]),t._v(" "),s("p",[s("strong",[t._v("Dependencies:")]),t._v(" random bytes")]),t._v(" "),s("p",[s("strong",[t._v("References:")]),t._v(" "),s("a",{attrs:{href:"https://docs.rs/lightning/*/lightning/sign/struct.KeysManager.html",target:"_blank",rel:"noopener noreferrer"}},[t._v("Rust "),s("code",[t._v("KeysManager")]),t._v(" docs"),s("OutboundLink")],1),t._v(", "),s("a",{attrs:{href:"https://github.com/lightningdevkit/ldk-garbagecollected/blob/main/src/main/java/org/ldk/structs/KeysManager.java",target:"_blank",rel:"noopener noreferrer"}},[t._v("Java/Kotlin "),s("code",[t._v("KeysManager")]),t._v(" bindings"),s("OutboundLink")],1)]),t._v(" "),s("h3",{attrs:{id:"read-channelmonitor-state-from-disk"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#read-channelmonitor-state-from-disk"}},[t._v("#")]),t._v(" Read "),s("code",[t._v("ChannelMonitor")]),t._v(" state from disk")]),t._v(" "),s("p",[s("strong",[t._v("What it's used for:")]),t._v(" if LDK is restarting and has at least 1 channel, its "),s("code",[t._v("ChannelMonitor")]),t._v("s will need to be (1) fed to the "),s("code",[t._v("ChannelManager")]),t._v(" and (2) synced to chain.")]),t._v(" "),s("CodeSwitcher",{attrs:{languages:{rust:"Rust",kotlin:"Kotlin",swift:"Swift"}},scopedSlots:t._u([{key:"rust",fn:function(){return[s("div",{staticClass:"language-rust extra-class"},[s("pre",{pre:!0,attrs:{class:"language-rust"}},[s("code",[s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Use LDK's sample persister crate provided method")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("mut")]),t._v(" channel_monitors "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v("\n persister"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("read_channelmonitors")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("keys_manager"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("clone")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("unwrap")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// If you are using Electrum or BIP 157/158, you must call load_outputs_to_watch")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// on each ChannelMonitor to prepare for chain synchronization.")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("for")]),t._v(" chan_mon "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("in")]),t._v(" channel_monitors"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("iter")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n chan_mon"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("load_outputs_to_watch")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v("filter"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])])]},proxy:!0},{key:"kotlin",fn:function(){return[s("div",{staticClass:"language-java extra-class"},[s("pre",{pre:!0,attrs:{class:"language-java"}},[s("code",[s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Initialize the hashmap where we'll store the `ChannelMonitor`s read from disk.")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// This hashmap will later be given to the `ChannelManager` on initialization.")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("var")]),t._v(" channelMonitors "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" arrayOf"),s("span",{pre:!0,attrs:{class:"token generics"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("ByteArray")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\nval channelMonitorList "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("ArrayList")]),s("span",{pre:!0,attrs:{class:"token generics"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("ByteArray")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\nchannelMonitorFiles"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("iterator")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("forEach "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n val channelMonitorBytes "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" it"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("hexStringToByteArray")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n channelMonitorList"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("add")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("channelMonitorBytes"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\nchannelMonitors "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" channelMonitorList"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("toTypedArray")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])])]},proxy:!0},{key:"swift",fn:function(){return[s("div",{staticClass:"language-Swift extra-class"},[s("pre",{pre:!0,attrs:{class:"language-swift"}},[s("code",[s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Initialize the array where we'll store the `ChannelMonitor`s read from disk.")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// This array will later be given to the `ChannelManagerConstructor` on initialization.")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("var")]),t._v(" serializedChannelMonitors"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("UInt8")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" allChannels "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Insert code to get a list of persisted channels")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("for")]),t._v(" channel "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("in")]),t._v(" allChannels "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" channelData "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("try")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Data")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("contentsOf"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" channel"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" channelBytes "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("UInt8")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("channelData"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n serializedChannelMonitors"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("append")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("channelBytes"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])])]},proxy:!0}])}),t._v(" "),s("p",[s("strong",[t._v("Dependencies:")]),t._v(" "),s("code",[t._v("KeysManager")])]),t._v(" "),s("p",[s("strong",[t._v("References:")]),t._v(" "),s("a",{attrs:{href:"https://docs.rs/lightning/*/lightning/chain/channelmonitor/struct.ChannelMonitor.html#method.load_outputs_to_watch",target:"_blank",rel:"noopener noreferrer"}},[t._v("Rust "),s("code",[t._v("load_outputs_to_watch")]),t._v(" docs"),s("OutboundLink")],1)]),t._v(" "),s("h3",{attrs:{id:"initialize-the-channelmanager"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#initialize-the-channelmanager"}},[t._v("#")]),t._v(" Initialize the "),s("code",[t._v("ChannelManager")])]),t._v(" "),s("p",[s("strong",[t._v("What it's used for:")]),t._v(" managing channel state")]),t._v(" "),s("CodeSwitcher",{attrs:{languages:{rust:"Rust",kotlin:"Kotlin",swift:"Swift"}},scopedSlots:t._u([{key:"rust",fn:function(){return[s("div",{staticClass:"language-rust extra-class"},[s("pre",{pre:!0,attrs:{class:"language-rust"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" user_config "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("UserConfig")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("default")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("/* RESTARTING */")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("channel_manager_blockhash"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("mut")]),t._v(" channel_manager"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" channel_manager_file "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("fs"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("File")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("open")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token macro property"}},[t._v("format!")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"{}/manager"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" ldk_data_dir"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("clone")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("unwrap")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Use the `ChannelMonitors` we read from disk.")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("mut")]),t._v(" channel_monitor_mut_references "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Vec")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("new")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("for")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("_"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" channel_monitor"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("in")]),t._v(" channel_monitors"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("iter_mut")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n channel_monitor_mut_references"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("push")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("channel_monitor"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" read_args "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("ChannelManagerReadArgs")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("new")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v("keys_manager"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v("fee_estimator"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v("chain_monitor"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v("broadcaster"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v("logger"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n user_config"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n channel_monitor_mut_references"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("BlockHash")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("ChannelManager")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("read")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("mut")]),t._v(" channel_manager_file"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" read_args"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("unwrap")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("/* FRESH CHANNELMANAGER */")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("channel_manager_blockhash"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("mut")]),t._v(" channel_manager"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" best_blockhash "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// insert the best blockhash you know of")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" best_chain_height "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// insert the height corresponding to best_blockhash")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" chain_params "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("ChainParameters")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n network"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Network")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Testnet")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// substitute this with your network")]),t._v("\n best_block"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("BestBlock")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("new")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("best_blockhash"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" best_chain_height"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" fresh_channel_manager "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("ChannelManager")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("new")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v("fee_estimator"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v("chain_monitor"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v("broadcaster"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v("router"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v("logger"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v("entropy_source"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v("node_signer"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v("signer_provider"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n user_config"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n chain_params"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n current_timestamp\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("best_blockhash"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" fresh_channel_manager"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n")])])])]},proxy:!0},{key:"kotlin",fn:function(){return[s("div",{staticClass:"language-kotlin extra-class"},[s("pre",{pre:!0,attrs:{class:"language-kotlin"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("serializedChannelManager "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("!=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("null")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&&")]),t._v(" serializedChannelManager"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("isNotEmpty")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Loading from disk (restarting)")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" channelManagerConstructor "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("ChannelManagerConstructor")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n serializedChannelManager"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n serializedChannelMonitors"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n userConfig"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n keysManager"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("!!")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("inner"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("as_EntropySource")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n keysManager"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("!!")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("inner"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("as_NodeSigner")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n SignerProvider"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("new_impl")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("keysManager"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("!!")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("signerProvider"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n feeEstimator"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n chainMonitor"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n txFilter"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n networkGraph"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("!!")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("write")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n ProbabilisticScoringDecayParameters"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("with_default")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n ProbabilisticScoringFeeParameters"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("with_default")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n scorer"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("!!")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("write")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("null")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n txBroadcaster"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n logger\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("else")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Fresh start")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" channelManagerConstructor "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("ChannelManagerConstructor")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n Network"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("LDKNetwork_Regtest"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n userConfig"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n latestBlockHash"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("toByteArray")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n latestBlockHeight"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n keysManager"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("!!")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("inner"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("as_EntropySource")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n keysManager"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("!!")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("inner"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("as_NodeSigner")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n SignerProvider"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("new_impl")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("keysManager"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("!!")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("signerProvider"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n feeEstimator"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n chainMonitor"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n networkGraph"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n ProbabilisticScoringDecayParameters"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("with_default")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n ProbabilisticScoringFeeParameters"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("with_default")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("null")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n txBroadcaster"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n logger\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n")])])])]},proxy:!0},{key:"swift",fn:function(){return[s("div",{staticClass:"language-Swift extra-class"},[s("pre",{pre:!0,attrs:{class:"language-swift"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" serializedChannelManager "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("!=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token nil constant"}},[t._v("nil")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&&")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("!")]),t._v("serializedChannelManager"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("!")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("isEmpty "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("do")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" channelManagerConstructor "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("try")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("ChannelManagerConstructor")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n channelManagerSerialized"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" serializedChannelManager"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("!")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n channelMonitorsSerialized"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" serializedChannelMonitors"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n networkGraph"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("NetworkGraphArgument")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("instance")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("netGraph"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n filter"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" filter"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n params"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" channelManagerConstructionParameters\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("catch")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" channelManagerConstructor "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("ChannelManagerConstructor")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n network"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" network"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n currentBlockchainTipHash"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" latestBlockHash"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("!")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n currentBlockchainTipHeight"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" latestBlockHeight"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("!")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n netGraph"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" netGraph"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n params"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" channelManagerConstructionParameters\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("else")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" channelManagerConstructor "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("ChannelManagerConstructor")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n network"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" network"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n currentBlockchainTipHash"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" latestBlockHash"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("!")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n currentBlockchainTipHeight"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" latestBlockHeight"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("!")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n netGraph"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" netGraph"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n params"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" channelManagerConstructionParameters\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n")])])])]},proxy:!0}])}),t._v(" "),s("p",[s("strong",[t._v("Implementation notes:")]),t._v(" No methods should be called on "),s("code",[t._v("ChannelManager")]),t._v(" until\n"),s("em",[t._v("after")]),t._v(" the "),s("code",[t._v("ChannelMonitor")]),t._v("s and "),s("code",[t._v("ChannelManager")]),t._v(" are synced to the chain tip (next step).")]),t._v(" "),s("p",[s("strong",[t._v("Dependencies:")]),t._v(" "),s("code",[t._v("KeysManager")]),t._v(", "),s("code",[t._v("FeeEstimator")]),t._v(", "),s("code",[t._v("ChainMonitor")]),t._v(", "),s("code",[t._v("BroadcasterInterface")]),t._v(", "),s("code",[t._v("Logger")])]),t._v(" "),s("p",[s("strong",[t._v("References:")]),t._v(" "),s("a",{attrs:{href:"https://docs.rs/lightning/*/lightning/ln/channelmanager/struct.ChannelManager.html",target:"_blank",rel:"noopener noreferrer"}},[t._v("Rust "),s("code",[t._v("ChannelManager")]),t._v(" docs"),s("OutboundLink")],1),t._v(", "),s("a",{attrs:{href:"https://github.com/lightningdevkit/ldk-garbagecollected/blob/main/src/main/java/org/ldk/structs/ChannelManager.java",target:"_blank",rel:"noopener noreferrer"}},[t._v("Java/Kotlin "),s("code",[t._v("ChannelManager")]),t._v(" bindings"),s("OutboundLink")],1)]),t._v(" "),s("h3",{attrs:{id:"sync-channelmonitors-and-channelmanager-to-chain-tip"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#sync-channelmonitors-and-channelmanager-to-chain-tip"}},[t._v("#")]),t._v(" Sync "),s("code",[t._v("ChannelMonitor")]),t._v("s and "),s("code",[t._v("ChannelManager")]),t._v(" to chain tip")]),t._v(" "),s("p",[s("strong",[t._v("What it's used for:")]),t._v(" this step is only necessary if you're restarting and have open channels. This step ensures that LDK channel state is up-to-date with the bitcoin blockchain")]),t._v(" "),s("p",[s("strong",[t._v("Example:")])]),t._v(" "),s("CodeSwitcher",{attrs:{languages:{rust:"Rust",kotlin:"Kotlin",swift:"Swift"}},scopedSlots:t._u([{key:"rust",fn:function(){return[s("div",{staticClass:"language-rust extra-class"},[s("pre",{pre:!0,attrs:{class:"language-rust"}},[s("code",[s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Full Blocks or BIP 157/158")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("use")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("lightning_block_sync"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),t._v("init"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("use")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("lightning_block_sync"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),t._v("poll"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("use")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("lightning_block_sync"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("UnboundedCache")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("impl")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("lightning_block_sync"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("BlockSource")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("for")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("YourChainBackend")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("fn")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function-definition function"}},[t._v("get_header")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token lifetime-annotation symbol"}},[t._v("'a")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),s("span",{pre:!0,attrs:{class:"token lifetime-annotation symbol"}},[t._v("'a")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("mut")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("self")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" header_hash"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),s("span",{pre:!0,attrs:{class:"token lifetime-annotation symbol"}},[t._v("'a")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("BlockHash")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" height_hint"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Option")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("u32")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("->")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("AsyncBlockSourceResult")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token lifetime-annotation symbol"}},[t._v("'a")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("BlockHeaderData")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// ")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("fn")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function-definition function"}},[t._v("get_block")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token lifetime-annotation symbol"}},[t._v("'a")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),s("span",{pre:!0,attrs:{class:"token lifetime-annotation symbol"}},[t._v("'a")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("mut")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("self")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" header_hash"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),s("span",{pre:!0,attrs:{class:"token lifetime-annotation symbol"}},[t._v("'a")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("BlockHash")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("->")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("AsyncBlockSourceResult")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token lifetime-annotation symbol"}},[t._v("'a")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Block")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// ")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("fn")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function-definition function"}},[t._v("get_best_block")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token lifetime-annotation symbol"}},[t._v("'a")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),s("span",{pre:!0,attrs:{class:"token lifetime-annotation symbol"}},[t._v("'a")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("mut")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("self")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("->")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("AsyncBlockSourceResult")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("BlockHash")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Option")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("u32")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// ")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" block_source "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("YourChainBackend")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("new")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("mut")]),t._v(" chain_listener_channel_monitors "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Vec")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("new")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("mut")]),t._v(" cache "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("UnboundedCache")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("new")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("mut")]),t._v(" chain_tip"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Option")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("poll"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("ValidatedBlockHeader")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("None")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("mut")]),t._v(" chain_listeners "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token macro property"}},[t._v("vec!")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n channel_manager_blockhash"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("mut")]),t._v(" channel_manager "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("as")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("mut")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("dyn")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("chain"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Listen")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("for")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("blockhash"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" channel_monitor"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("in")]),t._v(" channel_monitors"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("drain")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("..")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" outpoint "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" channel_monitor"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("get_funding_txo")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n chain_listener_channel_monitors"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("push")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n blockhash"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n channel_monitor"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v("broadcaster"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v("fee_estimator"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v("logger"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n outpoint"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("for")]),t._v(" monitor_listener_info "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("in")]),t._v(" chain_listener_channel_monitors"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("iter_mut")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n chain_listeners"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("push")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n monitor_listener_info"),s("span",{pre:!0,attrs:{class:"token number"}},[t._v(".0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("mut")]),t._v(" monitor_listener_info"),s("span",{pre:!0,attrs:{class:"token number"}},[t._v(".1")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("as")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("mut")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("dyn")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("chain"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Listen")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Save the chain tip to be used in future steps")]),t._v("\nchain_tip "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Some")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("init"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("synchronize_listeners")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("mut")]),t._v(" block_source"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Network")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Testnet")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("mut")]),t._v(" cache"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n chain_listeners"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("unwrap")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n\n")])])])]},proxy:!0},{key:"kotlin",fn:function(){return[s("div",{staticClass:"language-java extra-class"},[s("pre",{pre:!0,attrs:{class:"language-java"}},[s("code",[s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Electrum/Esplora")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Retrieve transaction IDs to check the chain for un-confirmation.")]),t._v("\nval relevantTxIdsFromChannelManager"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Array")]),s("span",{pre:!0,attrs:{class:"token generics"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("ByteArray")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" channelManager "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("as_Confirm")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("get_relevant_txids")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\nval relevantTxIdsFromChannelManager"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Array")]),s("span",{pre:!0,attrs:{class:"token generics"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("ByteArray")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" chainMonitor"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("as_Confirm")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("get_relevant_txids")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\nval relevantTxIds "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" relevantTxIdsFromChannelManager "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+")]),t._v(" relevantTxIdsFromChainMonitor\n\nval unconfirmedTxs"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Array")]),s("span",{pre:!0,attrs:{class:"token generics"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("ByteArray")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// ")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("for")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("txid in unconfirmedTxs"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n channelManager "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("transaction_unconfirmed")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("txid"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n chainMonitor"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("transaction_unconfirmed")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("txid"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Retrieve transactions and outputs that were registered through the `Filter`")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// interface.")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// If any of these txs/outputs were confirmed on-chain, then:")]),t._v("\nval header"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Array")]),s("span",{pre:!0,attrs:{class:"token generics"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("ByteArray")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// insert block header from the block with confirmed tx/output")]),t._v("\nval height"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Int")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// insert block height of `header`")]),t._v("\nval txIndex"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Long")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// insert tx index in block")]),t._v("\nval serializedTx"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Array")]),s("span",{pre:!0,attrs:{class:"token generics"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("ByteArray")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// insert tx hex as byte array")]),t._v("\nval tx"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("TwoTuple_usizeTransactionZ")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("TwoTuple_usizeTransactionZ")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("of")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("txIndex"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" serializedTx"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Marshall all TwoTuples you built right above into an array")]),t._v("\nval txList "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" arrayOf"),s("span",{pre:!0,attrs:{class:"token generics"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("TwoTuple_usizeTransactionZ")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("TwoTuple_usizeTransactionZ")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("of")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("tx"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\nchannelManager"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("transactions_confirmed")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("header"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" height"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" txList"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\nchainMonitor"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("transactions_confirmed")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("header"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" height"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" txList"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\nval bestHeader"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Array")]),s("span",{pre:!0,attrs:{class:"token generics"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("ByteArray")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// ")]),t._v("\nval bestHeight"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Int")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// ")]),t._v("\nchannelManager"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("update_best_block")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("bestHeader"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" bestHeight"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\nchainMonitor"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("update_best_block")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("bestHeader"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" bestHeight"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Finally, tell LDK that chain sync is complete. This will also spawn several")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// background threads to handle networking and event processing.")]),t._v("\nchannelManagerConstructor"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("chain_sync_completed")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("customEventHandler"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])])]},proxy:!0},{key:"swift",fn:function(){return[s("div",{staticClass:"language-Swift extra-class"},[s("pre",{pre:!0,attrs:{class:"language-swift"}},[s("code",[s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Electrum/Esplora")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Retrieve transaction IDs to check the chain for un-confirmation.")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" relevantTxIds1 "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" channelManager"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("asConfirm")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("getRelevantTxids")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("??")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" relevantTxIds2 "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" chainMonitor"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("asConfirm")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("getRelevantTxids")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("??")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("var")]),t._v(" relevantTxIds"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("UInt8")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("UInt8")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("for")]),t._v(" tx "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("in")]),t._v(" relevantTxIds1 "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n relevantTxIds"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("append")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("tx"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("for")]),t._v(" tx "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("in")]),t._v(" relevantTxIds2 "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n relevantTxIds"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("append")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("tx"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("var")]),t._v(" unconfirmedTx"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("UInt8")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Insert code to find out from your chain source")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// if any of relevantTxIds have been reorged out")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// of the chain")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("for")]),t._v(" txid "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("in")]),t._v(" unconfirmedTx "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n channelManager"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("asConfirm")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("transactionUnconfirmed")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("txid"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" txid"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n chainMonitor"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("asConfirm")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("transactionUnconfirmed")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("txid"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" txid"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Retrieve transactions and outputs that were registered through the `Filter` interface.")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("var")]),t._v(" confirmedTx"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("UInt8")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Insert code to find out from your chain source")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// if any of the `Filter` txs/outputs were confirmed")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// on-chain")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("for")]),t._v(" txid "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("in")]),t._v(" confirmedTx "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" header"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("UInt8")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Insert code to fetch header")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" height"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("UInt32")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Insert code to fetch height of the header")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" tx"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("UInt8")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Insert code to fetch tx")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" txIndex"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("UInt")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Insert code to fetch tx index")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("var")]),t._v(" twoTuple"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("UInt")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("UInt8")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v("\n twoTuple"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("append")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("UInt")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("UInt8")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("txIndex"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" tx"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n channelManager"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("asConfirm")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("transactionsConfirmed")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("header"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" header"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" txdata"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" twoTuple"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" height"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" height"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n chainMonitor"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("asConfirm")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("transactionsConfirmed")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("header"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" header"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" txdata"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" twoTuple"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" height"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" height"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" bestHeader "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Insert code to fetch best header")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" bestHeight "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Insert code to fetch best height")]),t._v("\n\nchannelManager"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("asConfirm")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("bestBlockUpdated")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("header"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" bestHeader"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" height"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" bestHeight"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\nchainMonitor"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("asConfirm")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("bestBlockUpdated")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("header"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" bestHeader"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" height"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" bestHeight"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Finally, tell LDK that chain sync is complete. This will also spawn several")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// background threads to handle networking and event processing.")]),t._v("\nchannelManagerConstructor"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("chainSyncCompleted")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("persister"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" channelManagerPersister"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n")])])])]},proxy:!0}])}),t._v(" "),s("p",[s("strong",[t._v("Implementation notes:")])]),t._v(" "),s("p",[t._v("There are 2 main options for synchronizing to chain on startup:")]),t._v(" "),s("p",[s("strong",[t._v("Full Blocks or BIP 157/158")])]),t._v(" "),s("p",[t._v("If you are connecting full blocks or using BIP 157/158, then it is recommended to use\nLDK's "),s("code",[t._v("lightning_block_sync")]),t._v(" crate as in the example above: the high-level steps that must be done for both "),s("code",[t._v("ChannelManager")]),t._v(" and each "),s("code",[t._v("ChannelMonitor")]),t._v(" are as follows:")]),t._v(" "),s("ol",[s("li",[t._v("Get the last blockhash that each object saw.\n"),s("ul",[s("li",[t._v("Receive the latest block hash when through "),s("a",{attrs:{href:"https://docs.rs/lightning/*/lightning/ln/channelmanager/struct.ChannelManagerReadArgs.html",target:"_blank",rel:"noopener noreferrer"}},[t._v("deserializtion"),s("OutboundLink")],1),t._v(" of the "),s("code",[t._v("ChannelManager")]),t._v(" via "),s("code",[t._v("read()")])]),t._v(" "),s("li",[t._v("Each "),s("code",[t._v("ChannelMonitor")]),t._v("'s is in "),s("code",[t._v("channel_manager.channel_monitors")]),t._v(", as the 2nd element in each tuple")])])]),t._v(" "),s("li",[t._v("For each object, if its latest known blockhash has been reorged out of the chain, then disconnect blocks using "),s("code",[t._v("channel_manager.as_Listen().block_disconnected(..)")]),t._v(" or "),s("code",[t._v("channel_monitor.block_disconnected(..)")]),t._v(" until you reach the last common ancestor with the main chain.")]),t._v(" "),s("li",[t._v("For each object, reconnect blocks starting from the common ancestor until it gets to your best known chain tip using "),s("code",[t._v("channel_manager.as_Listen().block_connected(..)")]),t._v(" and/or "),s("code",[t._v("channel_monitor.block_connected(..)")]),t._v(".")]),t._v(" "),s("li",[t._v("Call "),s("code",[t._v("channel_manager.chain_sync_completed(..)")]),t._v(" to complete the initial sync process.")])]),t._v(" "),s("p",[s("strong",[t._v("Electrum/Esplora")])]),t._v(" "),s("p",[t._v("Alternatively, you can use LDK's "),s("code",[t._v("lightning-transaction-sync")]),t._v(" crate. This provides utilities for syncing LDK via the transaction-based "),s("code",[t._v("Confirm")]),t._v(" interface.")]),t._v(" "),s("h3",{attrs:{id:"optional-initialize-p2pgossipsync-or-rapidgossipsync"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#optional-initialize-p2pgossipsync-or-rapidgossipsync"}},[t._v("#")]),t._v(" Optional: Initialize "),s("code",[t._v("P2PGossipSync or RapidGossipSync")])]),t._v(" "),s("p",[s("strong",[t._v("You must follow this step if:")]),t._v(" you need LDK to provide routes for sending payments (i.e. you are "),s("em",[t._v("not")]),t._v(" providing your own routes)")]),t._v(" "),s("p",[s("strong",[t._v("What it's used for:")]),t._v(" generating routes to send payments over")]),t._v(" "),s("CodeSwitcher",{attrs:{languages:{rust:"Rust",kotlin:"Kotlin",swift:"Swift"}},scopedSlots:t._u([{key:"rust",fn:function(){return[s("div",{staticClass:"language-rust extra-class"},[s("pre",{pre:!0,attrs:{class:"language-rust"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" genesis "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("genesis_block")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Network")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Testnet")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("header"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("block_hash")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" network_graph_path "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token macro property"}},[t._v("format!")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"{}/network_graph"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" ldk_data_dir"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("clone")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" network_graph "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Arc")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("new")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("disk"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("read_network")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Path")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("new")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v("network_graph_path"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" genesis"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" logger"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("clone")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" gossip_sync "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Arc")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("new")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("P2PGossipSync")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("new")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Arc")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("clone")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v("network_graph"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("None")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Arc")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("dyn")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("chain"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Access")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Send")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Sync")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">>")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n logger"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("clone")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])])]},proxy:!0},{key:"kotlin",fn:function(){return[s("div",{staticClass:"language-java extra-class"},[s("pre",{pre:!0,attrs:{class:"language-java"}},[s("code",[t._v("val genesisBlock "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("BestBlock")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("BestBlock")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("from_genesis")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Network"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("LDKNetwork_Testnet")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\nval genesisBlockHash "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("String")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("byteArrayToHex")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("genesisBlock"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("block_hash")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n\nval serializedNetworkGraph "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Read network graph bytes from file")]),t._v("\nval networkGraph "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("NetworkGraph")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("NetworkGraph")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("read")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("serializedNetworkGraph"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" logger"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\nval p2pGossip "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("P2PGossipSync")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("P2PGossipSync")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("of")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("networkGraph"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Option_AccessZ")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("none")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" logger"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n")])])])]},proxy:!0},{key:"swift",fn:function(){return[s("div",{staticClass:"language-Swift extra-class"},[s("pre",{pre:!0,attrs:{class:"language-swift"}},[s("code",[s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// If Network Graph exists, then read from disk")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" serializedNetworkGraph "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Read Network Graph bytes from file")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" readResult "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("NetworkGraph")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("read")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("ser"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" serializedNetworkGraph"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" arg"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" logger"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" readResult"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("isOk")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n netGraph "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" readResult"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("getValue")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("!")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// If Network Graph does not exist, create a new one")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" netGraph "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("NetworkGraph")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("network"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" network"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" logger"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" logger"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Initialise RGS")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" rgs "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("RapidGossipSync")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("networkGraph"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" netGraph"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" logger"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" logger"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" lastSync "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" netGraph"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("getLastRapidGossipSyncTimestamp")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" snapshot "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("getSnapshot")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("lastSyncTimeStamp"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" lastSync"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" timestampSeconds "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("UInt64")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("NSDate")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("timeIntervalSince1970"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" res "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" rgs"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("updateNetworkGraphNoStd")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("updateData"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" snapshot"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" currentTimeUnix"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" timestampSeconds"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" res"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("isOk")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("print")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string-literal"}},[s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"RGS updated"')])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("else")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" snapshot "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("getSnapshot")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("lastSyncTimeStamp"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Use lastSyncTimeStamp as 0 for first Sync")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" timestampSeconds "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("UInt64")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("NSDate")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("timeIntervalSince1970"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" res "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" rgs"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("updateNetworkGraphNoStd")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("updateData"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" snapshot"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" currentTimeUnix"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" timestampSeconds"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" res"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("isOk")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("print")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string-literal"}},[s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"RGS initialized for the first time"')])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Get current snapshot from the RGS Server")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("func")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function-definition function"}},[t._v("getSnapshot")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("lastSyncTimeStamp"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("UInt32")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("UInt8")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Use LDK's RGS Server or use your own Server")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" url"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("URL")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("URL")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("string"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string-literal"}},[s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"https://rapidsync.lightningdevkit.org/snapshot/')]),s("span",{pre:!0,attrs:{class:"token interpolation-punctuation punctuation"}},[t._v("\\(")]),s("span",{pre:!0,attrs:{class:"token interpolation"}},[t._v("lastSyncTimeStamp")]),s("span",{pre:!0,attrs:{class:"token interpolation-punctuation punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"')])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("!")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" data "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Use the url to get the data")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" data "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" data "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("UInt8")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("data"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token nil constant"}},[t._v("nil")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])])]},proxy:!0}])}),t._v(" "),s("p",[s("strong",[t._v("Implementation notes:")]),t._v(" this struct is not required if you are providing your own routes. It will be used internally in "),s("code",[t._v("ChannelManager")]),t._v(" to build a "),s("code",[t._v("NetworkGraph")]),t._v(". Network options include: "),s("code",[t._v("Mainnet")]),t._v(","),s("code",[t._v("Regtest")]),t._v(","),s("code",[t._v("Testnet")]),t._v(","),s("code",[t._v("Signet")])]),t._v(" "),s("p",[s("strong",[t._v("Dependencies:")]),t._v(" "),s("code",[t._v("Logger")])]),t._v(" "),s("p",[s("strong",[t._v("Optional dependency:")]),t._v(" "),s("code",[t._v("Access")]),t._v(", a source of chain information. Recommended to be able to verify channels before adding them to the internal network graph.")]),t._v(" "),s("p",[s("strong",[t._v("References:")]),t._v(" "),s("a",{attrs:{href:"https://docs.rs/lightning/*/lightning/routing/gossip/struct.P2PGossipSync.html",target:"_blank",rel:"noopener noreferrer"}},[t._v("Rust "),s("code",[t._v("P2PGossipSync")]),t._v(" docs"),s("OutboundLink")],1),t._v(", "),s("a",{attrs:{href:"https://docs.rs/lightning/*/lightning/chain/trait.Access.html",target:"_blank",rel:"noopener noreferrer"}},[s("code",[t._v("Access")]),t._v(" docs"),s("OutboundLink")],1),t._v(", "),s("a",{attrs:{href:"https://github.com/lightningdevkit/ldk-garbagecollected/blob/main/src/main/java/org/ldk/structs/P2PGossipSync.java",target:"_blank",rel:"noopener noreferrer"}},[t._v("Java/Kotlin "),s("code",[t._v("P2PGossipSync")]),t._v(" bindings"),s("OutboundLink")],1),t._v(", "),s("a",{attrs:{href:"https://docs.rs/lightning-rapid-gossip-sync/*/lightning_rapid_gossip_sync/",target:"_blank",rel:"noopener noreferrer"}},[t._v("Rust "),s("code",[t._v("RapidGossipSync")]),t._v(" docs"),s("OutboundLink")],1),t._v(", "),s("a",{attrs:{href:"https://github.com/lightningdevkit/ldk-garbagecollected/blob/main/src/main/java/org/ldk/structs/RapidGossipSync.java",target:"_blank",rel:"noopener noreferrer"}},[t._v("Java/Kotlin "),s("code",[t._v("RapidGossipSync")]),t._v(" bindings"),s("OutboundLink")],1)]),t._v(" "),s("h3",{attrs:{id:"optional-initialize-probabilistic-scorer"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#optional-initialize-probabilistic-scorer"}},[t._v("#")]),t._v(" Optional: Initialize "),s("code",[t._v("Probabilistic Scorer")])]),t._v(" "),s("p",[s("strong",[t._v("What it's used for")]),t._v(": to find a suitable payment path to reach the destination.")]),t._v(" "),s("CodeSwitcher",{attrs:{languages:{rust:"Rust",kotlin:"Kotlin",swift:"Swift"}},scopedSlots:t._u([{key:"rust",fn:function(){return[s("div",{staticClass:"language-rust extra-class"},[s("pre",{pre:!0,attrs:{class:"language-rust"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" network_graph_path "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token macro property"}},[t._v("format!")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"{}/network_graph"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" ldk_data_dir"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("clone")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" network_graph "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Arc")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("new")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("disk"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("read_network")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Path")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("new")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v("network_graph_path"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" args"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("network"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" logger"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("clone")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" scorer_path "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token macro property"}},[t._v("format!")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"{}/scorer"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" ldk_data_dir"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("clone")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" scorer "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Arc")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("new")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("RwLock")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("new")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("disk"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("read_scorer")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Path")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("new")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v("scorer_path"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Arc")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("clone")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v("network_graph"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Arc")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("clone")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v("logger"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n")])])])]},proxy:!0},{key:"kotlin",fn:function(){return[s("div",{staticClass:"language-kotlin extra-class"},[s("pre",{pre:!0,attrs:{class:"language-kotlin"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("scorerFile"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("exists")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" scorerReaderResult "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" ProbabilisticScorer"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("read")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("scorerFile"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("readBytes")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" ProbabilisticScoringDecayParameters"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("with_default")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" networkGraph"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" logger"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("scorerReaderResult"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("is_ok"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" probabilisticScorer "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("scorerReaderResult "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("as")]),t._v(" Result_ProbabilisticScorerDecodeErrorZ"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("Result_ProbabilisticScorerDecodeErrorZ_OK"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("res\n scorer "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" MultiThreadedLockableScore"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("of")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("probabilisticScorer"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("as_Score")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n Log"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("i")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("LDKTAG"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string-literal singleline"}},[s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"LDK: Probabilistic Scorer loaded and running"')])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("else")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n Log"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("i")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("LDKTAG"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string-literal singleline"}},[s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"LDK: Couldn\'t load Probabilistic Scorer"')])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" decayParams "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" ProbabilisticScoringDecayParameters"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("with_default")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" probabilisticScorer "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" ProbabilisticScorer"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("of")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("decayParams"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" networkGraph"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" logger"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n scorer "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" MultiThreadedLockableScore"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("of")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("probabilisticScorer"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("as_Score")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n Log"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("i")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("LDKTAG"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string-literal singleline"}},[s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"LDK: Creating a new Probabilistic Scorer"')])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("else")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" decayParams "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" ProbabilisticScoringDecayParameters"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("with_default")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" probabilisticScorer "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" ProbabilisticScorer"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("of")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("decayParams"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" networkGraph"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" logger"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n scorer "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" MultiThreadedLockableScore"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("of")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("probabilisticScorer"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("as_Score")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])])]},proxy:!0},{key:"swift",fn:function(){return[s("div",{staticClass:"language-Swift extra-class"},[s("pre",{pre:!0,attrs:{class:"language-swift"}},[s("code",[s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// If Scorer exists, then read from disk")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" serializedScorer "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Read Scorer bytes from file")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" decayParams "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("ProbabilisticScoringDecayParameters")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("initWithDefault")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" serializedProbabilisticScorer "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("ProbabilisticScorer")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("read")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n ser"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" serializedScorer"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n argA"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" decayParams"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n argB"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" netGraph"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n argC"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" logger\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" res "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" serializedProbabilisticScorer"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("getValue")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" probabilisticScorer "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" res\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" score "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" probabilisticScorer"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("asScore")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Scorer loaded")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" scorer "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("MultiThreadedLockableScore")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("score"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" score"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// If Scorer does not exist, create a new one")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" decayParams "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("ProbabilisticScoringDecayParameters")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("initWithDefault")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" probabilisticScorer "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("ProbabilisticScorer")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n decayParams"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" decayParams"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n networkGraph"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" netGraph"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n logger"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" logger\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" score "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" probabilisticScorer"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("asScore")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Scorer loaded")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" scorer "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("MultiThreadedLockableScore")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("score"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" score"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n")])])])]},proxy:!0}])}),t._v(" "),s("p",[s("strong",[t._v("Dependencies:")]),t._v(" "),s("code",[t._v("NetworkGraph")])]),t._v(" "),s("p",[s("strong",[t._v("References:")]),t._v(" "),s("a",{attrs:{href:"https://docs.rs/lightning/*/lightning/routing/scoring/struct.ProbabilisticScorer.html",target:"_blank",rel:"noopener noreferrer"}},[t._v("Rust "),s("code",[t._v("ProbabilisticScorer")]),t._v(" docs"),s("OutboundLink")],1),t._v(", "),s("a",{attrs:{href:"https://github.com/lightningdevkit/ldk-garbagecollected/blob/main/src/main/java/org/ldk/structs/ProbabilisticScorer.java",target:"_blank",rel:"noopener noreferrer"}},[t._v("Java/Kotlin "),s("code",[t._v("ProbabilisticScorer")]),t._v(" docs"),s("OutboundLink")],1)])],1)}),[],!1,null,null,null);s.default=e.exports}}]); \ No newline at end of file diff --git a/assets/js/53.b24ea71d.js b/assets/js/53.22e640ec.js similarity index 99% rename from assets/js/53.b24ea71d.js rename to assets/js/53.22e640ec.js index 78e996f04..80252fdd1 100644 --- a/assets/js/53.b24ea71d.js +++ b/assets/js/53.22e640ec.js @@ -1 +1 @@ -(window.webpackJsonp=window.webpackJsonp||[]).push([[53],{423:function(e,t,i){"use strict";i.r(t);var o=i(7),a=Object(o.a)({},(function(){var e=this,t=e._self._c;return t("ContentSlotsDistributor",{attrs:{"slot-key":e.$parent.slotKey}},[t("h1",{attrs:{id:"ldk-code-of-conduct"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#ldk-code-of-conduct"}},[e._v("#")]),e._v(" LDK Code of Conduct")]),e._v(" "),t("p",[e._v("The LDK community is open to pretty much anyone. To ensure that project forums such as the Discord server and GitHub repository are open and friendly, we count on maintainers and project representatives to behave in a way that is not disruptive to LDK's culture or to any one participant's well-being.")]),e._v(" "),t("p",[e._v("Therefore, we came up with some easy to follow guidelines.")]),e._v(" "),t("ul",[t("li",[e._v("Be friendly. Interact in a way that fosters openness, inclusivity, and collaboration.")]),e._v(" "),t("li",[e._v("Be respectful. We may disagree, but disagreement is no excuse for rude behavior or personal attacks.")]),e._v(" "),t("li",[e._v("Be considerate. Provide and accept constructive criticism.")])]),e._v(" "),t("p",[e._v("Private or public harassment of any kind will not be tolerated. Since harassment can take many forms, here's a non-exhaustive list of what we consider unacceptable behavior:")]),e._v(" "),t("ul",[t("li",[e._v("Offensive language directed at individuals or groups of people")]),e._v(" "),t("li",[e._v("Bullying (verbal, physical, social, or cyber)")]),e._v(" "),t("li",[e._v("Interfering with someone's ability to contribute, like with excessive nitpicking")]),e._v(" "),t("li",[e._v("Continued one-on-one communication after a party has requested it cease")]),e._v(" "),t("li",[e._v("Stalking online or offline")]),e._v(" "),t("li",[e._v("Doxing or unauthorized publication of private information or communication")]),e._v(" "),t("li",[e._v("Unwelcomed sexual attention")]),e._v(" "),t("li",[e._v("Inappropriate visual displays such as sexually-oriented or offensive photography, cartoons, drawings, or gestures")]),e._v(" "),t("li",[e._v("Retaliation for reporting or threatening to report harassment")])]),e._v(" "),t("p",[e._v("Additionally, spam and other content which disrupts or prevents LDK contributors from working on LDK is not acceptable.")]),e._v(" "),t("h2",{attrs:{id:"the-code-of-conduct-team"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#the-code-of-conduct-team"}},[e._v("#")]),e._v(" The Code of Conduct Team")]),e._v(" "),t("p",[e._v("A small team of LDK contributors has volunteered to enforce the LDK Code of Conduct. If you feel like a community member has engaged in inappropriate behavior, please don't hesitate to contact one of the following LDK contributors via email or on Discord:")]),e._v(" "),t("ul",[t("li",[e._v("Matt Corallo - ldkcocpoc on mattcorallo.com")]),e._v(" "),t("li",[e._v("Val Wallace - vwallace on protonmail.com")]),e._v(" "),t("li",[e._v("Devrandom - devrandom99 on proton.me")])]),e._v(" "),t("h2",{attrs:{id:"the-code-of-conduct-team-s-responsibilities"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#the-code-of-conduct-team-s-responsibilities"}},[e._v("#")]),e._v(" The Code of Conduct Team’s Responsibilities")]),e._v(" "),t("p",[e._v("Team members are tasked with responding to reports within 24 hours. They will review each incident and determine, to the best of their ability:")]),e._v(" "),t("ul",[t("li",[e._v("Does the event constitute a Code of Conduct violation?")]),e._v(" "),t("li",[e._v("Is the behavior on our list of inappropriate behavior? Is it borderline inappropriate?")]),e._v(" "),t("li",[e._v("Did the event occur in a space within our Code of Conduct's scope?\n"),t("ul",[t("li",[e._v("If the incident occurred outside community forums and the individual is seen as a project representative or identifies as an LDK contributor, the incident may be in scope.")]),e._v(" "),t("li",[e._v("Additionally, an incident may be in scope if a community member's ability to contribute to LDK is impacted.")])])]),e._v(" "),t("li",[e._v("Did this incident occur in a private conversation or in a public space?")]),e._v(" "),t("li",[e._v("Is the situation isolated or ongoing?")]),e._v(" "),t("li",[e._v("How is the reported person's behavior negatively impacting others?")]),e._v(" "),t("li",[e._v("Does the incident impact the ability of individuals to freely contribute to LDK?")]),e._v(" "),t("li",[e._v("Does this incident include sexual harassment?")]),e._v(" "),t("li",[e._v("Does this pose a safety risk or severely negatively impact someone's mental health?")]),e._v(" "),t("li",[e._v("Is there a risk of this behavior being repeated?")]),e._v(" "),t("li",[e._v("Does the reported person understand why their behavior was inappropriate?")])]),e._v(" "),t("p",[e._v("If a report is insufficiently detailed or involves multiple parties, the Code of Conduct Team may seek additional information from witnesses or the accused. Neither party should contact the other to discuss the incident. Likewise, the team will do its best not to disclose who reported a given incident, either to the accused or generally, though we recognize that circumstantial disclosures to the accused might be unavoidable.")]),e._v(" "),t("p",[e._v("The Code of Conduct Team aims to resolve all reports within one week. If a resolution is not possible within that time frame, the team will respond to the reporter(s) with an adjusted one.")]),e._v(" "),t("h2",{attrs:{id:"possible-responses-to-an-incident-include"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#possible-responses-to-an-incident-include"}},[e._v("#")]),e._v(" Possible responses to an incident include:")]),e._v(" "),t("h3",{attrs:{id:"taking-no-further-action"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#taking-no-further-action"}},[e._v("#")]),e._v(" Taking no further action:")]),e._v(" "),t("p",[e._v("If the Code of Conduct Team determines that no action is needed, they will inform the reporter.")]),e._v(" "),t("h3",{attrs:{id:"simple-warning"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#simple-warning"}},[e._v("#")]),e._v(" Simple warning:")]),e._v(" "),t("p",[e._v("This applies to disruptive behavior, but not insulting behavior. The Code of Conduct Team will contact the individual(s) and request that they stop.")]),e._v(" "),t("h3",{attrs:{id:"final-warning"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#final-warning"}},[e._v("#")]),e._v(" Final warning:")]),e._v(" "),t("p",[e._v("If an incident or series of incidents creates sustained toxicity within the LDK Community, the Code of Conduct Team will sternly warn the reported party and raise the possibility of further disciplinary action. In addition, they may request that the reported party:")]),e._v(" "),t("ul",[t("li",[e._v("Not use specific language")]),e._v(" "),t("li",[e._v("Not participate in specific types of discussions")]),e._v(" "),t("li",[e._v("Not send private messages to a community member")]),e._v(" "),t("li",[e._v("Not review a particular person's PRs on GitHub (but still allow them to privately share review comments with a maintainer)")]),e._v(" "),t("li",[e._v("Not lead sub-projects like code review sessions")]),e._v(" "),t("li",[e._v("Take a step away for a short period to cool off")]),e._v(" "),t("li",[e._v("Lose maintainer/merge access")])]),e._v(" "),t("h3",{attrs:{id:"2-3-months-imposed-break"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#2-3-months-imposed-break"}},[e._v("#")]),e._v(" 2-3 months imposed break:")]),e._v(" "),t("p",[e._v("If the Code of Conduct Team’s warning goes unheeded, the individual(s) may be asked to avoid participating with the LDK Community on its preferred platforms for several months. After time has passed, the individual(s) will have the option of meeting with the team to discuss returning to the community.")]),e._v(" "),t("h3",{attrs:{id:"extended-or-permanent-ban"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#extended-or-permanent-ban"}},[e._v("#")]),e._v(" Extended or permanent ban:")]),e._v(" "),t("p",[e._v("If a temporary break does not remedy a serious offense, the offender may be removed from the Discord server and Github repository. The Code of Conduct Team may also choose to un-ban a user for a first offense, depending on its severity and pending that the user has offered the offended party a genuine apology.")])])}),[],!1,null,null,null);t.default=a.exports}}]); \ No newline at end of file +(window.webpackJsonp=window.webpackJsonp||[]).push([[53],{419:function(e,t,i){"use strict";i.r(t);var o=i(7),a=Object(o.a)({},(function(){var e=this,t=e._self._c;return t("ContentSlotsDistributor",{attrs:{"slot-key":e.$parent.slotKey}},[t("h1",{attrs:{id:"ldk-code-of-conduct"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#ldk-code-of-conduct"}},[e._v("#")]),e._v(" LDK Code of Conduct")]),e._v(" "),t("p",[e._v("The LDK community is open to pretty much anyone. To ensure that project forums such as the Discord server and GitHub repository are open and friendly, we count on maintainers and project representatives to behave in a way that is not disruptive to LDK's culture or to any one participant's well-being.")]),e._v(" "),t("p",[e._v("Therefore, we came up with some easy to follow guidelines.")]),e._v(" "),t("ul",[t("li",[e._v("Be friendly. Interact in a way that fosters openness, inclusivity, and collaboration.")]),e._v(" "),t("li",[e._v("Be respectful. We may disagree, but disagreement is no excuse for rude behavior or personal attacks.")]),e._v(" "),t("li",[e._v("Be considerate. Provide and accept constructive criticism.")])]),e._v(" "),t("p",[e._v("Private or public harassment of any kind will not be tolerated. Since harassment can take many forms, here's a non-exhaustive list of what we consider unacceptable behavior:")]),e._v(" "),t("ul",[t("li",[e._v("Offensive language directed at individuals or groups of people")]),e._v(" "),t("li",[e._v("Bullying (verbal, physical, social, or cyber)")]),e._v(" "),t("li",[e._v("Interfering with someone's ability to contribute, like with excessive nitpicking")]),e._v(" "),t("li",[e._v("Continued one-on-one communication after a party has requested it cease")]),e._v(" "),t("li",[e._v("Stalking online or offline")]),e._v(" "),t("li",[e._v("Doxing or unauthorized publication of private information or communication")]),e._v(" "),t("li",[e._v("Unwelcomed sexual attention")]),e._v(" "),t("li",[e._v("Inappropriate visual displays such as sexually-oriented or offensive photography, cartoons, drawings, or gestures")]),e._v(" "),t("li",[e._v("Retaliation for reporting or threatening to report harassment")])]),e._v(" "),t("p",[e._v("Additionally, spam and other content which disrupts or prevents LDK contributors from working on LDK is not acceptable.")]),e._v(" "),t("h2",{attrs:{id:"the-code-of-conduct-team"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#the-code-of-conduct-team"}},[e._v("#")]),e._v(" The Code of Conduct Team")]),e._v(" "),t("p",[e._v("A small team of LDK contributors has volunteered to enforce the LDK Code of Conduct. If you feel like a community member has engaged in inappropriate behavior, please don't hesitate to contact one of the following LDK contributors via email or on Discord:")]),e._v(" "),t("ul",[t("li",[e._v("Matt Corallo - ldkcocpoc on mattcorallo.com")]),e._v(" "),t("li",[e._v("Val Wallace - vwallace on protonmail.com")]),e._v(" "),t("li",[e._v("Devrandom - devrandom99 on proton.me")])]),e._v(" "),t("h2",{attrs:{id:"the-code-of-conduct-team-s-responsibilities"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#the-code-of-conduct-team-s-responsibilities"}},[e._v("#")]),e._v(" The Code of Conduct Team’s Responsibilities")]),e._v(" "),t("p",[e._v("Team members are tasked with responding to reports within 24 hours. They will review each incident and determine, to the best of their ability:")]),e._v(" "),t("ul",[t("li",[e._v("Does the event constitute a Code of Conduct violation?")]),e._v(" "),t("li",[e._v("Is the behavior on our list of inappropriate behavior? Is it borderline inappropriate?")]),e._v(" "),t("li",[e._v("Did the event occur in a space within our Code of Conduct's scope?\n"),t("ul",[t("li",[e._v("If the incident occurred outside community forums and the individual is seen as a project representative or identifies as an LDK contributor, the incident may be in scope.")]),e._v(" "),t("li",[e._v("Additionally, an incident may be in scope if a community member's ability to contribute to LDK is impacted.")])])]),e._v(" "),t("li",[e._v("Did this incident occur in a private conversation or in a public space?")]),e._v(" "),t("li",[e._v("Is the situation isolated or ongoing?")]),e._v(" "),t("li",[e._v("How is the reported person's behavior negatively impacting others?")]),e._v(" "),t("li",[e._v("Does the incident impact the ability of individuals to freely contribute to LDK?")]),e._v(" "),t("li",[e._v("Does this incident include sexual harassment?")]),e._v(" "),t("li",[e._v("Does this pose a safety risk or severely negatively impact someone's mental health?")]),e._v(" "),t("li",[e._v("Is there a risk of this behavior being repeated?")]),e._v(" "),t("li",[e._v("Does the reported person understand why their behavior was inappropriate?")])]),e._v(" "),t("p",[e._v("If a report is insufficiently detailed or involves multiple parties, the Code of Conduct Team may seek additional information from witnesses or the accused. Neither party should contact the other to discuss the incident. Likewise, the team will do its best not to disclose who reported a given incident, either to the accused or generally, though we recognize that circumstantial disclosures to the accused might be unavoidable.")]),e._v(" "),t("p",[e._v("The Code of Conduct Team aims to resolve all reports within one week. If a resolution is not possible within that time frame, the team will respond to the reporter(s) with an adjusted one.")]),e._v(" "),t("h2",{attrs:{id:"possible-responses-to-an-incident-include"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#possible-responses-to-an-incident-include"}},[e._v("#")]),e._v(" Possible responses to an incident include:")]),e._v(" "),t("h3",{attrs:{id:"taking-no-further-action"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#taking-no-further-action"}},[e._v("#")]),e._v(" Taking no further action:")]),e._v(" "),t("p",[e._v("If the Code of Conduct Team determines that no action is needed, they will inform the reporter.")]),e._v(" "),t("h3",{attrs:{id:"simple-warning"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#simple-warning"}},[e._v("#")]),e._v(" Simple warning:")]),e._v(" "),t("p",[e._v("This applies to disruptive behavior, but not insulting behavior. The Code of Conduct Team will contact the individual(s) and request that they stop.")]),e._v(" "),t("h3",{attrs:{id:"final-warning"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#final-warning"}},[e._v("#")]),e._v(" Final warning:")]),e._v(" "),t("p",[e._v("If an incident or series of incidents creates sustained toxicity within the LDK Community, the Code of Conduct Team will sternly warn the reported party and raise the possibility of further disciplinary action. In addition, they may request that the reported party:")]),e._v(" "),t("ul",[t("li",[e._v("Not use specific language")]),e._v(" "),t("li",[e._v("Not participate in specific types of discussions")]),e._v(" "),t("li",[e._v("Not send private messages to a community member")]),e._v(" "),t("li",[e._v("Not review a particular person's PRs on GitHub (but still allow them to privately share review comments with a maintainer)")]),e._v(" "),t("li",[e._v("Not lead sub-projects like code review sessions")]),e._v(" "),t("li",[e._v("Take a step away for a short period to cool off")]),e._v(" "),t("li",[e._v("Lose maintainer/merge access")])]),e._v(" "),t("h3",{attrs:{id:"2-3-months-imposed-break"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#2-3-months-imposed-break"}},[e._v("#")]),e._v(" 2-3 months imposed break:")]),e._v(" "),t("p",[e._v("If the Code of Conduct Team’s warning goes unheeded, the individual(s) may be asked to avoid participating with the LDK Community on its preferred platforms for several months. After time has passed, the individual(s) will have the option of meeting with the team to discuss returning to the community.")]),e._v(" "),t("h3",{attrs:{id:"extended-or-permanent-ban"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#extended-or-permanent-ban"}},[e._v("#")]),e._v(" Extended or permanent ban:")]),e._v(" "),t("p",[e._v("If a temporary break does not remedy a serious offense, the offender may be removed from the Discord server and Github repository. The Code of Conduct Team may also choose to un-ban a user for a first offense, depending on its severity and pending that the user has offered the offended party a genuine apology.")])])}),[],!1,null,null,null);t.default=a.exports}}]); \ No newline at end of file diff --git a/assets/js/54.0fafc6dd.js b/assets/js/54.107affef.js similarity index 99% rename from assets/js/54.0fafc6dd.js rename to assets/js/54.107affef.js index e05ec5e39..f5ba68dd8 100644 --- a/assets/js/54.0fafc6dd.js +++ b/assets/js/54.107affef.js @@ -1 +1 @@ -(window.webpackJsonp=window.webpackJsonp||[]).push([[54],{419:function(e,t,a){"use strict";a.r(t);var r=a(7),n=Object(r.a)({},(function(){var e=this,t=e._self._c;return t("ContentSlotsDistributor",{attrs:{"slot-key":e.$parent.slotKey}},[t("h1",{attrs:{id:"examples"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#examples"}},[e._v("#")]),e._v(" Examples")]),e._v(" "),t("p",[e._v("Click the links below and learn from community-built example projects")]),e._v(" "),t("h3",{attrs:{id:"rust-sample-node"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#rust-sample-node"}},[e._v("#")]),e._v(" "),t("a",{attrs:{href:"https://github.com/lightningdevkit/ldk-sample",target:"_blank",rel:"noopener noreferrer"}},[e._v("Rust Sample Node"),t("OutboundLink")],1)]),e._v(" "),t("p",[e._v("This sample serves as a complete reference for constructing a lightning node with\nLDK. This is a good starting point if you want a self-guided tour.")]),e._v(" "),t("h3",{attrs:{id:"kotlinandroid-sample-app"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#kotlinandroid-sample-app"}},[e._v("#")]),e._v(" "),t("a",{attrs:{href:"https://github.com/conorokus/umlando-wallet",target:"_blank",rel:"noopener noreferrer"}},[e._v("Kotlin/Android Sample App"),t("OutboundLink")],1)]),e._v(" "),t("p",[e._v("This sample uses the Kotlin bindings provided by "),t("a",{attrs:{href:"https://github.com/lightningdevkit/ldk-garbagecollected",target:"_blank",rel:"noopener noreferrer"}},[e._v("ldk-garbagecollected"),t("OutboundLink")],1),e._v(" to create a self-custodial mobile lightning wallet on Android.")]),e._v(" "),t("h3",{attrs:{id:"swiftios-sample-app"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#swiftios-sample-app"}},[e._v("#")]),e._v(" "),t("a",{attrs:{href:"https://github.com/Roy0Anonymous/Vajra-Wallet",target:"_blank",rel:"noopener noreferrer"}},[e._v("Swift/iOS Sample App"),t("OutboundLink")],1)]),e._v(" "),t("p",[e._v("This sample uses the Swift bindings provided by "),t("a",{attrs:{href:"https://github.com/lightningdevkit/ldk-swift",target:"_blank",rel:"noopener noreferrer"}},[e._v("ldk-swift"),t("OutboundLink")],1),e._v(" to create a self-custodial mobile lightning wallet on iOS.")]),e._v(" "),t("h3",{attrs:{id:"rust-node-with-sample-lightning-signer-integration"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#rust-node-with-sample-lightning-signer-integration"}},[e._v("#")]),e._v(" "),t("a",{attrs:{href:"https://gitlab.com/lightning-signer/lnrod/",target:"_blank",rel:"noopener noreferrer"}},[e._v("Rust node with sample Lightning Signer integration"),t("OutboundLink")],1)]),e._v(" "),t("p",[e._v("A Rust lightning node implementation based on LDK and the Lightning Signer projects. Aims to be production ready at some point.")]),e._v(" "),t("h3",{attrs:{id:"rust-node-with-sample-tor-integration"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#rust-node-with-sample-tor-integration"}},[e._v("#")]),e._v(" "),t("a",{attrs:{href:"https://github.com/TonyGiorgio/ldk-sample-tor",target:"_blank",rel:"noopener noreferrer"}},[e._v("Rust node with sample Tor integration"),t("OutboundLink")],1)]),e._v(" "),t("p",[e._v("A Rust lightning node sample implementation based on LDK with an embedded Tor daemon.")]),e._v(" "),t("h3",{attrs:{id:"ldk-node"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#ldk-node"}},[e._v("#")]),e._v(" "),t("a",{attrs:{href:"https://github.com/lightningdevkit/ldk-node",target:"_blank",rel:"noopener noreferrer"}},[e._v("LDK Node"),t("OutboundLink")],1)]),e._v(" "),t("p",[e._v("A ready-to-go Lightning node library built using LDK and "),t("a",{attrs:{href:"https://bitcoindevkit.org/",target:"_blank",rel:"noopener noreferrer"}},[e._v("BDK"),t("OutboundLink")],1),e._v(".")]),e._v(" "),t("h3",{attrs:{id:"ldk-node-rust-sample"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#ldk-node-rust-sample"}},[e._v("#")]),e._v(" "),t("a",{attrs:{href:"https://github.com/optout21/ldk-node-sample",target:"_blank",rel:"noopener noreferrer"}},[e._v("LDK Node Rust Sample"),t("OutboundLink")],1)]),e._v(" "),t("p",[e._v("A sample lightning node command-line app built on top of LDK Node (similar to ldk-sample).")]),e._v(" "),t("h3",{attrs:{id:"ldk-node-swift-sample-app"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#ldk-node-swift-sample-app"}},[e._v("#")]),e._v(" "),t("a",{attrs:{href:"https://github.com/reez/Monday/tree/main/LDKNodeMonday",target:"_blank",rel:"noopener noreferrer"}},[e._v("LDK Node Swift Sample App"),t("OutboundLink")],1)]),e._v(" "),t("p",[e._v("This sample uses "),t("a",{attrs:{href:"https://github.com/lightningdevkit/ldk-node/blob/main/Package.swift",target:"_blank",rel:"noopener noreferrer"}},[e._v("ldk-node-swift"),t("OutboundLink")],1),e._v(" bindings to quickly build a self custodial lightning mobile wallet on iOS. Watch the video tutorial "),t("a",{attrs:{href:"https://www.youtube.com/watch?v=rcU3LU6iZCs",target:"_blank",rel:"noopener noreferrer"}},[e._v("here"),t("OutboundLink")],1),e._v(".")]),e._v(" "),t("h3",{attrs:{id:"ldk-node-swift-sample-app-using-bitcoin-design-guide"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#ldk-node-swift-sample-app-using-bitcoin-design-guide"}},[e._v("#")]),e._v(" "),t("a",{attrs:{href:"https://github.com/bdgwallet/dailywallet",target:"_blank",rel:"noopener noreferrer"}},[e._v("LDK Node Swift Sample app using Bitcoin Design Guide"),t("OutboundLink")],1)]),e._v(" "),t("p",[e._v("This sample is a good starting point for building a sample iOS wallet with a strong focus on user experience.")]),e._v(" "),t("h3",{attrs:{id:"ldk-node-flutter-sample-app"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#ldk-node-flutter-sample-app"}},[e._v("#")]),e._v(" "),t("a",{attrs:{href:"https://github.com/LtbLightning/ldk-node-flutter-demo",target:"_blank",rel:"noopener noreferrer"}},[e._v("LDK Node Flutter Sample App"),t("OutboundLink")],1)]),e._v(" "),t("p",[e._v("This sample is a starting point for an LDK Node Flutter app.")]),e._v(" "),t("h3",{attrs:{id:"ldk-node-react-native-sample-app"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#ldk-node-react-native-sample-app"}},[e._v("#")]),e._v(" "),t("a",{attrs:{href:"https://github.com/LtbLightning/ldk-node-rn-demo",target:"_blank",rel:"noopener noreferrer"}},[e._v("LDK Node React Native Sample App"),t("OutboundLink")],1)]),e._v(" "),t("p",[e._v("This sample is a starting point for an LDK Node React Native app.")]),e._v(" "),t("h3",{attrs:{id:"ldk-node-sample-desktop-app"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#ldk-node-sample-desktop-app"}},[e._v("#")]),e._v(" "),t("a",{attrs:{href:"https://github.com/jbesraa/ldk-node-desktop",target:"_blank",rel:"noopener noreferrer"}},[e._v("LDK Node Sample Desktop App"),t("OutboundLink")],1)]),e._v(" "),t("p",[e._v("This sample is a desktop node manager for LDK Node.")])])}),[],!1,null,null,null);t.default=n.exports}}]); \ No newline at end of file +(window.webpackJsonp=window.webpackJsonp||[]).push([[54],{420:function(e,t,a){"use strict";a.r(t);var r=a(7),n=Object(r.a)({},(function(){var e=this,t=e._self._c;return t("ContentSlotsDistributor",{attrs:{"slot-key":e.$parent.slotKey}},[t("h1",{attrs:{id:"examples"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#examples"}},[e._v("#")]),e._v(" Examples")]),e._v(" "),t("p",[e._v("Click the links below and learn from community-built example projects")]),e._v(" "),t("h3",{attrs:{id:"rust-sample-node"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#rust-sample-node"}},[e._v("#")]),e._v(" "),t("a",{attrs:{href:"https://github.com/lightningdevkit/ldk-sample",target:"_blank",rel:"noopener noreferrer"}},[e._v("Rust Sample Node"),t("OutboundLink")],1)]),e._v(" "),t("p",[e._v("This sample serves as a complete reference for constructing a lightning node with\nLDK. This is a good starting point if you want a self-guided tour.")]),e._v(" "),t("h3",{attrs:{id:"kotlinandroid-sample-app"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#kotlinandroid-sample-app"}},[e._v("#")]),e._v(" "),t("a",{attrs:{href:"https://github.com/conorokus/umlando-wallet",target:"_blank",rel:"noopener noreferrer"}},[e._v("Kotlin/Android Sample App"),t("OutboundLink")],1)]),e._v(" "),t("p",[e._v("This sample uses the Kotlin bindings provided by "),t("a",{attrs:{href:"https://github.com/lightningdevkit/ldk-garbagecollected",target:"_blank",rel:"noopener noreferrer"}},[e._v("ldk-garbagecollected"),t("OutboundLink")],1),e._v(" to create a self-custodial mobile lightning wallet on Android.")]),e._v(" "),t("h3",{attrs:{id:"swiftios-sample-app"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#swiftios-sample-app"}},[e._v("#")]),e._v(" "),t("a",{attrs:{href:"https://github.com/Roy0Anonymous/Vajra-Wallet",target:"_blank",rel:"noopener noreferrer"}},[e._v("Swift/iOS Sample App"),t("OutboundLink")],1)]),e._v(" "),t("p",[e._v("This sample uses the Swift bindings provided by "),t("a",{attrs:{href:"https://github.com/lightningdevkit/ldk-swift",target:"_blank",rel:"noopener noreferrer"}},[e._v("ldk-swift"),t("OutboundLink")],1),e._v(" to create a self-custodial mobile lightning wallet on iOS.")]),e._v(" "),t("h3",{attrs:{id:"rust-node-with-sample-lightning-signer-integration"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#rust-node-with-sample-lightning-signer-integration"}},[e._v("#")]),e._v(" "),t("a",{attrs:{href:"https://gitlab.com/lightning-signer/lnrod/",target:"_blank",rel:"noopener noreferrer"}},[e._v("Rust node with sample Lightning Signer integration"),t("OutboundLink")],1)]),e._v(" "),t("p",[e._v("A Rust lightning node implementation based on LDK and the Lightning Signer projects. Aims to be production ready at some point.")]),e._v(" "),t("h3",{attrs:{id:"rust-node-with-sample-tor-integration"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#rust-node-with-sample-tor-integration"}},[e._v("#")]),e._v(" "),t("a",{attrs:{href:"https://github.com/TonyGiorgio/ldk-sample-tor",target:"_blank",rel:"noopener noreferrer"}},[e._v("Rust node with sample Tor integration"),t("OutboundLink")],1)]),e._v(" "),t("p",[e._v("A Rust lightning node sample implementation based on LDK with an embedded Tor daemon.")]),e._v(" "),t("h3",{attrs:{id:"ldk-node"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#ldk-node"}},[e._v("#")]),e._v(" "),t("a",{attrs:{href:"https://github.com/lightningdevkit/ldk-node",target:"_blank",rel:"noopener noreferrer"}},[e._v("LDK Node"),t("OutboundLink")],1)]),e._v(" "),t("p",[e._v("A ready-to-go Lightning node library built using LDK and "),t("a",{attrs:{href:"https://bitcoindevkit.org/",target:"_blank",rel:"noopener noreferrer"}},[e._v("BDK"),t("OutboundLink")],1),e._v(".")]),e._v(" "),t("h3",{attrs:{id:"ldk-node-rust-sample"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#ldk-node-rust-sample"}},[e._v("#")]),e._v(" "),t("a",{attrs:{href:"https://github.com/optout21/ldk-node-sample",target:"_blank",rel:"noopener noreferrer"}},[e._v("LDK Node Rust Sample"),t("OutboundLink")],1)]),e._v(" "),t("p",[e._v("A sample lightning node command-line app built on top of LDK Node (similar to ldk-sample).")]),e._v(" "),t("h3",{attrs:{id:"ldk-node-swift-sample-app"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#ldk-node-swift-sample-app"}},[e._v("#")]),e._v(" "),t("a",{attrs:{href:"https://github.com/reez/Monday/tree/main/LDKNodeMonday",target:"_blank",rel:"noopener noreferrer"}},[e._v("LDK Node Swift Sample App"),t("OutboundLink")],1)]),e._v(" "),t("p",[e._v("This sample uses "),t("a",{attrs:{href:"https://github.com/lightningdevkit/ldk-node/blob/main/Package.swift",target:"_blank",rel:"noopener noreferrer"}},[e._v("ldk-node-swift"),t("OutboundLink")],1),e._v(" bindings to quickly build a self custodial lightning mobile wallet on iOS. Watch the video tutorial "),t("a",{attrs:{href:"https://www.youtube.com/watch?v=rcU3LU6iZCs",target:"_blank",rel:"noopener noreferrer"}},[e._v("here"),t("OutboundLink")],1),e._v(".")]),e._v(" "),t("h3",{attrs:{id:"ldk-node-swift-sample-app-using-bitcoin-design-guide"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#ldk-node-swift-sample-app-using-bitcoin-design-guide"}},[e._v("#")]),e._v(" "),t("a",{attrs:{href:"https://github.com/bdgwallet/dailywallet",target:"_blank",rel:"noopener noreferrer"}},[e._v("LDK Node Swift Sample app using Bitcoin Design Guide"),t("OutboundLink")],1)]),e._v(" "),t("p",[e._v("This sample is a good starting point for building a sample iOS wallet with a strong focus on user experience.")]),e._v(" "),t("h3",{attrs:{id:"ldk-node-flutter-sample-app"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#ldk-node-flutter-sample-app"}},[e._v("#")]),e._v(" "),t("a",{attrs:{href:"https://github.com/LtbLightning/ldk-node-flutter-demo",target:"_blank",rel:"noopener noreferrer"}},[e._v("LDK Node Flutter Sample App"),t("OutboundLink")],1)]),e._v(" "),t("p",[e._v("This sample is a starting point for an LDK Node Flutter app.")]),e._v(" "),t("h3",{attrs:{id:"ldk-node-react-native-sample-app"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#ldk-node-react-native-sample-app"}},[e._v("#")]),e._v(" "),t("a",{attrs:{href:"https://github.com/LtbLightning/ldk-node-rn-demo",target:"_blank",rel:"noopener noreferrer"}},[e._v("LDK Node React Native Sample App"),t("OutboundLink")],1)]),e._v(" "),t("p",[e._v("This sample is a starting point for an LDK Node React Native app.")]),e._v(" "),t("h3",{attrs:{id:"ldk-node-sample-desktop-app"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#ldk-node-sample-desktop-app"}},[e._v("#")]),e._v(" "),t("a",{attrs:{href:"https://github.com/jbesraa/ldk-node-desktop",target:"_blank",rel:"noopener noreferrer"}},[e._v("LDK Node Sample Desktop App"),t("OutboundLink")],1)]),e._v(" "),t("p",[e._v("This sample is a desktop node manager for LDK Node.")])])}),[],!1,null,null,null);t.default=n.exports}}]); \ No newline at end of file diff --git a/assets/js/55.f6576e42.js b/assets/js/55.26a7bb79.js similarity index 94% rename from assets/js/55.f6576e42.js rename to assets/js/55.26a7bb79.js index 05d565e3f..b7c91bf97 100644 --- a/assets/js/55.f6576e42.js +++ b/assets/js/55.26a7bb79.js @@ -1 +1 @@ -(window.webpackJsonp=window.webpackJsonp||[]).push([[55],{421:function(t,n,e){"use strict";e.r(n);var o=e(7),a=Object(o.a)({},(function(){var t=this,n=t._self._c;return n("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[n("h1",{attrs:{id:"blockchain-data"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#blockchain-data"}},[t._v("#")]),t._v(" Blockchain Data")]),t._v(" "),n("p",[t._v("LDK provides a simple "),n("code",[t._v("block_connected")]),t._v("/"),n("code",[t._v("block_disconnected")]),t._v(" API which you pass block headers and transaction information to. LDK also provides an API for getting information about transactions it wishes to be informed of, which is compatible with Electrum server requests/neutrino filtering/etc.")]),t._v(" "),n("p",[n("a",{attrs:{href:"https://lightningdevkit.org/blockchain_data/introduction/",target:"_blank",rel:"noopener noreferrer"}},[t._v("Blockchain Data Guide"),n("OutboundLink")],1)]),t._v(" "),n("p",[n("a",{attrs:{href:"https://github.com/rust-bitcoin/rust-lightning/tree/main/lightning-block-sync",target:"_blank",rel:"noopener noreferrer"}},[t._v("Sample module in Rust"),n("OutboundLink")],1)])])}),[],!1,null,null,null);n.default=a.exports}}]); \ No newline at end of file +(window.webpackJsonp=window.webpackJsonp||[]).push([[55],{423:function(t,n,e){"use strict";e.r(n);var o=e(7),a=Object(o.a)({},(function(){var t=this,n=t._self._c;return n("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[n("h1",{attrs:{id:"blockchain-data"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#blockchain-data"}},[t._v("#")]),t._v(" Blockchain Data")]),t._v(" "),n("p",[t._v("LDK provides a simple "),n("code",[t._v("block_connected")]),t._v("/"),n("code",[t._v("block_disconnected")]),t._v(" API which you pass block headers and transaction information to. LDK also provides an API for getting information about transactions it wishes to be informed of, which is compatible with Electrum server requests/neutrino filtering/etc.")]),t._v(" "),n("p",[n("a",{attrs:{href:"https://lightningdevkit.org/blockchain_data/introduction/",target:"_blank",rel:"noopener noreferrer"}},[t._v("Blockchain Data Guide"),n("OutboundLink")],1)]),t._v(" "),n("p",[n("a",{attrs:{href:"https://github.com/rust-bitcoin/rust-lightning/tree/main/lightning-block-sync",target:"_blank",rel:"noopener noreferrer"}},[t._v("Sample module in Rust"),n("OutboundLink")],1)])])}),[],!1,null,null,null);n.default=a.exports}}]); \ No newline at end of file diff --git a/assets/js/app.7a44e611.js b/assets/js/app.07661de7.js similarity index 77% rename from assets/js/app.7a44e611.js rename to assets/js/app.07661de7.js index 7ee6471c9..d896e4eb0 100644 --- a/assets/js/app.7a44e611.js +++ b/assets/js/app.07661de7.js @@ -1,4 +1,4 @@ -(window.webpackJsonp=window.webpackJsonp||[]).push([[0],[]]);!function(t){function e(e){for(var i,a,c=e[0],s=e[1],l=e[2],u=0,g=[];u
'};function r(t,e,n){return tn?n:t}function o(t){return 100*(-1+t)}n.configure=function(t){var e,n;for(e in t)void 0!==(n=t[e])&&t.hasOwnProperty(e)&&(i[e]=n);return this},n.status=null,n.set=function(t){var e=n.isStarted();t=r(t,i.minimum,1),n.status=1===t?null:t;var s=n.render(!e),l=s.querySelector(i.barSelector),p=i.speed,u=i.easing;return s.offsetWidth,a((function(e){""===i.positionUsing&&(i.positionUsing=n.getPositioningCSS()),c(l,function(t,e,n){var r;return(r="translate3d"===i.positionUsing?{transform:"translate3d("+o(t)+"%,0,0)"}:"translate"===i.positionUsing?{transform:"translate("+o(t)+"%,0)"}:{"margin-left":o(t)+"%"}).transition="all "+e+"ms "+n,r}(t,p,u)),1===t?(c(s,{transition:"none",opacity:1}),s.offsetWidth,setTimeout((function(){c(s,{transition:"all "+p+"ms linear",opacity:0}),setTimeout((function(){n.remove(),e()}),p)}),p)):setTimeout(e,p)})),this},n.isStarted=function(){return"number"==typeof n.status},n.start=function(){n.status||n.set(0);var t=function(){setTimeout((function(){n.status&&(n.trickle(),t())}),i.trickleSpeed)};return i.trickle&&t(),this},n.done=function(t){return t||n.status?n.inc(.3+.5*Math.random()).set(1):this},n.inc=function(t){var e=n.status;return e?("number"!=typeof t&&(t=(1-e)*r(Math.random()*e,.1,.95)),e=r(e+t,0,.994),n.set(e)):n.start()},n.trickle=function(){return n.inc(Math.random()*i.trickleRate)},t=0,e=0,n.promise=function(i){return i&&"resolved"!==i.state()?(0===e&&n.start(),t++,e++,i.always((function(){0==--e?(t=0,n.done()):n.set((t-e)/t)})),this):this},n.render=function(t){if(n.isRendered())return document.getElementById("nprogress");l(document.documentElement,"nprogress-busy");var e=document.createElement("div");e.id="nprogress",e.innerHTML=i.template;var r,a=e.querySelector(i.barSelector),s=t?"-100":o(n.status||0),p=document.querySelector(i.parent);return c(a,{transition:"all 0 linear",transform:"translate3d("+s+"%,0,0)"}),i.showSpinner||(r=e.querySelector(i.spinnerSelector))&&g(r),p!=document.body&&l(p,"nprogress-custom-parent"),p.appendChild(e),e},n.remove=function(){p(document.documentElement,"nprogress-busy"),p(document.querySelector(i.parent),"nprogress-custom-parent");var t=document.getElementById("nprogress");t&&g(t)},n.isRendered=function(){return!!document.getElementById("nprogress")},n.getPositioningCSS=function(){var t=document.body.style,e="WebkitTransform"in t?"Webkit":"MozTransform"in t?"Moz":"msTransform"in t?"ms":"OTransform"in t?"O":"";return e+"Perspective"in t?"translate3d":e+"Transform"in t?"translate":"margin"};var a=function(){var t=[];function e(){var n=t.shift();n&&n(e)}return function(n){t.push(n),1==t.length&&e()}}(),c=function(){var t=["Webkit","O","Moz","ms"],e={};function n(n){return n=n.replace(/^-ms-/,"ms-").replace(/-([\da-z])/gi,(function(t,e){return e.toUpperCase()})),e[n]||(e[n]=function(e){var n=document.body.style;if(e in n)return e;for(var i,r=t.length,o=e.charAt(0).toUpperCase()+e.slice(1);r--;)if((i=t[r]+o)in n)return i;return e}(n))}function i(t,e,i){e=n(e),t.style[e]=i}return function(t,e){var n,r,o=arguments;if(2==o.length)for(n in e)void 0!==(r=e[n])&&e.hasOwnProperty(n)&&i(t,n,r);else i(t,o[1],o[2])}}();function s(t,e){return("string"==typeof t?t:u(t)).indexOf(" "+e+" ")>=0}function l(t,e){var n=u(t),i=n+e;s(n,e)||(t.className=i.substring(1))}function p(t,e){var n,i=u(t);s(t,e)&&(n=i.replace(" "+e+" "," "),t.className=n.substring(1,n.length-1))}function u(t){return(" "+(t.className||"")+" ").replace(/\s+/gi," ")}function g(t){t&&t.parentNode&&t.parentNode.removeChild(t)}return n})?i.call(e,n,e,t):i)||(t.exports=r)},function(t,e){t.exports=function(t){var e=typeof t;return null!=t&&("object"==e||"function"==e)}},function(t,e){t.exports=function(t){return t}},function(t,e,n){"use strict";var i=n(1),r=n(54).f,o=n(13),a=n(106),c=n(34),s=n(70),l=n(136);t.exports=function(t,e){var n,p,u,g,d,h=t.target,f=t.global,m=t.stat;if(n=f?i:m?i[h]||c(h,{}):(i[h]||{}).prototype)for(p in e){if(g=e[p],u=t.dontCallGetSet?(d=r(n,p))&&d.value:n[p],!l(f?p:h+(m?".":"#")+p,t.forced)&&void 0!==u){if(typeof g==typeof u)continue;s(g,u)}(t.sham||u&&u.sham)&&o(g,"sham",!0),a(n,p,g,t)}}},function(t,e,n){"use strict";var i=n(27),r=Function.prototype.call;t.exports=i?r.bind(r):function(){return r.apply(r,arguments)}},function(t,e,n){"use strict";var i=n(3);t.exports=!i((function(){var t=function(){}.bind();return"function"!=typeof t||t.hasOwnProperty("prototype")}))},function(t,e,n){"use strict";t.exports=function(t,e){return{enumerable:!(1&t),configurable:!(2&t),writable:!(4&t),value:e}}},function(t,e,n){"use strict";var i=n(55),r=n(56);t.exports=function(t){return i(r(t))}},function(t,e,n){"use strict";var i=n(1),r=n(0),o=function(t){return r(t)?t:void 0};t.exports=function(t,e){return arguments.length<2?o(i[t]):i[t]&&i[t][e]}},function(t,e,n){"use strict";var i=n(0),r=n(118),o=TypeError;t.exports=function(t){if(i(t))return t;throw o(r(t)+" is not a function")}},function(t,e,n){"use strict";var i=n(1),r=n(65),o=n(8),a=n(67),c=n(63),s=n(62),l=i.Symbol,p=r("wks"),u=s?l.for||l:l&&l.withoutSetter||a;t.exports=function(t){return o(p,t)||(p[t]=c&&o(l,t)?l[t]:u("Symbol."+t)),p[t]}},function(t,e,n){"use strict";var i=n(1),r=n(34),o=i["__core-js_shared__"]||r("__core-js_shared__",{});t.exports=o},function(t,e,n){"use strict";var i=n(1),r=Object.defineProperty;t.exports=function(t,e){try{r(i,t,{value:e,configurable:!0,writable:!0})}catch(n){i[t]=e}return e}},function(t,e,n){"use strict";var i=n(56),r=Object;t.exports=function(t){return r(i(t))}},function(t,e,n){"use strict";var i=n(9),r=String,o=TypeError;t.exports=function(t){if(i(t))return t;throw o(r(t)+" is not an object")}},function(t,e,n){"use strict";var i=n(133);t.exports=function(t){return i(t.length)}},function(t,e,n){var i=n(158),r=n(11),o=Object.prototype,a=o.hasOwnProperty,c=o.propertyIsEnumerable,s=i(function(){return arguments}())?i:function(t){return r(t)&&a.call(t,"callee")&&!c.call(t,"callee")};t.exports=s},function(t,e,n){var i=n(10)(n(6),"Map");t.exports=i},function(t,e,n){var i=n(177),r=n(184),o=n(186),a=n(187),c=n(188);function s(t){var e=-1,n=null==t?0:t.length;for(this.clear();++e-1&&t%1==0&&t<=9007199254740991}},function(t,e,n){var i=n(4),r=n(44),o=/\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\\]|\\.)*?\1)\]/,a=/^\w*$/;t.exports=function(t,e){if(i(t))return!1;var n=typeof t;return!("number"!=n&&"symbol"!=n&&"boolean"!=n&&null!=t&&!r(t))||(a.test(t)||!o.test(t)||null!=e&&t in Object(e))}},function(t,e,n){var i=n(12),r=n(11);t.exports=function(t){return"symbol"==typeof t||r(t)&&"[object Symbol]"==i(t)}},function(t,e,n){t.exports=function(){"use strict";var t=6e4,e=36e5,n="millisecond",i="second",r="minute",o="hour",a="day",c="week",s="month",l="quarter",p="year",u="date",g="Invalid Date",d=/^(\d{4})[-/]?(\d{1,2})?[-/]?(\d{0,2})[Tt\s]*(\d{1,2})?:?(\d{1,2})?:?(\d{1,2})?[.:]?(\d+)?$/,h=/\[([^\]]+)]|Y{1,4}|M{1,4}|D{1,2}|d{1,4}|H{1,2}|h{1,2}|a|A|m{1,2}|s{1,2}|Z{1,2}|SSS/g,f={name:"en",weekdays:"Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_"),months:"January_February_March_April_May_June_July_August_September_October_November_December".split("_"),ordinal:function(t){var e=["th","st","nd","rd"],n=t%100;return"["+t+(e[(n-20)%10]||e[n]||e[0])+"]"}},m=function(t,e,n){var i=String(t);return!i||i.length>=e?t:""+Array(e+1-i.length).join(n)+t},v={s:m,z:function(t){var e=-t.utcOffset(),n=Math.abs(e),i=Math.floor(n/60),r=n%60;return(e<=0?"+":"-")+m(i,2,"0")+":"+m(r,2,"0")},m:function t(e,n){if(e.date()1)return t(a[0])}else{var c=e.name;b[c]=e,r=c}return!i&&r&&(y=r),r||!i&&y},_=function(t,e){if(w(t))return t.clone();var n="object"==typeof e?e:{};return n.date=t,n.args=arguments,new D(n)},L=v;L.l=k,L.i=w,L.w=function(t,e){return _(t,{locale:e.$L,utc:e.$u,x:e.$x,$offset:e.$offset})};var D=function(){function f(t){this.$L=k(t.locale,null,!0),this.parse(t)}var m=f.prototype;return m.parse=function(t){this.$d=function(t){var e=t.date,n=t.utc;if(null===e)return new Date(NaN);if(L.u(e))return new Date;if(e instanceof Date)return new Date(e);if("string"==typeof e&&!/Z$/i.test(e)){var i=e.match(d);if(i){var r=i[2]-1||0,o=(i[7]||"0").substring(0,3);return n?new Date(Date.UTC(i[1],r,i[3]||1,i[4]||0,i[5]||0,i[6]||0,o)):new Date(i[1],r,i[3]||1,i[4]||0,i[5]||0,i[6]||0,o)}}return new Date(e)}(t),this.$x=t.x||{},this.init()},m.init=function(){var t=this.$d;this.$y=t.getFullYear(),this.$M=t.getMonth(),this.$D=t.getDate(),this.$W=t.getDay(),this.$H=t.getHours(),this.$m=t.getMinutes(),this.$s=t.getSeconds(),this.$ms=t.getMilliseconds()},m.$utils=function(){return L},m.isValid=function(){return!(this.$d.toString()===g)},m.isSame=function(t,e){var n=_(t);return this.startOf(e)<=n&&n<=this.endOf(e)},m.isAfter=function(t,e){return _(t)-1&&t%1==0&&t79&&a<83||!o("reduce")},{reduce:function(t){var e=arguments.length;return r(this,t,e,e>1?arguments[1]:void 0)}})},function(t,e,n){"use strict";var i=n(5),r=n(26),o=n(114),a=n(28),c=n(29),s=n(58),l=n(8),p=n(68),u=Object.getOwnPropertyDescriptor;e.f=i?u:function(t,e){if(t=c(t),e=s(e),p)try{return u(t,e)}catch(t){}if(l(t,e))return a(!r(o.f,t,e),t[e])}},function(t,e,n){"use strict";var i=n(2),r=n(3),o=n(17),a=Object,c=i("".split);t.exports=r((function(){return!a("z").propertyIsEnumerable(0)}))?function(t){return"String"===o(t)?c(t,""):a(t)}:a},function(t,e,n){"use strict";var i=n(57),r=TypeError;t.exports=function(t){if(i(t))throw r("Can't call method on "+t);return t}},function(t,e,n){"use strict";t.exports=function(t){return null==t}},function(t,e,n){"use strict";var i=n(115),r=n(60);t.exports=function(t){var e=i(t,"string");return r(e)?e:e+""}},function(t,e,n){"use strict";var i="object"==typeof document&&document.all,r=void 0===i&&void 0!==i;t.exports={all:i,IS_HTMLDDA:r}},function(t,e,n){"use strict";var i=n(30),r=n(0),o=n(61),a=n(62),c=Object;t.exports=a?function(t){return"symbol"==typeof t}:function(t){var e=i("Symbol");return r(e)&&o(e.prototype,c(t))}},function(t,e,n){"use strict";var i=n(2);t.exports=i({}.isPrototypeOf)},function(t,e,n){"use strict";var i=n(63);t.exports=i&&!Symbol.sham&&"symbol"==typeof Symbol.iterator},function(t,e,n){"use strict";var i=n(64),r=n(3),o=n(1).String;t.exports=!!Object.getOwnPropertySymbols&&!r((function(){var t=Symbol("symbol detection");return!o(t)||!(Object(t)instanceof Symbol)||!Symbol.sham&&i&&i<41}))},function(t,e,n){"use strict";var i,r,o=n(1),a=n(116),c=o.process,s=o.Deno,l=c&&c.versions||s&&s.version,p=l&&l.v8;p&&(r=(i=p.split("."))[0]>0&&i[0]<4?1:+(i[0]+i[1])),!r&&a&&(!(i=a.match(/Edge\/(\d+)/))||i[1]>=74)&&(i=a.match(/Chrome\/(\d+)/))&&(r=+i[1]),t.exports=r},function(t,e,n){"use strict";var i=n(66),r=n(33);(t.exports=function(t,e){return r[t]||(r[t]=void 0!==e?e:{})})("versions",[]).push({version:"3.32.2",mode:i?"pure":"global",copyright:"© 2014-2023 Denis Pushkarev (zloirock.ru)",license:"https://github.com/zloirock/core-js/blob/v3.32.2/LICENSE",source:"https://github.com/zloirock/core-js"})},function(t,e,n){"use strict";t.exports=!1},function(t,e,n){"use strict";var i=n(2),r=0,o=Math.random(),a=i(1..toString);t.exports=function(t){return"Symbol("+(void 0===t?"":t)+")_"+a(++r+o,36)}},function(t,e,n){"use strict";var i=n(5),r=n(3),o=n(120);t.exports=!i&&!r((function(){return 7!==Object.defineProperty(o("div"),"a",{get:function(){return 7}}).a}))},function(t,e,n){"use strict";t.exports={}},function(t,e,n){"use strict";var i=n(8),r=n(127),o=n(54),a=n(16);t.exports=function(t,e,n){for(var c=r(e),s=a.f,l=o.f,p=0;pp))return!1;var g=s.get(t),d=s.get(e);if(g&&d)return g==e&&d==t;var h=-1,f=!0,m=2&n?new i:void 0;for(s.set(t,e),s.set(e,t);++h=0&&Math.floor(e)===e&&isFinite(t)}function f(t){return a(t)&&"function"==typeof t.then&&"function"==typeof t.catch}function m(t){return null==t?"":Array.isArray(t)||g(t)&&t.toString===u?JSON.stringify(t,null,2):String(t)}function v(t){var e=parseFloat(t);return isNaN(e)?t:e}function y(t,e){for(var n=Object.create(null),i=t.split(","),r=0;r-1)return t.splice(i,1)}}var k=Object.prototype.hasOwnProperty;function _(t,e){return k.call(t,e)}function L(t){var e=Object.create(null);return function(n){return e[n]||(e[n]=t(n))}}var D=/-(\w)/g,x=L((function(t){return t.replace(D,(function(t,e){return e?e.toUpperCase():""}))})),P=L((function(t){return t.charAt(0).toUpperCase()+t.slice(1)})),C=/\B([A-Z])/g,S=L((function(t){return t.replace(C,"-$1").toLowerCase()}));var K=Function.prototype.bind?function(t,e){return t.bind(e)}:function(t,e){function n(n){var i=arguments.length;return i?i>1?t.apply(e,arguments):t.call(e,n):t.call(e)}return n._length=t.length,n};function O(t,e){e=e||0;for(var n=t.length-e,i=new Array(n);n--;)i[n]=t[n+e];return i}function T(t,e){for(var n in e)t[n]=e[n];return t}function $(t){for(var e={},n=0;n0,X=J&&J.indexOf("edge/")>0;J&&J.indexOf("android");var Q=J&&/iphone|ipad|ipod|ios/.test(J);J&&/chrome\/\d+/.test(J),J&&/phantomjs/.test(J);var tt,et=J&&J.match(/firefox\/(\d+)/),nt={}.watch,it=!1;if(G)try{var rt={};Object.defineProperty(rt,"passive",{get:function(){it=!0}}),window.addEventListener("test-passive",null,rt)}catch(t){}var ot=function(){return void 0===tt&&(tt=!G&&"undefined"!=typeof global&&(global.process&&"server"===global.process.env.VUE_ENV)),tt},at=G&&window.__VUE_DEVTOOLS_GLOBAL_HOOK__;function ct(t){return"function"==typeof t&&/native code/.test(t.toString())}var st,lt="undefined"!=typeof Symbol&&ct(Symbol)&&"undefined"!=typeof Reflect&&ct(Reflect.ownKeys);st="undefined"!=typeof Set&&ct(Set)?Set:function(){function t(){this.set=Object.create(null)}return t.prototype.has=function(t){return!0===this.set[t]},t.prototype.add=function(t){this.set[t]=!0},t.prototype.clear=function(){this.set=Object.create(null)},t}();var pt=null;function ut(t){void 0===t&&(t=null),t||pt&&pt._scope.off(),pt=t,t&&t._scope.on()}var gt=function(){function t(t,e,n,i,r,o,a,c){this.tag=t,this.data=e,this.children=n,this.text=i,this.elm=r,this.ns=void 0,this.context=o,this.fnContext=void 0,this.fnOptions=void 0,this.fnScopeId=void 0,this.key=e&&e.key,this.componentOptions=a,this.componentInstance=void 0,this.parent=void 0,this.raw=!1,this.isStatic=!1,this.isRootInsert=!0,this.isComment=!1,this.isCloned=!1,this.isOnce=!1,this.asyncFactory=c,this.asyncMeta=void 0,this.isAsyncPlaceholder=!1}return Object.defineProperty(t.prototype,"child",{get:function(){return this.componentInstance},enumerable:!1,configurable:!0}),t}(),dt=function(t){void 0===t&&(t="");var e=new gt;return e.text=t,e.isComment=!0,e};function ht(t){return new gt(void 0,void 0,void 0,String(t))}function ft(t){var e=new gt(t.tag,t.data,t.children&&t.children.slice(),t.text,t.elm,t.context,t.componentOptions,t.asyncFactory);return e.ns=t.ns,e.isStatic=t.isStatic,e.key=t.key,e.isComment=t.isComment,e.fnContext=t.fnContext,e.fnOptions=t.fnOptions,e.fnScopeId=t.fnScopeId,e.asyncMeta=t.asyncMeta,e.isCloned=!0,e}var mt=0,vt=[],yt=function(){function t(){this._pending=!1,this.id=mt++,this.subs=[]}return t.prototype.addSub=function(t){this.subs.push(t)},t.prototype.removeSub=function(t){this.subs[this.subs.indexOf(t)]=null,this._pending||(this._pending=!0,vt.push(this))},t.prototype.depend=function(e){t.target&&t.target.addDep(this)},t.prototype.notify=function(t){var e=this.subs.filter((function(t){return t}));for(var n=0,i=e.length;n0&&(Jt((l=t(l,"".concat(n||"","_").concat(i)))[0])&&Jt(u)&&(g[p]=ht(u.text+l[0].text),l.shift()),g.push.apply(g,l)):s(l)?Jt(u)?g[p]=ht(u.text+l):""!==l&&g.push(ht(l)):Jt(l)&&Jt(u)?g[p]=ht(u.text+l.text):(c(e._isVList)&&a(l.tag)&&o(l.key)&&a(n)&&(l.key="__vlist".concat(n,"_").concat(i,"__")),g.push(l)));return g}(t):void 0}function Jt(t){return a(t)&&a(t.text)&&!1===t.isComment}function Zt(t,e){var n,i,o,c,s=null;if(r(t)||"string"==typeof t)for(s=new Array(t.length),n=0,i=t.length;n0,c=e?!!e.$stable:!a,s=e&&e.$key;if(e){if(e._normalized)return e._normalized;if(c&&r&&r!==i&&s===r.$key&&!a&&!r.$hasNormal)return r;for(var l in o={},e)e[l]&&"$"!==l[0]&&(o[l]=fe(t,n,l,e[l]))}else o={};for(var p in n)p in o||(o[p]=me(n,p));return e&&Object.isExtensible(e)&&(e._normalized=o),W(o,"$stable",c),W(o,"$key",s),W(o,"$hasNormal",a),o}function fe(t,e,n,i){var o=function(){var e=pt;ut(t);var n=arguments.length?i.apply(null,arguments):i({}),o=(n=n&&"object"==typeof n&&!r(n)?[n]:Gt(n))&&n[0];return ut(e),n&&(!o||1===n.length&&o.isComment&&!de(o))?void 0:n};return i.proxy&&Object.defineProperty(e,n,{get:o,enumerable:!0,configurable:!0}),o}function me(t,e){return function(){return t[e]}}function ve(t){return{get attrs(){if(!t._attrsProxy){var e=t._attrsProxy={};W(e,"_v_attr_proxy",!0),ye(e,t.$attrs,i,t,"$attrs")}return t._attrsProxy},get listeners(){t._listenersProxy||ye(t._listenersProxy={},t.$listeners,i,t,"$listeners");return t._listenersProxy},get slots(){return function(t){t._slotsProxy||we(t._slotsProxy={},t.$scopedSlots);return t._slotsProxy}(t)},emit:K(t.$emit,t),expose:function(e){e&&Object.keys(e).forEach((function(n){return Rt(t,e,n)}))}}}function ye(t,e,n,i,r){var o=!1;for(var a in e)a in t?e[a]!==n[a]&&(o=!0):(o=!0,be(t,a,i,r));for(var a in t)a in e||(o=!0,delete t[a]);return o}function be(t,e,n,i){Object.defineProperty(t,e,{enumerable:!0,configurable:!0,get:function(){return n[i][e]}})}function we(t,e){for(var n in e)t[n]=e[n];for(var n in t)n in e||delete t[n]}var ke=null;function _e(t,e){return(t.__esModule||lt&&"Module"===t[Symbol.toStringTag])&&(t=t.default),p(t)?e.extend(t):t}function Le(t){if(r(t))for(var e=0;edocument.createEvent("Event").timeStamp&&(sn=function(){return ln.now()})}var pn=function(t,e){if(t.post){if(!e.post)return 1}else if(e.post)return-1;return t.id-e.id};function un(){var t,e;for(cn=sn(),on=!0,tn.sort(pn),an=0;anan&&tn[n].id>t.id;)n--;tn.splice(n+1,0,t)}else tn.push(t);rn||(rn=!0,Fe(un))}}function dn(t,e){if(t){for(var n=Object.create(null),i=lt?Reflect.ownKeys(t):Object.keys(t),r=0;r-1)if(o&&!_(r,"default"))a=!1;else if(""===a||a===S(t)){var s=An(String,r.type);(s<0||c-1:"string"==typeof t?t.split(",").indexOf(e)>-1:!!d(t)&&t.test(e)}function Zn(t,e){var n=t.cache,i=t.keys,r=t._vnode;for(var o in n){var a=n[o];if(a){var c=a.name;c&&!e(c)&&Yn(n,o,i,r)}}}function Yn(t,e,n,i){var r=t[e];!r||i&&r.tag===i.tag||r.componentInstance.$destroy(),t[e]=null,w(n,e)}Hn.prototype._init=function(t){var e=this;e._uid=qn++,e._isVue=!0,e.__v_skip=!0,e._scope=new It(!0),e._scope._vm=!0,t&&t._isComponent?function(t,e){var n=t.$options=Object.create(t.constructor.options),i=e._parentVnode;n.parent=e.parent,n._parentVnode=i;var r=i.componentOptions;n.propsData=r.propsData,n._parentListeners=r.listeners,n._renderChildren=r.children,n._componentTag=r.tag,e.render&&(n.render=e.render,n.staticRenderFns=e.staticRenderFns)}(e,t):e.$options=Kn(Wn(e.constructor),t||{},e),e._renderProxy=e,e._self=e,function(t){var e=t.$options,n=e.parent;if(n&&!e.abstract){for(;n.$options.abstract&&n.$parent;)n=n.$parent;n.$children.push(t)}t.$parent=n,t.$root=n?n.$root:t,t.$children=[],t.$refs={},t._provided=n?n._provided:Object.create(null),t._watcher=null,t._inactive=null,t._directInactive=!1,t._isMounted=!1,t._isDestroyed=!1,t._isBeingDestroyed=!1}(e),function(t){t._events=Object.create(null),t._hasHookEvent=!1;var e=t.$options._parentListeners;e&&Ge(t,e)}(e),function(t){t._vnode=null,t._staticTrees=null;var e=t.$options,n=t.$vnode=e._parentVnode,r=n&&n.context;t.$slots=ue(e._renderChildren,r),t.$scopedSlots=n?he(t.$parent,n.data.scopedSlots,t.$slots):i,t._c=function(e,n,i,r){return De(t,e,n,i,r,!1)},t.$createElement=function(e,n,i,r){return De(t,e,n,i,r,!0)};var o=n&&n.data;Tt(t,"$attrs",o&&o.attrs||i,null,!0),Tt(t,"$listeners",e._parentListeners||i,null,!0)}(e),Qe(e,"beforeCreate",void 0,!1),function(t){var e=dn(t.$options.inject,t);e&&(Ct(!1),Object.keys(e).forEach((function(n){Tt(t,n,e[n])})),Ct(!0))}(e),Fn(e),function(t){var e=t.$options.provide;if(e){var n=l(e)?e.call(t):e;if(!p(n))return;for(var i=Ut(t),r=lt?Reflect.ownKeys(n):Object.keys(n),o=0;o1?O(n):n;for(var i=O(arguments,1),r='event handler for "'.concat(t,'"'),o=0,a=n.length;oparseInt(this.max)&&Yn(t,e[0],e,this._vnode),this.vnodeToCache=null}}},created:function(){this.cache=Object.create(null),this.keys=[]},destroyed:function(){for(var t in this.cache)Yn(this.cache,t,this.keys)},mounted:function(){var t=this;this.cacheVNode(),this.$watch("include",(function(e){Zn(t,(function(t){return Jn(e,t)}))})),this.$watch("exclude",(function(e){Zn(t,(function(t){return!Jn(e,t)}))}))},updated:function(){this.cacheVNode()},render:function(){var t=this.$slots.default,e=Le(t),n=e&&e.componentOptions;if(n){var i=Gn(n),r=this.include,o=this.exclude;if(r&&(!i||!Jn(r,i))||o&&i&&Jn(o,i))return e;var a=this.cache,c=this.keys,s=null==e.key?n.Ctor.cid+(n.tag?"::".concat(n.tag):""):e.key;a[s]?(e.componentInstance=a[s].componentInstance,w(c,s),c.push(s)):(this.vnodeToCache=e,this.keyToCache=s),e.data.keepAlive=!0}return e||t&&t[0]}}};!function(t){var e={get:function(){return U}};Object.defineProperty(t,"config",e),t.util={warn:_n,extend:T,mergeOptions:Kn,defineReactive:Tt},t.set=$t,t.delete=Et,t.nextTick=Fe,t.observable=function(t){return Ot(t),t},t.options=Object.create(null),N.forEach((function(e){t.options[e+"s"]=Object.create(null)})),t.options._base=t,T(t.options.components,Qn),function(t){t.use=function(t){var e=this._installedPlugins||(this._installedPlugins=[]);if(e.indexOf(t)>-1)return this;var n=O(arguments,1);return n.unshift(this),l(t.install)?t.install.apply(t,n):l(t)&&t.apply(null,n),e.push(t),this}}(t),function(t){t.mixin=function(t){return this.options=Kn(this.options,t),this}}(t),Vn(t),function(t){N.forEach((function(e){t[e]=function(t,n){return n?("component"===e&&g(n)&&(n.name=n.name||t,n=this.options._base.extend(n)),"directive"===e&&l(n)&&(n={bind:n,update:n}),this.options[e+"s"][t]=n,n):this.options[e+"s"][t]}}))}(t)}(Hn),Object.defineProperty(Hn.prototype,"$isServer",{get:ot}),Object.defineProperty(Hn.prototype,"$ssrContext",{get:function(){return this.$vnode&&this.$vnode.ssrContext}}),Object.defineProperty(Hn,"FunctionalRenderContext",{value:hn}),Hn.version="2.7.14";var ti=y("style,class"),ei=y("input,textarea,option,select,progress"),ni=y("contenteditable,draggable,spellcheck"),ii=y("events,caret,typing,plaintext-only"),ri=y("allowfullscreen,async,autofocus,autoplay,checked,compact,controls,declare,default,defaultchecked,defaultmuted,defaultselected,defer,disabled,enabled,formnovalidate,hidden,indeterminate,inert,ismap,itemscope,loop,multiple,muted,nohref,noresize,noshade,novalidate,nowrap,open,pauseonexit,readonly,required,reversed,scoped,seamless,selected,sortable,truespeed,typemustmatch,visible"),oi="http://www.w3.org/1999/xlink",ai=function(t){return":"===t.charAt(5)&&"xlink"===t.slice(0,5)},ci=function(t){return ai(t)?t.slice(6,t.length):""},si=function(t){return null==t||!1===t};function li(t){for(var e=t.data,n=t,i=t;a(i.componentInstance);)(i=i.componentInstance._vnode)&&i.data&&(e=pi(i.data,e));for(;a(n=n.parent);)n&&n.data&&(e=pi(e,n.data));return function(t,e){if(a(t)||a(e))return ui(t,gi(e));return""}(e.staticClass,e.class)}function pi(t,e){return{staticClass:ui(t.staticClass,e.staticClass),class:a(t.class)?[t.class,e.class]:e.class}}function ui(t,e){return t?e?t+" "+e:t:e||""}function gi(t){return Array.isArray(t)?function(t){for(var e,n="",i=0,r=t.length;i-1?ji(t,e,n):ri(e)?si(n)?t.removeAttribute(e):(n="allowfullscreen"===e&&"EMBED"===t.tagName?"true":e,t.setAttribute(e,n)):ni(e)?t.setAttribute(e,function(t,e){return si(e)||"false"===e?"false":"contenteditable"===t&&ii(e)?e:"true"}(e,n)):ai(e)?si(n)?t.removeAttributeNS(oi,ci(e)):t.setAttributeNS(oi,e,n):ji(t,e,n)}function ji(t,e,n){if(si(n))t.removeAttribute(e);else{if(Z&&!Y&&"TEXTAREA"===t.tagName&&"placeholder"===e&&""!==n&&!t.__ieph){var i=function(e){e.stopImmediatePropagation(),t.removeEventListener("input",i)};t.addEventListener("input",i),t.__ieph=!0}t.setAttribute(e,n)}}var Bi={create:Mi,update:Mi};function Fi(t,e){var n=e.elm,i=e.data,r=t.data;if(!(o(i.staticClass)&&o(i.class)&&(o(r)||o(r.staticClass)&&o(r.class)))){var c=li(e),s=n._transitionClasses;a(s)&&(c=ui(c,gi(s))),c!==n._prevClass&&(n.setAttribute("class",c),n._prevClass=c)}}var Ri,Ni={create:Fi,update:Fi};function Ii(t,e,n){var i=Ri;return function r(){var o=e.apply(null,arguments);null!==o&&qi(t,r,n,i)}}var Ui=Oe&&!(et&&Number(et[1])<=53);function zi(t,e,n,i){if(Ui){var r=cn,o=e;e=o._wrapper=function(t){if(t.target===t.currentTarget||t.timeStamp>=r||t.timeStamp<=0||t.target.ownerDocument!==document)return o.apply(this,arguments)}}Ri.addEventListener(t,e,it?{capture:n,passive:i}:n)}function qi(t,e,n,i){(i||Ri).removeEventListener(t,e._wrapper||e,n)}function Wi(t,e){if(!o(t.data.on)||!o(e.data.on)){var n=e.data.on||{},i=t.data.on||{};Ri=e.elm||t.elm,function(t){if(a(t.__r)){var e=Z?"change":"input";t[e]=[].concat(t.__r,t[e]||[]),delete t.__r}a(t.__c)&&(t.change=[].concat(t.__c,t.change||[]),delete t.__c)}(n),Wt(n,i,zi,qi,Ii,e.context),Ri=void 0}}var Hi,Vi={create:Wi,update:Wi,destroy:function(t){return Wi(t,Li)}};function Gi(t,e){if(!o(t.data.domProps)||!o(e.data.domProps)){var n,i,r=e.elm,s=t.data.domProps||{},l=e.data.domProps||{};for(n in(a(l.__ob__)||c(l._v_attr_proxy))&&(l=e.data.domProps=T({},l)),s)n in l||(r[n]="");for(n in l){if(i=l[n],"textContent"===n||"innerHTML"===n){if(e.children&&(e.children.length=0),i===s[n])continue;1===r.childNodes.length&&r.removeChild(r.childNodes[0])}if("value"===n&&"PROGRESS"!==r.tagName){r._value=i;var p=o(i)?"":String(i);Ji(r,p)&&(r.value=p)}else if("innerHTML"===n&&fi(r.tagName)&&o(r.innerHTML)){(Hi=Hi||document.createElement("div")).innerHTML="".concat(i,"");for(var u=Hi.firstChild;r.firstChild;)r.removeChild(r.firstChild);for(;u.firstChild;)r.appendChild(u.firstChild)}else if(i!==s[n])try{r[n]=i}catch(t){}}}}function Ji(t,e){return!t.composing&&("OPTION"===t.tagName||function(t,e){var n=!0;try{n=document.activeElement!==t}catch(t){}return n&&t.value!==e}(t,e)||function(t,e){var n=t.value,i=t._vModifiers;if(a(i)){if(i.number)return v(n)!==v(e);if(i.trim)return n.trim()!==e.trim()}return n!==e}(t,e))}var Zi={create:Gi,update:Gi},Yi=L((function(t){var e={},n=/:(.+)/;return t.split(/;(?![^(]*\))/g).forEach((function(t){if(t){var i=t.split(n);i.length>1&&(e[i[0].trim()]=i[1].trim())}})),e}));function Xi(t){var e=Qi(t.style);return t.staticStyle?T(t.staticStyle,e):e}function Qi(t){return Array.isArray(t)?$(t):"string"==typeof t?Yi(t):t}var tr,er=/^--/,nr=/\s*!important$/,ir=function(t,e,n){if(er.test(e))t.style.setProperty(e,n);else if(nr.test(n))t.style.setProperty(S(e),n.replace(nr,""),"important");else{var i=or(e);if(Array.isArray(n))for(var r=0,o=n.length;r-1?e.split(sr).forEach((function(e){return t.classList.add(e)})):t.classList.add(e);else{var n=" ".concat(t.getAttribute("class")||""," ");n.indexOf(" "+e+" ")<0&&t.setAttribute("class",(n+e).trim())}}function pr(t,e){if(e&&(e=e.trim()))if(t.classList)e.indexOf(" ")>-1?e.split(sr).forEach((function(e){return t.classList.remove(e)})):t.classList.remove(e),t.classList.length||t.removeAttribute("class");else{for(var n=" ".concat(t.getAttribute("class")||""," "),i=" "+e+" ";n.indexOf(i)>=0;)n=n.replace(i," ");(n=n.trim())?t.setAttribute("class",n):t.removeAttribute("class")}}function ur(t){if(t){if("object"==typeof t){var e={};return!1!==t.css&&T(e,gr(t.name||"v")),T(e,t),e}return"string"==typeof t?gr(t):void 0}}var gr=L((function(t){return{enterClass:"".concat(t,"-enter"),enterToClass:"".concat(t,"-enter-to"),enterActiveClass:"".concat(t,"-enter-active"),leaveClass:"".concat(t,"-leave"),leaveToClass:"".concat(t,"-leave-to"),leaveActiveClass:"".concat(t,"-leave-active")}})),dr=G&&!Y,hr="transition",fr="transitionend",mr="animation",vr="animationend";dr&&(void 0===window.ontransitionend&&void 0!==window.onwebkittransitionend&&(hr="WebkitTransition",fr="webkitTransitionEnd"),void 0===window.onanimationend&&void 0!==window.onwebkitanimationend&&(mr="WebkitAnimation",vr="webkitAnimationEnd"));var yr=G?window.requestAnimationFrame?window.requestAnimationFrame.bind(window):setTimeout:function(t){return t()};function br(t){yr((function(){yr(t)}))}function wr(t,e){var n=t._transitionClasses||(t._transitionClasses=[]);n.indexOf(e)<0&&(n.push(e),lr(t,e))}function kr(t,e){t._transitionClasses&&w(t._transitionClasses,e),pr(t,e)}function _r(t,e,n){var i=Dr(t,e),r=i.type,o=i.timeout,a=i.propCount;if(!r)return n();var c="transition"===r?fr:vr,s=0,l=function(){t.removeEventListener(c,p),n()},p=function(e){e.target===t&&++s>=a&&l()};setTimeout((function(){s0&&(n="transition",p=a,u=o.length):"animation"===e?l>0&&(n="animation",p=l,u=s.length):u=(n=(p=Math.max(a,l))>0?a>l?"transition":"animation":null)?"transition"===n?o.length:s.length:0,{type:n,timeout:p,propCount:u,hasTransform:"transition"===n&&Lr.test(i[hr+"Property"])}}function xr(t,e){for(;t.length1}function Tr(t,e){!0!==e.data.show&&Cr(e)}var $r=function(t){var e,n,i={},l=t.modules,p=t.nodeOps;for(e=0;eh?w(t,o(n[v+1])?null:n[v+1].elm,n,d,v,i):d>v&&_(e,u,h)}(u,f,v,n,l):a(v)?(a(t.text)&&p.setTextContent(u,""),w(u,null,v,0,v.length-1,n)):a(f)?_(f,0,f.length-1):a(t.text)&&p.setTextContent(u,""):t.text!==e.text&&p.setTextContent(u,e.text),a(h)&&a(d=h.hook)&&a(d=d.postpatch)&&d(t,e)}}}function P(t,e,n){if(c(n)&&a(t.parent))t.parent.data.pendingInsert=e;else for(var i=0;i-1,a.selected!==o&&(a.selected=o);else if(j(Br(a),i))return void(t.selectedIndex!==c&&(t.selectedIndex=c));r||(t.selectedIndex=-1)}}function jr(t,e){return e.every((function(e){return!j(e,t)}))}function Br(t){return"_value"in t?t._value:t.value}function Fr(t){t.target.composing=!0}function Rr(t){t.target.composing&&(t.target.composing=!1,Nr(t.target,"input"))}function Nr(t,e){var n=document.createEvent("HTMLEvents");n.initEvent(e,!0,!0),t.dispatchEvent(n)}function Ir(t){return!t.componentInstance||t.data&&t.data.transition?t:Ir(t.componentInstance._vnode)}var Ur={model:Er,show:{bind:function(t,e,n){var i=e.value,r=(n=Ir(n)).data&&n.data.transition,o=t.__vOriginalDisplay="none"===t.style.display?"":t.style.display;i&&r?(n.data.show=!0,Cr(n,(function(){t.style.display=o}))):t.style.display=i?o:"none"},update:function(t,e,n){var i=e.value;!i!=!e.oldValue&&((n=Ir(n)).data&&n.data.transition?(n.data.show=!0,i?Cr(n,(function(){t.style.display=t.__vOriginalDisplay})):Sr(n,(function(){t.style.display="none"}))):t.style.display=i?t.__vOriginalDisplay:"none")},unbind:function(t,e,n,i,r){r||(t.style.display=t.__vOriginalDisplay)}}},zr={name:String,appear:Boolean,css:Boolean,mode:String,type:String,enterClass:String,leaveClass:String,enterToClass:String,leaveToClass:String,enterActiveClass:String,leaveActiveClass:String,appearClass:String,appearActiveClass:String,appearToClass:String,duration:[Number,String,Object]};function qr(t){var e=t&&t.componentOptions;return e&&e.Ctor.options.abstract?qr(Le(e.children)):t}function Wr(t){var e={},n=t.$options;for(var i in n.propsData)e[i]=t[i];var r=n._parentListeners;for(var i in r)e[x(i)]=r[i];return e}function Hr(t,e){if(/\d-keep-alive$/.test(e.tag))return t("keep-alive",{props:e.componentOptions.propsData})}var Vr=function(t){return t.tag||de(t)},Gr=function(t){return"show"===t.name},Jr={name:"transition",props:zr,abstract:!0,render:function(t){var e=this,n=this.$slots.default;if(n&&(n=n.filter(Vr)).length){0;var i=this.mode;0;var r=n[0];if(function(t){for(;t=t.parent;)if(t.data.transition)return!0}(this.$vnode))return r;var o=qr(r);if(!o)return r;if(this._leaving)return Hr(t,r);var a="__transition-".concat(this._uid,"-");o.key=null==o.key?o.isComment?a+"comment":a+o.tag:s(o.key)?0===String(o.key).indexOf(a)?o.key:a+o.key:o.key;var c=(o.data||(o.data={})).transition=Wr(this),l=this._vnode,p=qr(l);if(o.data.directives&&o.data.directives.some(Gr)&&(o.data.show=!0),p&&p.data&&!function(t,e){return e.key===t.key&&e.tag===t.tag}(o,p)&&!de(p)&&(!p.componentInstance||!p.componentInstance._vnode.isComment)){var u=p.data.transition=T({},c);if("out-in"===i)return this._leaving=!0,Ht(u,"afterLeave",(function(){e._leaving=!1,e.$forceUpdate()})),Hr(t,r);if("in-out"===i){if(de(o))return l;var g,d=function(){g()};Ht(c,"afterEnter",d),Ht(c,"enterCancelled",d),Ht(u,"delayLeave",(function(t){g=t}))}}return r}}},Zr=T({tag:String,moveClass:String},zr);function Yr(t){t.elm._moveCb&&t.elm._moveCb(),t.elm._enterCb&&t.elm._enterCb()}function Xr(t){t.data.newPos=t.elm.getBoundingClientRect()}function Qr(t){var e=t.data.pos,n=t.data.newPos,i=e.left-n.left,r=e.top-n.top;if(i||r){t.data.moved=!0;var o=t.elm.style;o.transform=o.WebkitTransform="translate(".concat(i,"px,").concat(r,"px)"),o.transitionDuration="0s"}}delete Zr.mode;var to={Transition:Jr,TransitionGroup:{props:Zr,beforeMount:function(){var t=this,e=this._update;this._update=function(n,i){var r=Ze(t);t.__patch__(t._vnode,t.kept,!1,!0),t._vnode=t.kept,r(),e.call(t,n,i)}},render:function(t){for(var e=this.tag||this.$vnode.data.tag||"span",n=Object.create(null),i=this.prevChildren=this.children,r=this.$slots.default||[],o=this.children=[],a=Wr(this),c=0;c-1?vi[t]=e.constructor===window.HTMLUnknownElement||e.constructor===window.HTMLElement:vi[t]=/HTMLUnknownElement/.test(e.toString())},T(Hn.options.directives,Ur),T(Hn.options.components,to),Hn.prototype.__patch__=G?$r:E,Hn.prototype.$mount=function(t,e){return function(t,e,n){var i;t.$el=e,t.$options.render||(t.$options.render=dt),Qe(t,"beforeMount"),i=function(){t._update(t._render(),n)},new qe(t,i,E,{before:function(){t._isMounted&&!t._isDestroyed&&Qe(t,"beforeUpdate")}},!0),n=!1;var r=t._preWatchers;if(r)for(var o=0;o=0&&(e=t.slice(i),t=t.slice(0,i));var r=t.indexOf("?");return r>=0&&(n=t.slice(r+1),t=t.slice(0,r)),{path:t,query:n,hash:e}}(r.path||""),l=e&&e.path||"/",p=s.path?_o(s.path,l,n||r.append):l,u=function(t,e,n){void 0===e&&(e={});var i,r=n||so;try{i=r(t||"")}catch(t){i={}}for(var o in e){var a=e[o];i[o]=Array.isArray(a)?a.map(co):co(a)}return i}(s.query,r.query,i&&i.options.parseQuery),g=r.hash||s.hash;return g&&"#"!==g.charAt(0)&&(g="#"+g),{_normalized:!0,path:p,query:u,hash:g}}var zo,qo=function(){},Wo={name:"RouterLink",props:{to:{type:[String,Object],required:!0},tag:{type:String,default:"a"},custom:Boolean,exact:Boolean,exactPath:Boolean,append:Boolean,replace:Boolean,activeClass:String,exactActiveClass:String,ariaCurrentValue:{type:String,default:"page"},event:{type:[String,Array],default:"click"}},render:function(t){var e=this,n=this.$router,i=this.$route,r=n.resolve(this.to,i,this.append),o=r.location,a=r.route,c=r.href,s={},l=n.options.linkActiveClass,p=n.options.linkExactActiveClass,u=null==l?"router-link-active":l,g=null==p?"router-link-exact-active":p,d=null==this.activeClass?u:this.activeClass,h=null==this.exactActiveClass?g:this.exactActiveClass,f=a.redirectedFrom?uo(null,Uo(a.redirectedFrom),null,n):a;s[h]=vo(i,f,this.exactPath),s[d]=this.exact||this.exactPath?s[h]:function(t,e){return 0===t.path.replace(po,"/").indexOf(e.path.replace(po,"/"))&&(!e.hash||t.hash===e.hash)&&function(t,e){for(var n in e)if(!(n in t))return!1;return!0}(t.query,e.query)}(i,f);var m=s[h]?this.ariaCurrentValue:null,v=function(t){Ho(t)&&(e.replace?n.replace(o,qo):n.push(o,qo))},y={click:Ho};Array.isArray(this.event)?this.event.forEach((function(t){y[t]=v})):y[this.event]=v;var b={class:s},w=!this.$scopedSlots.$hasNormal&&this.$scopedSlots.default&&this.$scopedSlots.default({href:c,route:a,navigate:v,isActive:s[d],isExactActive:s[h]});if(w){if(1===w.length)return w[0];if(w.length>1||!w.length)return 0===w.length?t():t("span",{},w)}if("a"===this.tag)b.on=y,b.attrs={href:c,"aria-current":m};else{var k=function t(e){var n;if(e)for(var i=0;i-1&&(c.params[g]=n.params[g]);return c.path=Io(p.path,c.params),s(p,c,a)}if(c.path){c.params={};for(var d=0;d-1}function La(t,e){return _a(t)&&t._isRouter&&(null==e||t.type===e)}function Da(t,e,n){var i=function(r){r>=t.length?n():t[r]?e(t[r],(function(){i(r+1)})):i(r+1)};i(0)}function xa(t){return function(e,n,i){var r=!1,o=0,a=null;Pa(t,(function(t,e,n,c){if("function"==typeof t&&void 0===t.cid){r=!0,o++;var s,l=Ka((function(e){var r;((r=e).__esModule||Sa&&"Module"===r[Symbol.toStringTag])&&(e=e.default),t.resolved="function"==typeof e?e:zo.extend(e),n.components[c]=e,--o<=0&&i()})),p=Ka((function(t){var e="Failed to resolve async component "+c+": "+t;a||(a=_a(t)?t:new Error(e),i(a))}));try{s=t(l,p)}catch(t){p(t)}if(s)if("function"==typeof s.then)s.then(l,p);else{var u=s.component;u&&"function"==typeof u.then&&u.then(l,p)}}})),r||i()}}function Pa(t,e){return Ca(t.map((function(t){return Object.keys(t.components).map((function(n){return e(t.components[n],t.instances[n],t,n)}))})))}function Ca(t){return Array.prototype.concat.apply([],t)}var Sa="function"==typeof Symbol&&"symbol"==typeof Symbol.toStringTag;function Ka(t){var e=!1;return function(){for(var n=[],i=arguments.length;i--;)n[i]=arguments[i];if(!e)return e=!0,t.apply(this,n)}}var Oa=function(t,e){this.router=t,this.base=function(t){if(!t)if(Vo){var e=document.querySelector("base");t=(t=e&&e.getAttribute("href")||"/").replace(/^https?:\/\/[^\/]+/,"")}else t="/";"/"!==t.charAt(0)&&(t="/"+t);return t.replace(/\/$/,"")}(e),this.current=ho,this.pending=null,this.ready=!1,this.readyCbs=[],this.readyErrorCbs=[],this.errorCbs=[],this.listeners=[]};function Ta(t,e,n,i){var r=Pa(t,(function(t,i,r,o){var a=function(t,e){"function"!=typeof t&&(t=zo.extend(t));return t.options[e]}(t,e);if(a)return Array.isArray(a)?a.map((function(t){return n(t,i,r,o)})):n(a,i,r,o)}));return Ca(i?r.reverse():r)}function $a(t,e){if(e)return function(){return t.apply(e,arguments)}}Oa.prototype.listen=function(t){this.cb=t},Oa.prototype.onReady=function(t,e){this.ready?t():(this.readyCbs.push(t),e&&this.readyErrorCbs.push(e))},Oa.prototype.onError=function(t){this.errorCbs.push(t)},Oa.prototype.transitionTo=function(t,e,n){var i,r=this;try{i=this.router.match(t,this.current)}catch(t){throw this.errorCbs.forEach((function(e){e(t)})),t}var o=this.current;this.confirmTransition(i,(function(){r.updateRoute(i),e&&e(i),r.ensureURL(),r.router.afterHooks.forEach((function(t){t&&t(i,o)})),r.ready||(r.ready=!0,r.readyCbs.forEach((function(t){t(i)})))}),(function(t){n&&n(t),t&&!r.ready&&(La(t,va.redirected)&&o===ho||(r.ready=!0,r.readyErrorCbs.forEach((function(e){e(t)}))))}))},Oa.prototype.confirmTransition=function(t,e,n){var i=this,r=this.current;this.pending=t;var o,a,c=function(t){!La(t)&&_a(t)&&(i.errorCbs.length?i.errorCbs.forEach((function(e){e(t)})):console.error(t)),n&&n(t)},s=t.matched.length-1,l=r.matched.length-1;if(vo(t,r)&&s===l&&t.matched[s]===r.matched[l])return this.ensureURL(),t.hash&&oa(this.router,r,t,!1),c(((a=wa(o=r,t,va.duplicated,'Avoided redundant navigation to current location: "'+o.fullPath+'".')).name="NavigationDuplicated",a));var p=function(t,e){var n,i=Math.max(t.length,e.length);for(n=0;n0)){var e=this.router,n=e.options.scrollBehavior,i=ha&&n;i&&this.listeners.push(ra());var r=function(){var n=t.current,r=Ma(t.base);t.current===ho&&r===t._startLocation||t.transitionTo(r,(function(t){i&&oa(e,t,n,!0)}))};window.addEventListener("popstate",r),this.listeners.push((function(){window.removeEventListener("popstate",r)}))}},e.prototype.go=function(t){window.history.go(t)},e.prototype.push=function(t,e,n){var i=this,r=this.current;this.transitionTo(t,(function(t){fa(Lo(i.base+t.fullPath)),oa(i.router,t,r,!1),e&&e(t)}),n)},e.prototype.replace=function(t,e,n){var i=this,r=this.current;this.transitionTo(t,(function(t){ma(Lo(i.base+t.fullPath)),oa(i.router,t,r,!1),e&&e(t)}),n)},e.prototype.ensureURL=function(t){if(Ma(this.base)!==this.current.fullPath){var e=Lo(this.base+this.current.fullPath);t?fa(e):ma(e)}},e.prototype.getCurrentLocation=function(){return Ma(this.base)},e}(Oa);function Ma(t){var e=window.location.pathname,n=e.toLowerCase(),i=t.toLowerCase();return!t||n!==i&&0!==n.indexOf(Lo(i+"/"))||(e=e.slice(t.length)),(e||"/")+window.location.search+window.location.hash}var Aa=function(t){function e(e,n,i){t.call(this,e,n),i&&function(t){var e=Ma(t);if(!/^\/#/.test(e))return window.location.replace(Lo(t+"/#"+e)),!0}(this.base)||ja()}return t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e,e.prototype.setupListeners=function(){var t=this;if(!(this.listeners.length>0)){var e=this.router.options.scrollBehavior,n=ha&&e;n&&this.listeners.push(ra());var i=function(){var e=t.current;ja()&&t.transitionTo(Ba(),(function(i){n&&oa(t.router,i,e,!0),ha||Na(i.fullPath)}))},r=ha?"popstate":"hashchange";window.addEventListener(r,i),this.listeners.push((function(){window.removeEventListener(r,i)}))}},e.prototype.push=function(t,e,n){var i=this,r=this.current;this.transitionTo(t,(function(t){Ra(t.fullPath),oa(i.router,t,r,!1),e&&e(t)}),n)},e.prototype.replace=function(t,e,n){var i=this,r=this.current;this.transitionTo(t,(function(t){Na(t.fullPath),oa(i.router,t,r,!1),e&&e(t)}),n)},e.prototype.go=function(t){window.history.go(t)},e.prototype.ensureURL=function(t){var e=this.current.fullPath;Ba()!==e&&(t?Ra(e):Na(e))},e.prototype.getCurrentLocation=function(){return Ba()},e}(Oa);function ja(){var t=Ba();return"/"===t.charAt(0)||(Na("/"+t),!1)}function Ba(){var t=window.location.href,e=t.indexOf("#");return e<0?"":t=t.slice(e+1)}function Fa(t){var e=window.location.href,n=e.indexOf("#");return(n>=0?e.slice(0,n):e)+"#"+t}function Ra(t){ha?fa(Fa(t)):window.location.hash=t}function Na(t){ha?ma(Fa(t)):window.location.replace(Fa(t))}var Ia=function(t){function e(e,n){t.call(this,e,n),this.stack=[],this.index=-1}return t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e,e.prototype.push=function(t,e,n){var i=this;this.transitionTo(t,(function(t){i.stack=i.stack.slice(0,i.index+1).concat(t),i.index++,e&&e(t)}),n)},e.prototype.replace=function(t,e,n){var i=this;this.transitionTo(t,(function(t){i.stack=i.stack.slice(0,i.index).concat(t),e&&e(t)}),n)},e.prototype.go=function(t){var e=this,n=this.index+t;if(!(n<0||n>=this.stack.length)){var i=this.stack[n];this.confirmTransition(i,(function(){var t=e.current;e.index=n,e.updateRoute(i),e.router.afterHooks.forEach((function(e){e&&e(i,t)}))}),(function(t){La(t,va.duplicated)&&(e.index=n)}))}},e.prototype.getCurrentLocation=function(){var t=this.stack[this.stack.length-1];return t?t.fullPath:"/"},e.prototype.ensureURL=function(){},e}(Oa),Ua=function(t){void 0===t&&(t={}),this.app=null,this.apps=[],this.options=t,this.beforeHooks=[],this.resolveHooks=[],this.afterHooks=[],this.matcher=Zo(t.routes||[],this);var e=t.mode||"hash";switch(this.fallback="history"===e&&!ha&&!1!==t.fallback,this.fallback&&(e="hash"),Vo||(e="abstract"),this.mode=e,e){case"history":this.history=new Ea(this,t.base);break;case"hash":this.history=new Aa(this,t.base,this.fallback);break;case"abstract":this.history=new Ia(this,t.base);break;default:0}},za={currentRoute:{configurable:!0}};Ua.prototype.match=function(t,e,n){return this.matcher.match(t,e,n)},za.currentRoute.get=function(){return this.history&&this.history.current},Ua.prototype.init=function(t){var e=this;if(this.apps.push(t),t.$once("hook:destroyed",(function(){var n=e.apps.indexOf(t);n>-1&&e.apps.splice(n,1),e.app===t&&(e.app=e.apps[0]||null),e.app||e.history.teardown()})),!this.app){this.app=t;var n=this.history;if(n instanceof Ea||n instanceof Aa){var i=function(t){n.setupListeners(),function(t){var i=n.current,r=e.options.scrollBehavior;ha&&r&&"fullPath"in t&&oa(e,t,i,!1)}(t)};n.transitionTo(n.getCurrentLocation(),i,i)}n.listen((function(t){e.apps.forEach((function(e){e._route=t}))}))}},Ua.prototype.beforeEach=function(t){return Wa(this.beforeHooks,t)},Ua.prototype.beforeResolve=function(t){return Wa(this.resolveHooks,t)},Ua.prototype.afterEach=function(t){return Wa(this.afterHooks,t)},Ua.prototype.onReady=function(t,e){this.history.onReady(t,e)},Ua.prototype.onError=function(t){this.history.onError(t)},Ua.prototype.push=function(t,e,n){var i=this;if(!e&&!n&&"undefined"!=typeof Promise)return new Promise((function(e,n){i.history.push(t,e,n)}));this.history.push(t,e,n)},Ua.prototype.replace=function(t,e,n){var i=this;if(!e&&!n&&"undefined"!=typeof Promise)return new Promise((function(e,n){i.history.replace(t,e,n)}));this.history.replace(t,e,n)},Ua.prototype.go=function(t){this.history.go(t)},Ua.prototype.back=function(){this.go(-1)},Ua.prototype.forward=function(){this.go(1)},Ua.prototype.getMatchedComponents=function(t){var e=t?t.matched?t:this.resolve(t).route:this.currentRoute;return e?[].concat.apply([],e.matched.map((function(t){return Object.keys(t.components).map((function(e){return t.components[e]}))}))):[]},Ua.prototype.resolve=function(t,e,n){var i=Uo(t,e=e||this.history.current,n,this),r=this.match(i,e),o=r.redirectedFrom||r.fullPath;return{location:i,route:r,href:function(t,e,n){var i="hash"===n?"#"+e:e;return t?Lo(t+"/"+i):i}(this.history.base,o,this.mode),normalizedTo:i,resolved:r}},Ua.prototype.getRoutes=function(){return this.matcher.getRoutes()},Ua.prototype.addRoute=function(t,e){this.matcher.addRoute(t,e),this.history.current!==ho&&this.history.transitionTo(this.history.getCurrentLocation())},Ua.prototype.addRoutes=function(t){this.matcher.addRoutes(t),this.history.current!==ho&&this.history.transitionTo(this.history.getCurrentLocation())},Object.defineProperties(Ua.prototype,za);var qa=Ua;function Wa(t,e){return t.push(e),function(){var n=t.indexOf(e);n>-1&&t.splice(n,1)}}Ua.install=function t(e){if(!t.installed||zo!==e){t.installed=!0,zo=e;var n=function(t){return void 0!==t},i=function(t,e){var i=t.$options._parentVnode;n(i)&&n(i=i.data)&&n(i=i.registerRouteInstance)&&i(t,e)};e.mixin({beforeCreate:function(){n(this.$options.router)?(this._routerRoot=this,this._router=this.$options.router,this._router.init(this),e.util.defineReactive(this,"_route",this._router.history.current)):this._routerRoot=this.$parent&&this.$parent._routerRoot||this,i(this,this)},destroyed:function(){i(this)}}),Object.defineProperty(e.prototype,"$router",{get:function(){return this._routerRoot._router}}),Object.defineProperty(e.prototype,"$route",{get:function(){return this._routerRoot._route}}),e.component("RouterView",wo),e.component("RouterLink",Wo);var r=e.config.optionMergeStrategies;r.beforeRouteEnter=r.beforeRouteLeave=r.beforeRouteUpdate=r.created}},Ua.version="3.6.5",Ua.isNavigationFailure=La,Ua.NavigationFailureType=va,Ua.START_LOCATION=ho,Vo&&window.Vue&&window.Vue.use(Ua);n(53);n(46),n(109);var Ha={NotFound:()=>Promise.all([n.e(0),n.e(1),n.e(27)]).then(n.bind(null,377)),Layout:()=>Promise.all([n.e(0),n.e(1),n.e(10)]).then(n.bind(null,376)),DirectoryPagination:()=>Promise.all([n.e(0),n.e(1),n.e(5)]).then(n.bind(null,378)),FrontmatterKey:()=>Promise.all([n.e(0),n.e(1),n.e(18)]).then(n.bind(null,379)),FrontmatterPagination:()=>Promise.all([n.e(0),n.e(1),n.e(6)]).then(n.bind(null,380)),IndexPost:()=>Promise.all([n.e(0),n.e(1),n.e(8)]).then(n.bind(null,281)),Post:()=>Promise.all([n.e(0),n.e(1),n.e(9)]).then(n.bind(null,381))},Va={"v-109b7b6a":()=>n.e(29).then(n.bind(null,385)),"v-0f4e007e":()=>n.e(30).then(n.bind(null,386)),"v-59a63080":()=>n.e(19).then(n.bind(null,387)),"v-6018492a":()=>n.e(12).then(n.bind(null,388)),"v-e02a8a76":()=>n.e(20).then(n.bind(null,389)),"v-2578306f":()=>n.e(31).then(n.bind(null,390)),"v-177ef1fe":()=>n.e(17).then(n.bind(null,391)),"v-eebe6fe6":()=>n.e(32).then(n.bind(null,392)),"v-7b0f0961":()=>n.e(21).then(n.bind(null,393)),"v-61c088e6":()=>n.e(33).then(n.bind(null,394)),"v-7b672071":()=>n.e(13).then(n.bind(null,395)),"v-394e384e":()=>n.e(22).then(n.bind(null,396)),"v-4ffe1afe":()=>n.e(23).then(n.bind(null,397)),"v-67ea603f":()=>n.e(34).then(n.bind(null,398)),"v-4c78f51d":()=>n.e(35).then(n.bind(null,399)),"v-3843152b":()=>n.e(36).then(n.bind(null,400)),"v-e5335502":()=>n.e(37).then(n.bind(null,401)),"v-3dc27382":()=>n.e(38).then(n.bind(null,402)),"v-7da54c6f":()=>n.e(39).then(n.bind(null,403)),"v-3efb3c3e":()=>n.e(40).then(n.bind(null,404)),"v-2f9b6cb6":()=>n.e(24).then(n.bind(null,405)),"v-66b18f61":()=>n.e(41).then(n.bind(null,406)),"v-6b753255":()=>n.e(42).then(n.bind(null,407)),"v-0c8784ee":()=>n.e(43).then(n.bind(null,408)),"v-2e33a981":()=>n.e(44).then(n.bind(null,409)),"v-208c95fe":()=>n.e(46).then(n.bind(null,410)),"v-4e009901":()=>n.e(47).then(n.bind(null,411)),"v-4215c085":()=>n.e(45).then(n.bind(null,412)),"v-f958b67a":()=>n.e(48).then(n.bind(null,413)),"v-44e9497e":()=>n.e(49).then(n.bind(null,414)),"v-1f59967e":()=>n.e(50).then(n.bind(null,415)),"v-f0ae247e":()=>n.e(52).then(n.bind(null,416)),"v-3cfeb3fe":()=>n.e(51).then(n.bind(null,417)),"v-1df9ba79":()=>n.e(7).then(n.bind(null,418)),"v-5e36ef8a":()=>n.e(54).then(n.bind(null,419)),"v-197bd04c":()=>n.e(11).then(n.bind(null,420)),"v-7495ad8d":()=>n.e(55).then(n.bind(null,421)),"v-d599223e":()=>n.e(25).then(n.bind(null,422)),"v-acaf8bbe":()=>n.e(53).then(n.bind(null,423)),"v-2615480c":()=>n.e(56).then(n.bind(null,424)),"v-2c8ce301":()=>n.e(57).then(n.bind(null,425)),"v-6f688c61":()=>n.e(58).then(n.bind(null,426)),"v-9b98f9ca":()=>n.e(26).then(n.bind(null,427)),"v-73ba0ae1":()=>n.e(59).then(n.bind(null,428)),"v-0a5ecb01":()=>n.e(60).then(n.bind(null,429)),"v-8b8ac0be":()=>n.e(61).then(n.bind(null,430)),"v-2e6cd4fd":()=>n.e(62).then(n.bind(null,431)),"v-c4171d36":()=>n.e(63).then(n.bind(null,432)),"v-21d81ac1":()=>n.e(65).then(n.bind(null,433)),"v-50f91cc7":()=>n.e(64).then(n.bind(null,434)),"v-102e5c3e":()=>n.e(66).then(n.bind(null,435)),"v-1d645dc1":()=>n.e(67).then(n.bind(null,436))};function Ga(t){const e=Object.create(null);return function(n){return e[n]||(e[n]=t(n))}}const Ja=/-(\w)/g,Za=Ga(t=>t.replace(Ja,(t,e)=>e?e.toUpperCase():"")),Ya=/\B([A-Z])/g,Xa=Ga(t=>t.replace(Ya,"-$1").toLowerCase()),Qa=Ga(t=>t.charAt(0).toUpperCase()+t.slice(1));function tc(t,e){if(!e)return;if(t(e))return t(e);return e.includes("-")?t(Qa(Za(e))):t(Qa(e))||t(Xa(e))}const ec=Object.assign({},Ha,Va),nc=t=>ec[t],ic=t=>Va[t],rc=t=>Ha[t],oc=t=>Hn.component(t);function ac(t){return tc(ic,t)}function cc(t){return tc(rc,t)}function sc(t){return tc(nc,t)}function lc(t){return tc(oc,t)}function pc(...t){return Promise.all(t.filter(t=>t).map(async t=>{if(!lc(t)&&sc(t)){const e=await sc(t)();Hn.component(t,e.default)}}))}function uc(t,e){"undefined"!=typeof window&&window.__VUEPRESS__&&(window.__VUEPRESS__[t]=e)}var gc=n(92),dc=n.n(gc),hc=n(93),fc=n.n(hc),mc={created(){if(this.siteMeta=this.$site.headTags.filter(([t])=>"meta"===t).map(([t,e])=>e),this.$ssrContext){const e=this.getMergedMetaTags();this.$ssrContext.title=this.$title,this.$ssrContext.lang=this.$lang,this.$ssrContext.pageMeta=(t=e)?t.map(t=>{let e="{e+=` ${n}="${fc()(t[n])}"`}),e+">"}).join("\n "):"",this.$ssrContext.canonicalLink=yc(this.$canonicalUrl)}var t},mounted(){this.currentMetaTags=[...document.querySelectorAll("meta")],this.updateMeta(),this.updateCanonicalLink()},methods:{updateMeta(){document.title=this.$title,document.documentElement.lang=this.$lang;const t=this.getMergedMetaTags();this.currentMetaTags=bc(t,this.currentMetaTags)},getMergedMetaTags(){const t=this.$page.frontmatter.meta||[];return dc()([{name:"description",content:this.$description}],t,this.siteMeta,wc)},updateCanonicalLink(){vc(),this.$canonicalUrl&&document.head.insertAdjacentHTML("beforeend",yc(this.$canonicalUrl))}},watch:{$page(){this.updateMeta(),this.updateCanonicalLink()}},beforeDestroy(){bc(null,this.currentMetaTags),vc()}};function vc(){const t=document.querySelector("link[rel='canonical']");t&&t.remove()}function yc(t=""){return t?``:""}function bc(t,e){if(e&&[...e].filter(t=>t.parentNode===document.head).forEach(t=>document.head.removeChild(t)),t)return t.map(t=>{const e=document.createElement("meta");return Object.keys(t).forEach(n=>{e.setAttribute(n,t[n])}),document.head.appendChild(e),e})}function wc(t){for(const e of["name","property","itemprop"])if(t.hasOwnProperty(e))return t[e]+e;return JSON.stringify(t)}var kc=n(94),_c={mounted(){window.addEventListener("scroll",this.onScroll)},methods:{onScroll:n.n(kc)()((function(){this.setActiveHash()}),300),setActiveHash(){const t=[].slice.call(document.querySelectorAll(".sidebar-link")),e=[].slice.call(document.querySelectorAll(".header-anchor")).filter(e=>t.some(t=>t.hash===e.hash)),n=Math.max(window.pageYOffset,document.documentElement.scrollTop,document.body.scrollTop),i=Math.max(document.documentElement.scrollHeight,document.body.scrollHeight),r=window.innerHeight+n;for(let t=0;t=o.parentElement.offsetTop+10&&(!a||n{this.$nextTick(()=>{this.$vuepress.$set("disableScrollBehavior",!1)})})}}}},beforeDestroy(){window.removeEventListener("scroll",this.onScroll)}},Lc=n(22),Dc=n.n(Lc),xc={mounted(){Dc.a.configure({showSpinner:!1}),this.$router.beforeEach((t,e,n)=>{t.path===e.path||Hn.component(t.name)||Dc.a.start(),n()}),this.$router.afterEach(()=>{Dc.a.done(),this.isSidebarOpen=!1})}},Pc={props:{parent:Object,code:String,options:{align:String,color:String,backgroundTransition:Boolean,backgroundColor:String,successText:String,staticIcon:Boolean}},data:()=>({success:!1,originalBackground:null,originalTransition:null}),computed:{alignStyle(){let t={};return t[this.options.align]="7.5px",t},iconClass(){return this.options.staticIcon?"":"hover"}},mounted(){this.originalTransition=this.parent.style.transition,this.originalBackground=this.parent.style.background},beforeDestroy(){this.parent.style.transition=this.originalTransition,this.parent.style.background=this.originalBackground},methods:{hexToRgb(t){let e=/^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(t);return e?{r:parseInt(e[1],16),g:parseInt(e[2],16),b:parseInt(e[3],16)}:null},copyToClipboard(t){if(navigator.clipboard)navigator.clipboard.writeText(this.code).then(()=>{this.setSuccessTransitions()},()=>{});else{let t=document.createElement("textarea");document.body.appendChild(t),t.value=this.code,t.select(),document.execCommand("Copy"),t.remove(),this.setSuccessTransitions()}},setSuccessTransitions(){if(clearTimeout(this.successTimeout),this.options.backgroundTransition){this.parent.style.transition="background 350ms";let t=this.hexToRgb(this.options.backgroundColor);this.parent.style.background=`rgba(${t.r}, ${t.g}, ${t.b}, 0.1)`}this.success=!0,this.successTimeout=setTimeout(()=>{this.options.backgroundTransition&&(this.parent.style.background=this.originalBackground,this.parent.style.transition=this.originalTransition),this.success=!1},500)}}},Cc=(n(240),n(7)),Sc=Object(Cc.a)(Pc,(function(){var t=this,e=t._self._c;return e("div",{staticClass:"code-copy"},[e("svg",{class:t.iconClass,style:t.alignStyle,attrs:{xmlns:"http://www.w3.org/2000/svg",width:"24",height:"24",viewBox:"0 0 24 24"},on:{click:t.copyToClipboard}},[e("path",{attrs:{fill:"none",d:"M0 0h24v24H0z"}}),t._v(" "),e("path",{attrs:{fill:t.options.color,d:"M16 1H4c-1.1 0-2 .9-2 2v14h2V3h12V1zm-1 4l6 6v10c0 1.1-.9 2-2 2H7.99C6.89 23 6 22.1 6 21l.01-14c0-1.1.89-2 1.99-2h7zm-1 7h5.5L14 6.5V12z"}})]),t._v(" "),e("span",{class:t.success?"success":"",style:t.alignStyle},[t._v("\n "+t._s(t.options.successText)+"\n ")])])}),[],!1,null,"49140617",null).exports,Kc=(n(241),[mc,_c,xc,{updated(){this.update()},methods:{update(){setTimeout(()=>{document.querySelectorAll('div[class*="language-"] pre').forEach(t=>{if(t.classList.contains("code-copy-added"))return;let e=new(Hn.extend(Sc));e.options={align:"bottom",color:"#8F979E",backgroundTransition:!1,backgroundColor:"#0075b8",successText:"Copied!",staticIcon:!0},e.code=t.innerText,e.parent=t,e.$mount(),t.classList.add("code-copy-added"),t.appendChild(e.$el)})},100)}}}]),Oc={name:"GlobalLayout",computed:{layout(){const t=this.getLayout();return uc("layout",t),Hn.component(t)}},methods:{getLayout(){if(this.$page.path){const t=this.$page.frontmatter.layout;return t&&(this.$vuepress.getLayoutAsyncComponent(t)||this.$vuepress.getVueComponent(t))?t:"Layout"}return"NotFound"}}},Tc=Object(Cc.a)(Oc,(function(){return(0,this._self._c)(this.layout,{tag:"component"})}),[],!1,null,null,null).exports;!function(t,e,n){switch(e){case"components":t[e]||(t[e]={}),Object.assign(t[e],n);break;case"mixins":t[e]||(t[e]=[]),t[e].push(...n);break;default:throw new Error("Unknown option name.")}}(Tc,"mixins",Kc);const $c=[{name:"v-109b7b6a",path:"/blog/anchor-outputs-channels-are-here/",component:Tc,beforeEnter:(t,e,n)=>{pc("Post","v-109b7b6a").then(n)}},{path:"/blog/anchor-outputs-channels-are-here/index.html",redirect:"/blog/anchor-outputs-channels-are-here/"},{path:"/_blog/anchor-outputs-channels-are-here.html",redirect:"/blog/anchor-outputs-channels-are-here/"},{name:"v-0f4e007e",path:"/blog/announcing-ldk-node/",component:Tc,beforeEnter:(t,e,n)=>{pc("Post","v-0f4e007e").then(n)}},{path:"/blog/announcing-ldk-node/index.html",redirect:"/blog/announcing-ldk-node/"},{path:"/_blog/announcing-ldk-node.html",redirect:"/blog/announcing-ldk-node/"},{name:"v-59a63080",path:"/blog/bitkit-uses-ldk-to-build-the-ultimate-alternative-to-custodial-wallets/",component:Tc,beforeEnter:(t,e,n)=>{pc("Post","v-59a63080").then(n)}},{path:"/blog/bitkit-uses-ldk-to-build-the-ultimate-alternative-to-custodial-wallets/index.html",redirect:"/blog/bitkit-uses-ldk-to-build-the-ultimate-alternative-to-custodial-wallets/"},{path:"/_blog/bitkit-uses-ldk-to-build-the-ultimate-alternative-to-custodial wallets.html",redirect:"/blog/bitkit-uses-ldk-to-build-the-ultimate-alternative-to-custodial-wallets/"},{name:"v-6018492a",path:"/blog/bolt12-has-arrived/",component:Tc,beforeEnter:(t,e,n)=>{pc("Post","v-6018492a").then(n)}},{path:"/blog/bolt12-has-arrived/index.html",redirect:"/blog/bolt12-has-arrived/"},{path:"/_blog/bolt12-has-arrived.html",redirect:"/blog/bolt12-has-arrived/"},{name:"v-e02a8a76",path:"/blog/cashapp-enables-lightning-withdrawals-and-deposits-using-ldk/",component:Tc,beforeEnter:(t,e,n)=>{pc("Post","v-e02a8a76").then(n)}},{path:"/blog/cashapp-enables-lightning-withdrawals-and-deposits-using-ldk/index.html",redirect:"/blog/cashapp-enables-lightning-withdrawals-and-deposits-using-ldk/"},{path:"/_blog/cashapp-enables-lightning-withdrawals-and-deposits-using-ldk.html",redirect:"/blog/cashapp-enables-lightning-withdrawals-and-deposits-using-ldk/"},{name:"v-2578306f",path:"/blog/announcing-rapid-gossip-sync/",component:Tc,beforeEnter:(t,e,n)=>{pc("Post","v-2578306f").then(n)}},{path:"/blog/announcing-rapid-gossip-sync/index.html",redirect:"/blog/announcing-rapid-gossip-sync/"},{path:"/_blog/announcing-rapid-gossip-sync.html",redirect:"/blog/announcing-rapid-gossip-sync/"},{name:"v-177ef1fe",path:"/blog/introducing-phantom-node-payments/",component:Tc,beforeEnter:(t,e,n)=>{pc("Post","v-177ef1fe").then(n)}},{path:"/blog/introducing-phantom-node-payments/index.html",redirect:"/blog/introducing-phantom-node-payments/"},{path:"/_blog/introducing-phantom-node-payments.html",redirect:"/blog/introducing-phantom-node-payments/"},{name:"v-eebe6fe6",path:"/blog/ldk-an-sdk-for-the-lightning-network/",component:Tc,beforeEnter:(t,e,n)=>{pc("Post","v-eebe6fe6").then(n)}},{path:"/blog/ldk-an-sdk-for-the-lightning-network/index.html",redirect:"/blog/ldk-an-sdk-for-the-lightning-network/"},{path:"/_blog/ldk-an-sdk-for-the-lightning-network.html",redirect:"/blog/ldk-an-sdk-for-the-lightning-network/"},{name:"v-7b0f0961",path:"/blog/ldk-roadmap/",component:Tc,beforeEnter:(t,e,n)=>{pc("Post","v-7b0f0961").then(n)}},{path:"/blog/ldk-roadmap/index.html",redirect:"/blog/ldk-roadmap/"},{path:"/_blog/ldk-roadmap.html",redirect:"/blog/ldk-roadmap/"},{name:"v-61c088e6",path:"/blog/mutiny-uses-ldk-the-first-lightning-wallet-for-the-web/",component:Tc,beforeEnter:(t,e,n)=>{pc("Post","v-61c088e6").then(n)}},{path:"/blog/mutiny-uses-ldk-the-first-lightning-wallet-for-the-web/index.html",redirect:"/blog/mutiny-uses-ldk-the-first-lightning-wallet-for-the-web/"},{path:"/_blog/mutiny-uses-ldk-the-first-lightning-wallet-for-the-web.html",redirect:"/blog/mutiny-uses-ldk-the-first-lightning-wallet-for-the-web/"},{name:"v-7b672071",path:"/blog/onion-messages-demystified/",component:Tc,beforeEnter:(t,e,n)=>{pc("Post","v-7b672071").then(n)}},{path:"/blog/onion-messages-demystified/index.html",redirect:"/blog/onion-messages-demystified/"},{path:"/_blog/onion-messages-demystified.html",redirect:"/blog/onion-messages-demystified/"},{name:"v-394e384e",path:"/blog/sensei-uses-ldk-to-build-a-multi-node-lightning-server-application/",component:Tc,beforeEnter:(t,e,n)=>{pc("Post","v-394e384e").then(n)}},{path:"/blog/sensei-uses-ldk-to-build-a-multi-node-lightning-server-application/index.html",redirect:"/blog/sensei-uses-ldk-to-build-a-multi-node-lightning-server-application/"},{path:"/_blog/sensei-uses-ldk-to-build-a-multi-node-lightning-server-application.html",redirect:"/blog/sensei-uses-ldk-to-build-a-multi-node-lightning-server-application/"},{name:"v-4ffe1afe",path:"/blog/teos-uses-ldk-to-build-open-source-watchtower/",component:Tc,beforeEnter:(t,e,n)=>{pc("Post","v-4ffe1afe").then(n)}},{path:"/blog/teos-uses-ldk-to-build-open-source-watchtower/index.html",redirect:"/blog/teos-uses-ldk-to-build-open-source-watchtower/"},{path:"/_blog/teos-uses-ldk-to-build-open-source-watchtower.html",redirect:"/blog/teos-uses-ldk-to-build-open-source-watchtower/"},{name:"v-67ea603f",path:"/blog/the-challenges-of-developing-non-custodial-lightning-on-mobile/",component:Tc,beforeEnter:(t,e,n)=>{pc("Post","v-67ea603f").then(n)}},{path:"/blog/the-challenges-of-developing-non-custodial-lightning-on-mobile/index.html",redirect:"/blog/the-challenges-of-developing-non-custodial-lightning-on-mobile/"},{path:"/_blog/the-challenges-of-developing-non-custodial-lightning-on-mobile.html",redirect:"/blog/the-challenges-of-developing-non-custodial-lightning-on-mobile/"},{name:"v-4c78f51d",path:"/blog/unleashing-liquidity-on-the-lightning-network-with-lightning-liquidity/",component:Tc,beforeEnter:(t,e,n)=>{pc("Post","v-4c78f51d").then(n)}},{path:"/blog/unleashing-liquidity-on-the-lightning-network-with-lightning-liquidity/index.html",redirect:"/blog/unleashing-liquidity-on-the-lightning-network-with-lightning-liquidity/"},{path:"/_blog/unleashing-liquidity-on-the-lightning-network-with-lightning-liquidity.html",redirect:"/blog/unleashing-liquidity-on-the-lightning-network-with-lightning-liquidity/"},{name:"v-3843152b",path:"/blog/zero-confirmation-channels/",component:Tc,beforeEnter:(t,e,n)=>{pc("Post","v-3843152b").then(n)}},{path:"/blog/zero-confirmation-channels/index.html",redirect:"/blog/zero-confirmation-channels/"},{path:"/_blog/zero-confirmation-channels.html",redirect:"/blog/zero-confirmation-channels/"},{name:"v-e5335502",path:"/blockchain_data/block_source/",component:Tc,beforeEnter:(t,e,n)=>{pc("Layout","v-e5335502").then(n)}},{path:"/blockchain_data/block_source/index.html",redirect:"/blockchain_data/block_source/"},{path:"/blockchain_data/block_source.html",redirect:"/blockchain_data/block_source/"},{name:"v-3dc27382",path:"/blockchain_data/chain_activity/",component:Tc,beforeEnter:(t,e,n)=>{pc("Layout","v-3dc27382").then(n)}},{path:"/blockchain_data/chain_activity/index.html",redirect:"/blockchain_data/chain_activity/"},{path:"/blockchain_data/chain_activity.html",redirect:"/blockchain_data/chain_activity/"},{name:"v-7da54c6f",path:"/blockchain_data/confirmed_transactions/",component:Tc,beforeEnter:(t,e,n)=>{pc("Layout","v-7da54c6f").then(n)}},{path:"/blockchain_data/confirmed_transactions/index.html",redirect:"/blockchain_data/confirmed_transactions/"},{path:"/blockchain_data/confirmed_transactions.html",redirect:"/blockchain_data/confirmed_transactions/"},{name:"v-3efb3c3e",path:"/blockchain_data/full_blocks/",component:Tc,beforeEnter:(t,e,n)=>{pc("Layout","v-3efb3c3e").then(n)}},{path:"/blockchain_data/full_blocks/index.html",redirect:"/blockchain_data/full_blocks/"},{path:"/blockchain_data/full_blocks.html",redirect:"/blockchain_data/full_blocks/"},{name:"v-2f9b6cb6",path:"/blockchain_data/introduction/",component:Tc,beforeEnter:(t,e,n)=>{pc("Layout","v-2f9b6cb6").then(n)}},{path:"/blockchain_data/introduction/index.html",redirect:"/blockchain_data/introduction/"},{path:"/blockchain_data/introduction.html",redirect:"/blockchain_data/introduction/"},{name:"v-66b18f61",path:"/blockchain_data/pre_filtered_blocks/",component:Tc,beforeEnter:(t,e,n)=>{pc("Layout","v-66b18f61").then(n)}},{path:"/blockchain_data/pre_filtered_blocks/index.html",redirect:"/blockchain_data/pre_filtered_blocks/"},{path:"/blockchain_data/pre_filtered_blocks.html",redirect:"/blockchain_data/pre_filtered_blocks/"},{name:"v-6b753255",path:"/blockchain_data/transaction_broadcasting/",component:Tc,beforeEnter:(t,e,n)=>{pc("Layout","v-6b753255").then(n)}},{path:"/blockchain_data/transaction_broadcasting/index.html",redirect:"/blockchain_data/transaction_broadcasting/"},{path:"/blockchain_data/transaction_broadcasting.html",redirect:"/blockchain_data/transaction_broadcasting/"},{name:"v-0c8784ee",path:"/building-a-node-with-ldk/closing-a-channel/",component:Tc,beforeEnter:(t,e,n)=>{pc("Layout","v-0c8784ee").then(n)}},{path:"/building-a-node-with-ldk/closing-a-channel/index.html",redirect:"/building-a-node-with-ldk/closing-a-channel/"},{path:"/building-a-node-with-ldk/closing-a-channel.html",redirect:"/building-a-node-with-ldk/closing-a-channel/"},{name:"v-2e33a981",path:"/building-a-node-with-ldk/connect-to-peers/",component:Tc,beforeEnter:(t,e,n)=>{pc("Layout","v-2e33a981").then(n)}},{path:"/building-a-node-with-ldk/connect-to-peers/index.html",redirect:"/building-a-node-with-ldk/connect-to-peers/"},{path:"/building-a-node-with-ldk/connect-to-peers.html",redirect:"/building-a-node-with-ldk/connect-to-peers/"},{name:"v-208c95fe",path:"/building-a-node-with-ldk/installation/",component:Tc,beforeEnter:(t,e,n)=>{pc("Layout","v-208c95fe").then(n)}},{path:"/building-a-node-with-ldk/installation/index.html",redirect:"/building-a-node-with-ldk/installation/"},{path:"/building-a-node-with-ldk/installation.html",redirect:"/building-a-node-with-ldk/installation/"},{name:"v-4e009901",path:"/building-a-node-with-ldk/introduction/",component:Tc,beforeEnter:(t,e,n)=>{pc("Layout","v-4e009901").then(n)}},{path:"/building-a-node-with-ldk/introduction/index.html",redirect:"/building-a-node-with-ldk/introduction/"},{path:"/building-a-node-with-ldk/introduction.html",redirect:"/building-a-node-with-ldk/introduction/"},{name:"v-4215c085",path:"/building-a-node-with-ldk/handling-events/",component:Tc,beforeEnter:(t,e,n)=>{pc("Layout","v-4215c085").then(n)}},{path:"/building-a-node-with-ldk/handling-events/index.html",redirect:"/building-a-node-with-ldk/handling-events/"},{path:"/building-a-node-with-ldk/handling-events.html",redirect:"/building-a-node-with-ldk/handling-events/"},{name:"v-f958b67a",path:"/building-a-node-with-ldk/opening-a-channel/",component:Tc,beforeEnter:(t,e,n)=>{pc("Layout","v-f958b67a").then(n)}},{path:"/building-a-node-with-ldk/opening-a-channel/index.html",redirect:"/building-a-node-with-ldk/opening-a-channel/"},{path:"/building-a-node-with-ldk/opening-a-channel.html",redirect:"/building-a-node-with-ldk/opening-a-channel/"},{name:"v-44e9497e",path:"/building-a-node-with-ldk/receiving-payments/",component:Tc,beforeEnter:(t,e,n)=>{pc("Layout","v-44e9497e").then(n)}},{path:"/building-a-node-with-ldk/receiving-payments/index.html",redirect:"/building-a-node-with-ldk/receiving-payments/"},{path:"/building-a-node-with-ldk/receiving-payments.html",redirect:"/building-a-node-with-ldk/receiving-payments/"},{name:"v-1f59967e",path:"/building-a-node-with-ldk/sending-payments/",component:Tc,beforeEnter:(t,e,n)=>{pc("Layout","v-1f59967e").then(n)}},{path:"/building-a-node-with-ldk/sending-payments/index.html",redirect:"/building-a-node-with-ldk/sending-payments/"},{path:"/building-a-node-with-ldk/sending-payments.html",redirect:"/building-a-node-with-ldk/sending-payments/"},{name:"v-f0ae247e",path:"/building-a-node-with-ldk/setting-up-a-peer-manager/",component:Tc,beforeEnter:(t,e,n)=>{pc("Layout","v-f0ae247e").then(n)}},{path:"/building-a-node-with-ldk/setting-up-a-peer-manager/index.html",redirect:"/building-a-node-with-ldk/setting-up-a-peer-manager/"},{path:"/building-a-node-with-ldk/setting-up-a-peer-manager.html",redirect:"/building-a-node-with-ldk/setting-up-a-peer-manager/"},{name:"v-3cfeb3fe",path:"/building-a-node-with-ldk/setting-up-a-channel-manager/",component:Tc,beforeEnter:(t,e,n)=>{pc("Layout","v-3cfeb3fe").then(n)}},{path:"/building-a-node-with-ldk/setting-up-a-channel-manager/index.html",redirect:"/building-a-node-with-ldk/setting-up-a-channel-manager/"},{path:"/building-a-node-with-ldk/setting-up-a-channel-manager.html",redirect:"/building-a-node-with-ldk/setting-up-a-channel-manager/"},{name:"v-1df9ba79",path:"/case-studies/",component:Tc,beforeEnter:(t,e,n)=>{pc("Layout","v-1df9ba79").then(n)}},{path:"/case-studies/index.html",redirect:"/case-studies/"},{path:"/case-studies.html",redirect:"/case-studies/"},{name:"v-5e36ef8a",path:"/examples/",component:Tc,beforeEnter:(t,e,n)=>{pc("Layout","v-5e36ef8a").then(n)}},{path:"/examples/index.html",redirect:"/examples/"},{path:"/examples.html",redirect:"/examples/"},{name:"v-197bd04c",path:"/",component:Tc,beforeEnter:(t,e,n)=>{pc("Layout","v-197bd04c").then(n)}},{path:"/index.html",redirect:"/"},{name:"v-7495ad8d",path:"/introduction/blockchain_data/",component:Tc,beforeEnter:(t,e,n)=>{pc("Layout","v-7495ad8d").then(n)}},{path:"/introduction/blockchain_data/index.html",redirect:"/introduction/blockchain_data/"},{path:"/introduction/blockchain_data.html",redirect:"/introduction/blockchain_data/"},{name:"v-d599223e",path:"/introduction/architecture/",component:Tc,beforeEnter:(t,e,n)=>{pc("Layout","v-d599223e").then(n)}},{path:"/introduction/architecture/index.html",redirect:"/introduction/architecture/"},{path:"/introduction/architecture.html",redirect:"/introduction/architecture/"},{name:"v-acaf8bbe",path:"/code_of_conduct/",component:Tc,beforeEnter:(t,e,n)=>{pc("Layout","v-acaf8bbe").then(n)}},{path:"/code_of_conduct/index.html",redirect:"/code_of_conduct/"},{path:"/code_of_conduct.html",redirect:"/code_of_conduct/"},{name:"v-2615480c",path:"/introduction/",component:Tc,beforeEnter:(t,e,n)=>{pc("Layout","v-2615480c").then(n)}},{path:"/introduction/index.html",redirect:"/introduction/"},{name:"v-2c8ce301",path:"/introduction/networking/",component:Tc,beforeEnter:(t,e,n)=>{pc("Layout","v-2c8ce301").then(n)}},{path:"/introduction/networking/index.html",redirect:"/introduction/networking/"},{path:"/introduction/networking.html",redirect:"/introduction/networking/"},{name:"v-6f688c61",path:"/introduction/persistent_storage/",component:Tc,beforeEnter:(t,e,n)=>{pc("Layout","v-6f688c61").then(n)}},{path:"/introduction/persistent_storage/index.html",redirect:"/introduction/persistent_storage/"},{path:"/introduction/persistent_storage.html",redirect:"/introduction/persistent_storage/"},{name:"v-9b98f9ca",path:"/introduction/peer-management/",component:Tc,beforeEnter:(t,e,n)=>{pc("Layout","v-9b98f9ca").then(n)}},{path:"/introduction/peer-management/index.html",redirect:"/introduction/peer-management/"},{path:"/introduction/peer-management.html",redirect:"/introduction/peer-management/"},{name:"v-73ba0ae1",path:"/introduction/private_key_management/",component:Tc,beforeEnter:(t,e,n)=>{pc("Layout","v-73ba0ae1").then(n)}},{path:"/introduction/private_key_management/index.html",redirect:"/introduction/private_key_management/"},{path:"/introduction/private_key_management.html",redirect:"/introduction/private_key_management/"},{name:"v-0a5ecb01",path:"/introduction/random_number_generation/",component:Tc,beforeEnter:(t,e,n)=>{pc("Layout","v-0a5ecb01").then(n)}},{path:"/introduction/random_number_generation/index.html",redirect:"/introduction/random_number_generation/"},{path:"/introduction/random_number_generation.html",redirect:"/introduction/random_number_generation/"},{name:"v-8b8ac0be",path:"/introduction/transactions/",component:Tc,beforeEnter:(t,e,n)=>{pc("Layout","v-8b8ac0be").then(n)}},{path:"/introduction/transactions/index.html",redirect:"/introduction/transactions/"},{path:"/introduction/transactions.html",redirect:"/introduction/transactions/"},{name:"v-2e6cd4fd",path:"/introduction/use-cases/",component:Tc,beforeEnter:(t,e,n)=>{pc("Layout","v-2e6cd4fd").then(n)}},{path:"/introduction/use-cases/index.html",redirect:"/introduction/use-cases/"},{path:"/introduction/use-cases.html",redirect:"/introduction/use-cases/"},{name:"v-c4171d36",path:"/introduction/wallet_management/",component:Tc,beforeEnter:(t,e,n)=>{pc("Layout","v-c4171d36").then(n)}},{path:"/introduction/wallet_management/index.html",redirect:"/introduction/wallet_management/"},{path:"/introduction/wallet_management.html",redirect:"/introduction/wallet_management/"},{name:"v-21d81ac1",path:"/language_bindings/",component:Tc,beforeEnter:(t,e,n)=>{pc("Layout","v-21d81ac1").then(n)}},{path:"/language_bindings/index.html",redirect:"/language_bindings/"},{path:"/language_bindings.html",redirect:"/language_bindings/"},{name:"v-50f91cc7",path:"/key_management/",component:Tc,beforeEnter:(t,e,n)=>{pc("Layout","v-50f91cc7").then(n)}},{path:"/key_management/index.html",redirect:"/key_management/"},{path:"/key_management.html",redirect:"/key_management/"},{name:"v-102e5c3e",path:"/persist/",component:Tc,beforeEnter:(t,e,n)=>{pc("Layout","v-102e5c3e").then(n)}},{path:"/persist/index.html",redirect:"/persist/"},{path:"/persist.html",redirect:"/persist/"},{name:"v-1d645dc1",path:"/running-a-sample-ldk-node/",component:Tc,beforeEnter:(t,e,n)=>{pc("Layout","v-1d645dc1").then(n)}},{path:"/running-a-sample-ldk-node/index.html",redirect:"/running-a-sample-ldk-node/"},{path:"/running-a-sample-ldk-node.html",redirect:"/running-a-sample-ldk-node/"},{name:"v-424df898",path:"/blog/",component:Tc,beforeEnter:(t,e,n)=>{pc("IndexPost","v-424df898").then(n)},meta:{pid:"blog",id:"blog"}},{path:"/blog/index.html",redirect:"/blog/"},{name:"v-619df59e",path:"/blog/tags/",component:Tc,beforeEnter:(t,e,n)=>{pc("FrontmatterKey","v-619df59e").then(n)},meta:{pid:"tags",id:"tags"}},{path:"/blog/tags/index.html",redirect:"/blog/tags/"},{name:"v-b0968728",path:"/blog/author/",component:Tc,beforeEnter:(t,e,n)=>{pc("FrontmatterKey","v-b0968728").then(n)},meta:{pid:"author",id:"author"}},{path:"/blog/author/index.html",redirect:"/blog/author/"},{name:"v-07a81b3e",path:"/blog/tags/Channels/",component:Tc,beforeEnter:(t,e,n)=>{pc("FrontmatterPagination","v-07a81b3e").then(n)},meta:{pid:"tags",id:"Channels"}},{path:"/blog/tags/Channels/index.html",redirect:"/blog/tags/Channels/"},{name:"v-2d66714d",path:"/blog/tags/Anchor Outputs/",component:Tc,beforeEnter:(t,e,n)=>{pc("FrontmatterPagination","v-2d66714d").then(n)},meta:{pid:"tags",id:"Anchor Outputs"}},{path:"/blog/tags/Anchor Outputs/index.html",redirect:"/blog/tags/Anchor Outputs/"},{name:"v-3d7abd24",path:"/blog/tags/Fees/",component:Tc,beforeEnter:(t,e,n)=>{pc("FrontmatterPagination","v-3d7abd24").then(n)},meta:{pid:"tags",id:"Fees"}},{path:"/blog/tags/Fees/index.html",redirect:"/blog/tags/Fees/"},{name:"v-45d354a1",path:"/blog/tags/Self-custody/",component:Tc,beforeEnter:(t,e,n)=>{pc("FrontmatterPagination","v-45d354a1").then(n)},meta:{pid:"tags",id:"Self-custody"}},{path:"/blog/tags/Self-custody/index.html",redirect:"/blog/tags/Self-custody/"},{name:"v-4cee384f",path:"/blog/tags/Mobile/",component:Tc,beforeEnter:(t,e,n)=>{pc("FrontmatterPagination","v-4cee384f").then(n)},meta:{pid:"tags",id:"Mobile"}},{path:"/blog/tags/Mobile/index.html",redirect:"/blog/tags/Mobile/"},{name:"v-2571507d",path:"/blog/tags/Case Studies/",component:Tc,beforeEnter:(t,e,n)=>{pc("FrontmatterPagination","v-2571507d").then(n)},meta:{pid:"tags",id:"Case Studies"}},{path:"/blog/tags/Case Studies/index.html",redirect:"/blog/tags/Case Studies/"},{name:"v-b0d4940c",path:"/blog/tags/Offers/",component:Tc,beforeEnter:(t,e,n)=>{pc("FrontmatterPagination","v-b0d4940c").then(n)},meta:{pid:"tags",id:"Offers"}},{path:"/blog/tags/Offers/index.html",redirect:"/blog/tags/Offers/"},{name:"v-d885a66a",path:"/blog/tags/Onion Messages/",component:Tc,beforeEnter:(t,e,n)=>{pc("FrontmatterPagination","v-d885a66a").then(n)},meta:{pid:"tags",id:"Onion Messages"}},{path:"/blog/tags/Onion Messages/index.html",redirect:"/blog/tags/Onion Messages/"},{name:"v-33d32965",path:"/blog/tags/Privacy/",component:Tc,beforeEnter:(t,e,n)=>{pc("FrontmatterPagination","v-33d32965").then(n)},meta:{pid:"tags",id:"Privacy"}},{path:"/blog/tags/Privacy/index.html",redirect:"/blog/tags/Privacy/"},{name:"v-107ce622",path:"/blog/tags/Gossip/",component:Tc,beforeEnter:(t,e,n)=>{pc("FrontmatterPagination","v-107ce622").then(n)},meta:{pid:"tags",id:"Gossip"}},{path:"/blog/tags/Gossip/index.html",redirect:"/blog/tags/Gossip/"},{name:"v-288bb6f4",path:"/blog/tags/Network Graph/",component:Tc,beforeEnter:(t,e,n)=>{pc("FrontmatterPagination","v-288bb6f4").then(n)},meta:{pid:"tags",id:"Network Graph"}},{path:"/blog/tags/Network Graph/index.html",redirect:"/blog/tags/Network Graph/"},{name:"v-75584720",path:"/blog/tags/Enterprise/",component:Tc,beforeEnter:(t,e,n)=>{pc("FrontmatterPagination","v-75584720").then(n)},meta:{pid:"tags",id:"Enterprise"}},{path:"/blog/tags/Enterprise/index.html",redirect:"/blog/tags/Enterprise/"},{name:"v-14c62680",path:"/blog/tags/Phantom/",component:Tc,beforeEnter:(t,e,n)=>{pc("FrontmatterPagination","v-14c62680").then(n)},meta:{pid:"tags",id:"Phantom"}},{path:"/blog/tags/Phantom/index.html",redirect:"/blog/tags/Phantom/"},{name:"v-89aabae2",path:"/blog/tags/Bitcoin/",component:Tc,beforeEnter:(t,e,n)=>{pc("FrontmatterPagination","v-89aabae2").then(n)},meta:{pid:"tags",id:"Bitcoin"}},{path:"/blog/tags/Bitcoin/index.html",redirect:"/blog/tags/Bitcoin/"},{name:"v-5f1ce94c",path:"/blog/tags/LDK/",component:Tc,beforeEnter:(t,e,n)=>{pc("FrontmatterPagination","v-5f1ce94c").then(n)},meta:{pid:"tags",id:"LDK"}},{path:"/blog/tags/LDK/index.html",redirect:"/blog/tags/LDK/"},{name:"v-5643d131",path:"/blog/tags/Roadmap/",component:Tc,beforeEnter:(t,e,n)=>{pc("FrontmatterPagination","v-5643d131").then(n)},meta:{pid:"tags",id:"Roadmap"}},{path:"/blog/tags/Roadmap/index.html",redirect:"/blog/tags/Roadmap/"},{name:"v-0bfa2c21",path:"/blog/tags/Non-Custodial/",component:Tc,beforeEnter:(t,e,n)=>{pc("FrontmatterPagination","v-0bfa2c21").then(n)},meta:{pid:"tags",id:"Non-Custodial"}},{path:"/blog/tags/Non-Custodial/index.html",redirect:"/blog/tags/Non-Custodial/"},{name:"v-2520b09b",path:"/blog/tags/liquidity/",component:Tc,beforeEnter:(t,e,n)=>{pc("FrontmatterPagination","v-2520b09b").then(n)},meta:{pid:"tags",id:"liquidity"}},{path:"/blog/tags/liquidity/index.html",redirect:"/blog/tags/liquidity/"},{name:"v-026b604a",path:"/blog/tags/0-Conf Channels/",component:Tc,beforeEnter:(t,e,n)=>{pc("FrontmatterPagination","v-026b604a").then(n)},meta:{pid:"tags",id:"0-Conf Channels"}},{path:"/blog/tags/0-Conf Channels/index.html",redirect:"/blog/tags/0-Conf Channels/"},{name:"v-27610544",path:"/blog/author/Wilmer Paulino/",component:Tc,beforeEnter:(t,e,n)=>{pc("FrontmatterPagination","v-27610544").then(n)},meta:{pid:"author",id:"Wilmer Paulino"}},{path:"/blog/author/Wilmer Paulino/index.html",redirect:"/blog/author/Wilmer Paulino/"},{name:"v-580ef260",path:"/blog/author/Elias Rohrer/",component:Tc,beforeEnter:(t,e,n)=>{pc("FrontmatterPagination","v-580ef260").then(n)},meta:{pid:"author",id:"Elias Rohrer"}},{path:"/blog/author/Elias Rohrer/index.html",redirect:"/blog/author/Elias Rohrer/"},{name:"v-5e0b95d8",path:"/blog/author/Matt Carvalho/",component:Tc,beforeEnter:(t,e,n)=>{pc("FrontmatterPagination","v-5e0b95d8").then(n)},meta:{pid:"author",id:"Matt Carvalho"}},{path:"/blog/author/Matt Carvalho/index.html",redirect:"/blog/author/Matt Carvalho/"},{name:"v-bf9b8e8a",path:"/blog/author/Jeff Czyz/",component:Tc,beforeEnter:(t,e,n)=>{pc("FrontmatterPagination","v-bf9b8e8a").then(n)},meta:{pid:"author",id:"Jeff Czyz"}},{path:"/blog/author/Jeff Czyz/index.html",redirect:"/blog/author/Jeff Czyz/"},{name:"v-571fde2c",path:"/blog/author/Ryan Loomba/",component:Tc,beforeEnter:(t,e,n)=>{pc("FrontmatterPagination","v-571fde2c").then(n)},meta:{pid:"author",id:"Ryan Loomba"}},{path:"/blog/author/Ryan Loomba/index.html",redirect:"/blog/author/Ryan Loomba/"},{name:"v-79994b30",path:"/blog/author/Arik Sosman/",component:Tc,beforeEnter:(t,e,n)=>{pc("FrontmatterPagination","v-79994b30").then(n)},meta:{pid:"author",id:"Arik Sosman"}},{path:"/blog/author/Arik Sosman/index.html",redirect:"/blog/author/Arik Sosman/"},{name:"v-54403322",path:"/blog/author/Valentine Wallace/",component:Tc,beforeEnter:(t,e,n)=>{pc("FrontmatterPagination","v-54403322").then(n)},meta:{pid:"author",id:"Valentine Wallace"}},{path:"/blog/author/Valentine Wallace/index.html",redirect:"/blog/author/Valentine Wallace/"},{name:"v-044cdb6b",path:"/blog/author/Conor Okus/",component:Tc,beforeEnter:(t,e,n)=>{pc("FrontmatterPagination","v-044cdb6b").then(n)},meta:{pid:"author",id:"Conor Okus"}},{path:"/blog/author/Conor Okus/index.html",redirect:"/blog/author/Conor Okus/"},{name:"v-39b7f2bf",path:"/blog/author/Steve Lee/",component:Tc,beforeEnter:(t,e,n)=>{pc("FrontmatterPagination","v-39b7f2bf").then(n)},meta:{pid:"author",id:"Steve Lee"}},{path:"/blog/author/Steve Lee/index.html",redirect:"/blog/author/Steve Lee/"},{name:"v-6a051305",path:"/blog/author/Ben Carman/",component:Tc,beforeEnter:(t,e,n)=>{pc("FrontmatterPagination","v-6a051305").then(n)},meta:{pid:"author",id:"Ben Carman"}},{path:"/blog/author/Ben Carman/index.html",redirect:"/blog/author/Ben Carman/"},{name:"v-c06ffaa8",path:"/blog/author/John Cantrell/",component:Tc,beforeEnter:(t,e,n)=>{pc("FrontmatterPagination","v-c06ffaa8").then(n)},meta:{pid:"author",id:"John Cantrell"}},{path:"/blog/author/John Cantrell/index.html",redirect:"/blog/author/John Cantrell/"},{name:"v-0c9ef90c",path:"/blog/author/Sergi Delgado/",component:Tc,beforeEnter:(t,e,n)=>{pc("FrontmatterPagination","v-0c9ef90c").then(n)},meta:{pid:"author",id:"Sergi Delgado"}},{path:"/blog/author/Sergi Delgado/index.html",redirect:"/blog/author/Sergi Delgado/"},{name:"v-438a3c44",path:"/blog/author/Matt Corallo/",component:Tc,beforeEnter:(t,e,n)=>{pc("FrontmatterPagination","v-438a3c44").then(n)},meta:{pid:"author",id:"Matt Corallo"}},{path:"/blog/author/Matt Corallo/index.html",redirect:"/blog/author/Matt Corallo/"},{name:"v-c3507bb6",path:"/blog/page/2/",component:Tc,beforeEnter:(t,e,n)=>{pc("DirectoryPagination","v-c3507bb6").then(n)},meta:{pid:"blog",id:"blog"}},{path:"/blog/page/2/index.html",redirect:"/blog/page/2/"},{path:"*",component:Tc}],Ec={title:"Lightning Dev Kit Documentation",description:"LDK is a flexible lightning implementation with supporting batteries (or modules).",base:"/",headTags:[["meta",{name:"viewport",content:"width=device-width,initial-scale=1.0"}],["link",{rel:"preload",href:"/fonts/ibm-plex-mono-400.woff2",as:"font",crossorigin:!0}],["link",{rel:"apple-touch-icon",sizes:"180x180",href:"/img/favicon/apple-touch-icon.png"}],["link",{rel:"manifest",href:"/site.webmanifest"}],["link",{rel:"stylesheet",href:"/css/variables.css"}],["link",{name:"msapplication-config",content:"/browserconfig.xml"}],["link",{name:"msapplication-TileColor",content:"#ffffff"}],["link",{name:"theme-color",content:"#ffffff"}]],pages:[{title:"Anchor Outputs Channels Are Here",frontmatter:{title:"Anchor Outputs Channels Are Here",description:"LDK v0.0.116 added support for opening channels with anchor outputs.",date:"2023-08-02",authors:["Wilmer Paulino"],tags:["Channels","Anchor Outputs","Fees"],meta:[{property:"article:published_time",content:"2023-08-02T00:00:00.000Z"},{property:"og:site_name",content:"Lightning Dev Kit Documentation"},{property:"og:title",content:"Anchor Outputs Channels Are Here"},{property:"og:description",content:"LDK v0.0.116 added support for opening channels with anchor outputs."},{property:"og:type",content:"article"},{property:"og:url",content:"https://lightningdevkit.org/_blog/anchor-outputs-channels-are-here/"},{property:"og:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:title",content:"Anchor Outputs Channels Are Here"},{name:"twitter:description",content:"LDK v0.0.116 added support for opening channels with anchor outputs."},{name:"twitter:url",content:"https://lightningdevkit.org/_blog/anchor-outputs-channels-are-here/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Channels, Anchor Outputs, Fees"},{property:"article:tag",content:"Channels"},{property:"article:tag",content:"Anchor Outputs"},{property:"article:tag",content:"Fees"}],layout:"Post",permalink:"/blog/:slug"},regularPath:"/_blog/anchor-outputs-channels-are-here.html",relativePath:"_blog/anchor-outputs-channels-are-here.md",key:"v-109b7b6a",path:"/blog/anchor-outputs-channels-are-here/",codeSwitcherOptions:{},id:"blog",pid:"blog",lastUpdated:"4/30/2024, 6:58:57 PM",lastUpdatedTimestamp:1714503537e3},{title:"Announcing LDK Node",frontmatter:{title:"Announcing LDK Node",description:"A ready-to-go Lightning node library built using LDK and BDK.",date:"2023-06-22",authors:["Elias Rohrer"],tags:["Self-custody","Mobile"],meta:[{property:"article:published_time",content:"2023-06-22T00:00:00.000Z"},{property:"og:site_name",content:"Lightning Dev Kit Documentation"},{property:"og:title",content:"Announcing LDK Node"},{property:"og:description",content:"A ready-to-go Lightning node library built using LDK and BDK."},{property:"og:type",content:"article"},{property:"og:url",content:"https://lightningdevkit.org/_blog/announcing-ldk-node/"},{property:"og:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:title",content:"Announcing LDK Node"},{name:"twitter:description",content:"A ready-to-go Lightning node library built using LDK and BDK."},{name:"twitter:url",content:"https://lightningdevkit.org/_blog/announcing-ldk-node/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Self-custody, Mobile"},{property:"article:tag",content:"Self-custody"},{property:"article:tag",content:"Mobile"}],layout:"Post",permalink:"/blog/:slug"},regularPath:"/_blog/announcing-ldk-node.html",relativePath:"_blog/announcing-ldk-node.md",key:"v-0f4e007e",path:"/blog/announcing-ldk-node/",headers:[{level:2,title:"A Lightweight Solution",slug:"a-lightweight-solution"},{level:2,title:"LDK Node: Simplifying Self-custodial Lightning Integration",slug:"ldk-node-simplifying-self-custodial-lightning-integration"},{level:2,title:"Mobile-first Self-Custody",slug:"mobile-first-self-custody"},{level:2,title:"Getting Started",slug:"getting-started"},{level:2,title:"Outlook",slug:"outlook"},{level:2,title:"Further Resources",slug:"further-resources"},{level:2,title:"Showcases",slug:"showcases"}],codeSwitcherOptions:{},id:"blog",pid:"blog",lastUpdated:"4/30/2024, 6:58:57 PM",lastUpdatedTimestamp:1714503537e3},{title:"Bitkit uses LDK to build the ultimate alternative to custodial wallets",frontmatter:{title:"Bitkit uses LDK to build the ultimate alternative to custodial wallets",description:"Learn how Bitkit uses LDK to build a cross platform mobile wallet",date:"2024-01-24",authors:["Matt Carvalho"],tags:["Case Studies"],meta:[{property:"article:published_time",content:"2024-01-24T00:00:00.000Z"},{property:"og:site_name",content:"Lightning Dev Kit Documentation"},{property:"og:title",content:"Bitkit uses LDK to build the ultimate alternative to custodial wallets"},{property:"og:description",content:"Learn how Bitkit uses LDK to build a cross platform mobile wallet"},{property:"og:type",content:"article"},{property:"og:url",content:"https://lightningdevkit.org/_blog/bitkit-uses-ldk-to-build-the-ultimate-alternative-to-custodial%20wallets/"},{property:"og:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:title",content:"Bitkit uses LDK to build the ultimate alternative to custodial wallets"},{name:"twitter:description",content:"Learn how Bitkit uses LDK to build a cross platform mobile wallet"},{name:"twitter:url",content:"https://lightningdevkit.org/_blog/bitkit-uses-ldk-to-build-the-ultimate-alternative-to-custodial%20wallets/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Case Studies"},{property:"article:tag",content:"Case Studies"}],layout:"Post",permalink:"/blog/:slug"},regularPath:"/_blog/bitkit-uses-ldk-to-build-the-ultimate-alternative-to-custodial%20wallets.html",relativePath:"_blog/bitkit-uses-ldk-to-build-the-ultimate-alternative-to-custodial wallets.md",key:"v-59a63080",path:"/blog/bitkit-uses-ldk-to-build-the-ultimate-alternative-to-custodial-wallets/",codeSwitcherOptions:{},id:"blog",pid:"blog",lastUpdated:"4/30/2024, 6:58:57 PM",lastUpdatedTimestamp:1714503537e3},{title:"BOLT12 Has Arrived",frontmatter:{title:"BOLT12 Has Arrived",description:"BOLT12 offers enhanced privacy, reusable payment codes, refunds, and much more, all natively over the Lightning Network.",date:"2024-04-30",authors:["Jeff Czyz"],tags:["Offers","Onion Messages","Privacy"],meta:[{property:"article:published_time",content:"2024-04-30T00:00:00.000Z"},{property:"og:site_name",content:"Lightning Dev Kit Documentation"},{property:"og:title",content:"BOLT12 Has Arrived"},{property:"og:description",content:"BOLT12 offers enhanced privacy, reusable payment codes, refunds, and much more, all natively over the Lightning Network."},{property:"og:type",content:"article"},{property:"og:url",content:"https://lightningdevkit.org/_blog/bolt12-has-arrived/"},{property:"og:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:title",content:"BOLT12 Has Arrived"},{name:"twitter:description",content:"BOLT12 offers enhanced privacy, reusable payment codes, refunds, and much more, all natively over the Lightning Network."},{name:"twitter:url",content:"https://lightningdevkit.org/_blog/bolt12-has-arrived/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Offers, Onion Messages, Privacy"},{property:"article:tag",content:"Offers"},{property:"article:tag",content:"Onion Messages"},{property:"article:tag",content:"Privacy"}],layout:"Post",permalink:"/blog/:slug"},regularPath:"/_blog/bolt12-has-arrived.html",relativePath:"_blog/bolt12-has-arrived.md",key:"v-6018492a",path:"/blog/bolt12-has-arrived/",headers:[{level:2,title:"BOLT11 Invoices and Reusability",slug:"bolt11-invoices-and-reusability"},{level:2,title:"BOLT12 to the Rescue",slug:"bolt12-to-the-rescue"},{level:2,title:"OK, so what about privacy?",slug:"ok-so-what-about-privacy"},{level:2,title:"Offers in LDK",slug:"offers-in-ldk"},{level:2,title:"Wait, what about refunds?",slug:"wait-what-about-refunds"},{level:2,title:"Achieving statelessness",slug:"achieving-statelessness"},{level:2,title:"What’s next?",slug:"what-s-next"}],codeSwitcherOptions:{},id:"blog",pid:"blog",lastUpdated:"4/30/2024, 6:58:57 PM",lastUpdatedTimestamp:1714503537e3},{title:"Cash App Enables Lightning Withdrawals & Deposits Using LDK",frontmatter:{title:"Cash App Enables Lightning Withdrawals & Deposits Using LDK",description:"Learn how Cash App integrated with the lightning network, allowing its users to send and receive bitcoin instantly.",date:"2022-11-17",authors:["Ryan Loomba"],tags:["Case Studies"],meta:[{property:"article:published_time",content:"2022-11-17T00:00:00.000Z"},{property:"og:site_name",content:"Lightning Dev Kit Documentation"},{property:"og:title",content:"Cash App Enables Lightning Withdrawals & Deposits Using LDK"},{property:"og:description",content:"Learn how Cash App integrated with the lightning network, allowing its users to send and receive bitcoin instantly."},{property:"og:type",content:"article"},{property:"og:url",content:"https://lightningdevkit.org/_blog/cashapp-enables-lightning-withdrawals-and-deposits-using-ldk/"},{property:"og:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:title",content:"Cash App Enables Lightning Withdrawals & Deposits Using LDK"},{name:"twitter:description",content:"Learn how Cash App integrated with the lightning network, allowing its users to send and receive bitcoin instantly."},{name:"twitter:url",content:"https://lightningdevkit.org/_blog/cashapp-enables-lightning-withdrawals-and-deposits-using-ldk/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Case Studies"},{property:"article:tag",content:"Case Studies"}],layout:"Post",permalink:"/blog/:slug"},regularPath:"/_blog/cashapp-enables-lightning-withdrawals-and-deposits-using-ldk.html",relativePath:"_blog/cashapp-enables-lightning-withdrawals-and-deposits-using-ldk.md",key:"v-e02a8a76",path:"/blog/cashapp-enables-lightning-withdrawals-and-deposits-using-ldk/",codeSwitcherOptions:{},id:"blog",pid:"blog",lastUpdated:"4/30/2024, 6:58:57 PM",lastUpdatedTimestamp:1714503537e3},{title:"Announcing Rapid Gossip Sync",frontmatter:{title:"Announcing Rapid Gossip Sync",description:"Rapid Gossip Sync is a protocol that allows nodes to catch up with channel gossip data by relying on semi-trusted servers.",date:"2022-08-30",authors:["Arik Sosman"],tags:["Gossip","Network Graph"],meta:[{property:"article:published_time",content:"2022-08-30T00:00:00.000Z"},{property:"og:site_name",content:"Lightning Dev Kit Documentation"},{property:"og:title",content:"Announcing Rapid Gossip Sync"},{property:"og:description",content:"Rapid Gossip Sync is a protocol that allows nodes to catch up with channel gossip data by relying on semi-trusted servers."},{property:"og:type",content:"article"},{property:"og:url",content:"https://lightningdevkit.org/_blog/announcing-rapid-gossip-sync/"},{property:"og:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:title",content:"Announcing Rapid Gossip Sync"},{name:"twitter:description",content:"Rapid Gossip Sync is a protocol that allows nodes to catch up with channel gossip data by relying on semi-trusted servers."},{name:"twitter:url",content:"https://lightningdevkit.org/_blog/announcing-rapid-gossip-sync/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Gossip, Network Graph"},{property:"article:tag",content:"Gossip"},{property:"article:tag",content:"Network Graph"}],layout:"Post",permalink:"/blog/:slug"},regularPath:"/_blog/announcing-rapid-gossip-sync.html",relativePath:"_blog/announcing-rapid-gossip-sync.md",key:"v-2578306f",path:"/blog/announcing-rapid-gossip-sync/",headers:[{level:2,title:"Exchanging Gossip Today",slug:"exchanging-gossip-today"},{level:2,title:"Rapid Gossip Sync",slug:"rapid-gossip-sync"},{level:2,title:"Rapid Gossip Sync Server",slug:"rapid-gossip-sync-server"},{level:2,title:"Trust Model",slug:"trust-model"},{level:2,title:"Conclusion",slug:"conclusion"}],codeSwitcherOptions:{},id:"blog",pid:"blog",lastUpdated:"4/30/2024, 6:58:57 PM",lastUpdatedTimestamp:1714503537e3},{title:"Introducing Phantom Node Payments",frontmatter:{title:"Introducing Phantom Node Payments",description:"Phantom node payments let enterprise users running high-volume lightning nodes generate invoices that can be paid to one of multiple production nodes.",date:"2022-07-11",authors:["Valentine Wallace"],tags:["Enterprise","Phantom"],meta:[{property:"article:published_time",content:"2022-07-11T00:00:00.000Z"},{property:"og:site_name",content:"Lightning Dev Kit Documentation"},{property:"og:title",content:"Introducing Phantom Node Payments"},{property:"og:description",content:"Phantom node payments let enterprise users running high-volume lightning nodes generate invoices that can be paid to one of multiple production nodes."},{property:"og:type",content:"article"},{property:"og:url",content:"https://lightningdevkit.org/_blog/introducing-phantom-node-payments/"},{property:"og:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:title",content:"Introducing Phantom Node Payments"},{name:"twitter:description",content:"Phantom node payments let enterprise users running high-volume lightning nodes generate invoices that can be paid to one of multiple production nodes."},{name:"twitter:url",content:"https://lightningdevkit.org/_blog/introducing-phantom-node-payments/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Enterprise, Phantom"},{property:"article:tag",content:"Enterprise"},{property:"article:tag",content:"Phantom"}],layout:"Post",permalink:"/blog/:slug"},regularPath:"/_blog/introducing-phantom-node-payments.html",relativePath:"_blog/introducing-phantom-node-payments.md",key:"v-177ef1fe",path:"/blog/introducing-phantom-node-payments/",headers:[{level:2,title:"Phantom Payment Flow",slug:"phantom-payment-flow"},{level:2,title:"Why It’s OK to Not Support MPP",slug:"why-it-s-ok-to-not-support-mpp"},{level:2,title:"Why MPP Shouldn’t Be Enabled",slug:"why-mpp-shouldn-t-be-enabled"}],codeSwitcherOptions:{},id:"blog",pid:"blog",lastUpdated:"4/30/2024, 6:58:57 PM",lastUpdatedTimestamp:1714503537e3},{title:"LDK: An SDK for the Lightning Network",frontmatter:{title:"LDK: An SDK for the Lightning Network",description:"Learn how LDK improves DX, makes it easier to work with Lightning functionality, and makes building faster for your entire team in our newly launched blog.",date:"2022-06-20",authors:["Conor Okus"],tags:["Bitcoin","LDK"],meta:[{property:"article:published_time",content:"2022-06-20T00:00:00.000Z"},{property:"og:site_name",content:"Lightning Dev Kit Documentation"},{property:"og:title",content:"LDK: An SDK for the Lightning Network"},{property:"og:description",content:"Learn how LDK improves DX, makes it easier to work with Lightning functionality, and makes building faster for your entire team in our newly launched blog."},{property:"og:type",content:"article"},{property:"og:url",content:"https://lightningdevkit.org/_blog/ldk-an-sdk-for-the-lightning-network/"},{property:"og:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:title",content:"LDK: An SDK for the Lightning Network"},{name:"twitter:description",content:"Learn how LDK improves DX, makes it easier to work with Lightning functionality, and makes building faster for your entire team in our newly launched blog."},{name:"twitter:url",content:"https://lightningdevkit.org/_blog/ldk-an-sdk-for-the-lightning-network/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, LDK"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"LDK"}],layout:"Post",permalink:"/blog/:slug"},regularPath:"/_blog/ldk-an-sdk-for-the-lightning-network.html",relativePath:"_blog/ldk-an-sdk-for-the-lightning-network.md",key:"v-eebe6fe6",path:"/blog/ldk-an-sdk-for-the-lightning-network/",headers:[{level:2,title:"LDWho?",slug:"ldwho"},{level:2,title:"What advantages does LDK offer developers?",slug:"what-advantages-does-ldk-offer-developers"},{level:2,title:"Who uses LDK?",slug:"who-uses-ldk"},{level:2,title:"What are LDK’s engineering priorities?",slug:"what-are-ldk-s-engineering-priorities"},{level:2,title:"Notable Updates",slug:"notable-updates"}],codeSwitcherOptions:{},id:"blog",pid:"blog",lastUpdated:"4/30/2024, 6:58:57 PM",lastUpdatedTimestamp:1714503537e3},{title:"LDK Roadmap",frontmatter:{title:"LDK Roadmap",description:"LDK is going to have a big year. Several key features are actively being developed or expected to be developed in the next few quarters.",date:"2023-03-13",authors:["Steve Lee"],tags:["Roadmap"],meta:[{property:"article:published_time",content:"2023-03-13T00:00:00.000Z"},{property:"og:site_name",content:"Lightning Dev Kit Documentation"},{property:"og:title",content:"LDK Roadmap"},{property:"og:description",content:"LDK is going to have a big year. Several key features are actively being developed or expected to be developed in the next few quarters."},{property:"og:type",content:"article"},{property:"og:url",content:"https://lightningdevkit.org/_blog/ldk-roadmap/"},{property:"og:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:title",content:"LDK Roadmap"},{name:"twitter:description",content:"LDK is going to have a big year. Several key features are actively being developed or expected to be developed in the next few quarters."},{name:"twitter:url",content:"https://lightningdevkit.org/_blog/ldk-roadmap/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Roadmap"},{property:"article:tag",content:"Roadmap"}],layout:"Post",permalink:"/blog/:slug"},regularPath:"/_blog/ldk-roadmap.html",relativePath:"_blog/ldk-roadmap.md",key:"v-7b0f0961",path:"/blog/ldk-roadmap/",headers:[{level:2,title:"LDK Node",slug:"ldk-node"},{level:2,title:"BOLT 12",slug:"bolt-12"},{level:2,title:"Anchor Outputs",slug:"anchor-outputs"},{level:2,title:"VSS",slug:"vss"},{level:2,title:"Improved Async-ness in LDK API",slug:"improved-async-ness-in-ldk-api"},{level:2,title:"Simple Taproot Channels",slug:"simple-taproot-channels"},{level:2,title:"Dual-Funded Channels",slug:"dual-funded-channels"},{level:2,title:"Splicing",slug:"splicing"},{level:2,title:"Async Payments",slug:"async-payments"},{level:2,title:"PTLCs",slug:"ptlcs"},{level:2,title:"Additional Language Bindings",slug:"additional-language-bindings"},{level:2,title:"Custom Scripts",slug:"custom-scripts"},{level:2,title:"Dynamic Commitments",slug:"dynamic-commitments"}],codeSwitcherOptions:{},id:"blog",pid:"blog",lastUpdated:"4/30/2024, 6:58:57 PM",lastUpdatedTimestamp:1714503537e3},{title:"Mutiny uses LDK to create the first lightning wallet for the web",frontmatter:{title:"Mutiny uses LDK to create the first lightning wallet for the web",description:"Learn how Mutiny built a lightning wallet for the web",date:"2023-08-07",authors:["Ben Carman"],tags:["Case Studies"],meta:[{property:"article:published_time",content:"2023-08-07T00:00:00.000Z"},{property:"og:site_name",content:"Lightning Dev Kit Documentation"},{property:"og:title",content:"Mutiny uses LDK to create the first lightning wallet for the web"},{property:"og:description",content:"Learn how Mutiny built a lightning wallet for the web"},{property:"og:type",content:"article"},{property:"og:url",content:"https://lightningdevkit.org/_blog/mutiny-uses-ldk-the-first-lightning-wallet-for-the-web/"},{property:"og:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:title",content:"Mutiny uses LDK to create the first lightning wallet for the web"},{name:"twitter:description",content:"Learn how Mutiny built a lightning wallet for the web"},{name:"twitter:url",content:"https://lightningdevkit.org/_blog/mutiny-uses-ldk-the-first-lightning-wallet-for-the-web/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Case Studies"},{property:"article:tag",content:"Case Studies"}],layout:"Post",permalink:"/blog/:slug"},regularPath:"/_blog/mutiny-uses-ldk-the-first-lightning-wallet-for-the-web.html",relativePath:"_blog/mutiny-uses-ldk-the-first-lightning-wallet-for-the-web.md",key:"v-61c088e6",path:"/blog/mutiny-uses-ldk-the-first-lightning-wallet-for-the-web/",codeSwitcherOptions:{},id:"blog",pid:"blog",lastUpdated:"4/30/2024, 6:58:57 PM",lastUpdatedTimestamp:1714503537e3},{title:"Onion Messages Demystified",frontmatter:{title:"Onion Messages Demystified",description:"We recently merged support for onion message forwarding, a precursor to deprecating today’s Lightning invoice format, in favor of offers.",date:"2022-10-04",authors:["Valentine Wallace"],tags:["Onion Messages","Offers"],meta:[{property:"article:published_time",content:"2022-10-04T00:00:00.000Z"},{property:"og:site_name",content:"Lightning Dev Kit Documentation"},{property:"og:title",content:"Onion Messages Demystified"},{property:"og:description",content:"We recently merged support for onion message forwarding, a precursor to deprecating today’s Lightning invoice format, in favor of offers."},{property:"og:type",content:"article"},{property:"og:url",content:"https://lightningdevkit.org/_blog/onion-messages-demystified/"},{property:"og:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:title",content:"Onion Messages Demystified"},{name:"twitter:description",content:"We recently merged support for onion message forwarding, a precursor to deprecating today’s Lightning invoice format, in favor of offers."},{name:"twitter:url",content:"https://lightningdevkit.org/_blog/onion-messages-demystified/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Onion Messages, Offers"},{property:"article:tag",content:"Onion Messages"},{property:"article:tag",content:"Offers"}],layout:"Post",permalink:"/blog/:slug"},regularPath:"/_blog/onion-messages-demystified.html",relativePath:"_blog/onion-messages-demystified.md",key:"v-7b672071",path:"/blog/onion-messages-demystified/",headers:[{level:2,title:"How Onion Messages Work",slug:"how-onion-messages-work"},{level:2,title:"Blinded Routes",slug:"blinded-routes"},{level:2,title:"Onion Message Structure",slug:"onion-message-structure"},{level:2,title:"Beyond Offers: Asynchronous Payments",slug:"beyond-offers-asynchronous-payments"},{level:2,title:"Future Security Directions",slug:"future-security-directions"},{level:2,title:"Seeya",slug:"seeya"}],codeSwitcherOptions:{},id:"blog",pid:"blog",lastUpdated:"4/30/2024, 6:58:57 PM",lastUpdatedTimestamp:1714503537e3},{title:"Sensei uses LDK to Build a Multi-Node Lightning Server App",frontmatter:{title:"Sensei uses LDK to Build a Multi-Node Lightning Server App",description:"Learn how Sensei built a lightning node app to serve many nodes",date:"2022-12-20",authors:["John Cantrell"],tags:["Case Studies"],meta:[{property:"article:published_time",content:"2022-12-20T00:00:00.000Z"},{property:"og:site_name",content:"Lightning Dev Kit Documentation"},{property:"og:title",content:"Sensei uses LDK to Build a Multi-Node Lightning Server App"},{property:"og:description",content:"Learn how Sensei built a lightning node app to serve many nodes"},{property:"og:type",content:"article"},{property:"og:url",content:"https://lightningdevkit.org/_blog/sensei-uses-ldk-to-build-a-multi-node-lightning-server-application/"},{property:"og:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:title",content:"Sensei uses LDK to Build a Multi-Node Lightning Server App"},{name:"twitter:description",content:"Learn how Sensei built a lightning node app to serve many nodes"},{name:"twitter:url",content:"https://lightningdevkit.org/_blog/sensei-uses-ldk-to-build-a-multi-node-lightning-server-application/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Case Studies"},{property:"article:tag",content:"Case Studies"}],layout:"Post",permalink:"/blog/:slug"},regularPath:"/_blog/sensei-uses-ldk-to-build-a-multi-node-lightning-server-application.html",relativePath:"_blog/sensei-uses-ldk-to-build-a-multi-node-lightning-server-application.md",key:"v-394e384e",path:"/blog/sensei-uses-ldk-to-build-a-multi-node-lightning-server-application/",codeSwitcherOptions:{},id:"blog",pid:"blog",lastUpdated:"4/30/2024, 6:58:57 PM",lastUpdatedTimestamp:1714503537e3},{title:"TEOS uses LDK to build open-source watchtower",frontmatter:{title:"TEOS uses LDK to build open-source watchtower",description:"Learn how TEOS built an open-source watchtower",date:"2023-01-18",authors:["Sergi Delgado"],tags:["Case Studies"],meta:[{property:"article:published_time",content:"2023-01-18T00:00:00.000Z"},{property:"og:site_name",content:"Lightning Dev Kit Documentation"},{property:"og:title",content:"TEOS uses LDK to build open-source watchtower"},{property:"og:description",content:"Learn how TEOS built an open-source watchtower"},{property:"og:type",content:"article"},{property:"og:url",content:"https://lightningdevkit.org/_blog/teos-uses-ldk-to-build-open-source-watchtower/"},{property:"og:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:title",content:"TEOS uses LDK to build open-source watchtower"},{name:"twitter:description",content:"Learn how TEOS built an open-source watchtower"},{name:"twitter:url",content:"https://lightningdevkit.org/_blog/teos-uses-ldk-to-build-open-source-watchtower/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Case Studies"},{property:"article:tag",content:"Case Studies"}],layout:"Post",permalink:"/blog/:slug"},regularPath:"/_blog/teos-uses-ldk-to-build-open-source-watchtower.html",relativePath:"_blog/teos-uses-ldk-to-build-open-source-watchtower.md",key:"v-4ffe1afe",path:"/blog/teos-uses-ldk-to-build-open-source-watchtower/",codeSwitcherOptions:{},id:"blog",pid:"blog",lastUpdated:"4/30/2024, 6:58:57 PM",lastUpdatedTimestamp:1714503537e3},{title:"The Challenges of Developing Non-Custodial Lightning on Mobile",frontmatter:{title:"The Challenges of Developing Non-Custodial Lightning on Mobile",description:"Lightning development is tough. While going custodial simplifies the process, it means sacrificing user privacy, censorship resistance, and self-sovereignty, all of which contradict bitcoin’s ethos.",date:"2023-12-14",authors:["Matt Corallo"],tags:["Mobile","Non-Custodial"],meta:[{property:"article:published_time",content:"2023-12-14T00:00:00.000Z"},{property:"og:site_name",content:"Lightning Dev Kit Documentation"},{property:"og:title",content:"The Challenges of Developing Non-Custodial Lightning on Mobile"},{property:"og:description",content:"Lightning development is tough. While going custodial simplifies the process, it means sacrificing user privacy, censorship resistance, and self-sovereignty, all of which contradict bitcoin’s ethos."},{property:"og:type",content:"article"},{property:"og:url",content:"https://lightningdevkit.org/_blog/the-challenges-of-developing-non-custodial-lightning-on-mobile/"},{property:"og:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:title",content:"The Challenges of Developing Non-Custodial Lightning on Mobile"},{name:"twitter:description",content:"Lightning development is tough. While going custodial simplifies the process, it means sacrificing user privacy, censorship resistance, and self-sovereignty, all of which contradict bitcoin’s ethos."},{name:"twitter:url",content:"https://lightningdevkit.org/_blog/the-challenges-of-developing-non-custodial-lightning-on-mobile/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Mobile, Non-Custodial"},{property:"article:tag",content:"Mobile"},{property:"article:tag",content:"Non-Custodial"}],layout:"Post",permalink:"/blog/:slug"},regularPath:"/_blog/the-challenges-of-developing-non-custodial-lightning-on-mobile.html",relativePath:"_blog/the-challenges-of-developing-non-custodial-lightning-on-mobile.md",key:"v-67ea603f",path:"/blog/the-challenges-of-developing-non-custodial-lightning-on-mobile/",headers:[{level:2,title:"Obstacles",slug:"obstacles"},{level:2,title:"Liquidity",slug:"liquidity"}],codeSwitcherOptions:{},id:"blog",pid:"blog",lastUpdated:"4/30/2024, 6:58:57 PM",lastUpdatedTimestamp:1714503537e3},{title:'Unleashing Liquidity on the Lightning Network with "lightning-liquidity"',frontmatter:{title:'Unleashing Liquidity on the Lightning Network with "lightning-liquidity"',description:"The lightning-liquidity crate is an easy-to-integrate rust library that wallet developers and LSP operators can use to implement the LSP specification",date:"2024-02-29",authors:["John Cantrell"],tags:["liquidity"],meta:[{property:"article:published_time",content:"2024-02-29T00:00:00.000Z"},{property:"og:site_name",content:"Lightning Dev Kit Documentation"},{property:"og:title",content:'Unleashing Liquidity on the Lightning Network with "lightning-liquidity"'},{property:"og:description",content:"The lightning-liquidity crate is an easy-to-integrate rust library that wallet developers and LSP operators can use to implement the LSP specification"},{property:"og:type",content:"article"},{property:"og:url",content:"https://lightningdevkit.org/_blog/unleashing-liquidity-on-the-lightning-network-with-lightning-liquidity/"},{property:"og:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:title",content:'Unleashing Liquidity on the Lightning Network with "lightning-liquidity"'},{name:"twitter:description",content:"The lightning-liquidity crate is an easy-to-integrate rust library that wallet developers and LSP operators can use to implement the LSP specification"},{name:"twitter:url",content:"https://lightningdevkit.org/_blog/unleashing-liquidity-on-the-lightning-network-with-lightning-liquidity/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"liquidity"},{property:"article:tag",content:"liquidity"}],layout:"Post",permalink:"/blog/:slug"},regularPath:"/_blog/unleashing-liquidity-on-the-lightning-network-with-lightning-liquidity.html",relativePath:"_blog/unleashing-liquidity-on-the-lightning-network-with-lightning-liquidity.md",key:"v-4c78f51d",path:"/blog/unleashing-liquidity-on-the-lightning-network-with-lightning-liquidity/",headers:[{level:2,title:"How It All Started: Lightning's Liquidity Problem",slug:"how-it-all-started-lightnings-liquidity-problem"},{level:2,title:"Current Approaches and Their Shortcomings",slug:"current-approaches-and-their-shortcomings"},{level:2,title:"A Unified Solution: The Standardization Effort",slug:"a-unified-solution-the-standardization-effort"},{level:2,title:"Just-In-Time Channels: A Cornerstone of the New Protocol",slug:"just-in-time-channels-a-cornerstone-of-the-new-protocol"},{level:2,title:"Introducing lightning-liquidity",slug:"introducing-lightning-liquidity"},{level:2,title:"How It Works: For Developers and Businesses",slug:"how-it-works-for-developers-and-businesses"},{level:2,title:"Join Us in Shaping the Future",slug:"join-us-in-shaping-the-future"}],codeSwitcherOptions:{},id:"blog",pid:"blog",lastUpdated:"4/30/2024, 6:58:57 PM",lastUpdatedTimestamp:1714503537e3},{title:"Zero-Confirmation Channels",frontmatter:{title:"Zero-Confirmation Channels",description:"A 0-conf channel allows peers to start using a channel as soon as the funding transaction is broadcast.",date:"2022-09-15",authors:["John Cantrell"],tags:["0-Conf Channels"],meta:[{property:"article:published_time",content:"2022-09-15T00:00:00.000Z"},{property:"og:site_name",content:"Lightning Dev Kit Documentation"},{property:"og:title",content:"Zero-Confirmation Channels"},{property:"og:description",content:"A 0-conf channel allows peers to start using a channel as soon as the funding transaction is broadcast."},{property:"og:type",content:"article"},{property:"og:url",content:"https://lightningdevkit.org/_blog/zero-confirmation-channels/"},{property:"og:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:title",content:"Zero-Confirmation Channels"},{name:"twitter:description",content:"A 0-conf channel allows peers to start using a channel as soon as the funding transaction is broadcast."},{name:"twitter:url",content:"https://lightningdevkit.org/_blog/zero-confirmation-channels/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"0-Conf Channels"},{property:"article:tag",content:"0-Conf Channels"}],layout:"Post",permalink:"/blog/:slug"},regularPath:"/_blog/zero-confirmation-channels.html",relativePath:"_blog/zero-confirmation-channels.md",key:"v-3843152b",path:"/blog/zero-confirmation-channels/",headers:[{level:2,title:"What is a confirmation?",slug:"what-is-a-confirmation"},{level:2,title:"Why does the number of confirmations matter?",slug:"why-does-the-number-of-confirmations-matter"},{level:2,title:"What does this have to do with the Lightning Network?",slug:"what-does-this-have-to-do-with-the-lightning-network"},{level:2,title:"Why or when might 0-conf channels be useful?",slug:"why-or-when-might-0-conf-channels-be-useful"},{level:2,title:"Conclusion",slug:"conclusion"}],codeSwitcherOptions:{},id:"blog",pid:"blog",lastUpdated:"4/30/2024, 6:58:57 PM",lastUpdatedTimestamp:1714503537e3},{title:"Block Source",frontmatter:{meta:[{property:"og:site_name",content:"Lightning Dev Kit Documentation"},{property:"og:title",content:"Block Source"},{property:"og:description",content:"Implementing the `BlockSource` interface requires defining methods for fetching\nheaders, blocks, and the best block hash."},{property:"og:type",content:"article"},{property:"og:url",content:"https://lightningdevkit.org/blockchain_data/block_source/"},{property:"og:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:title",content:"Block Source"},{name:"twitter:description",content:"Implementing the `BlockSource` interface requires defining methods for fetching\nheaders, blocks, and the best block hash."},{name:"twitter:url",content:"https://lightningdevkit.org/blockchain_data/block_source/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Lightning, LDK, Lightning Dev Kit, Documentation"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Lightning"},{property:"article:tag",content:"LDK"},{property:"article:tag",content:"Lightning Dev Kit"},{property:"article:tag",content:"Documentation"}]},regularPath:"/blockchain_data/block_source.html",relativePath:"blockchain_data/block_source.md",key:"v-e5335502",path:"/blockchain_data/block_source/",codeSwitcherOptions:{},lastUpdated:"4/30/2024, 6:58:57 PM",lastUpdatedTimestamp:1714503537e3},{title:"Chain Activity",frontmatter:{meta:[{property:"og:site_name",content:"Lightning Dev Kit Documentation"},{property:"og:title",content:"Chain Activity"},{property:"og:description",content:"Initially, our node doesn't have any channels and hence has no data to monitor\nfor on-chain. When a channel is opened with a peer, the `ChannelManager` creates\na `ChannelMonitor` and passes it to the `ChainMonitor` to watch."},{property:"og:type",content:"article"},{property:"og:url",content:"https://lightningdevkit.org/blockchain_data/chain_activity/"},{property:"og:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:title",content:"Chain Activity"},{name:"twitter:description",content:"Initially, our node doesn't have any channels and hence has no data to monitor\nfor on-chain. When a channel is opened with a peer, the `ChannelManager` creates\na `ChannelMonitor` and passes it to the `ChainMonitor` to watch."},{name:"twitter:url",content:"https://lightningdevkit.org/blockchain_data/chain_activity/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Lightning, LDK, Lightning Dev Kit, Documentation"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Lightning"},{property:"article:tag",content:"LDK"},{property:"article:tag",content:"Lightning Dev Kit"},{property:"article:tag",content:"Documentation"}]},regularPath:"/blockchain_data/chain_activity.html",relativePath:"blockchain_data/chain_activity.md",key:"v-3dc27382",path:"/blockchain_data/chain_activity/",codeSwitcherOptions:{},lastUpdated:"4/30/2024, 6:58:57 PM",lastUpdatedTimestamp:1714503537e3},{title:"Confirmed Transactions",frontmatter:{meta:[{property:"og:site_name",content:"Lightning Dev Kit Documentation"},{property:"og:title",content:"Confirmed Transactions"},{property:"og:description",content:"Up until this point, we've explored how to notify LDK of chain activity using\nblocks. But what if you're sourcing chain activity from a place that doesn't\nprovide a block-centric interface, like Electrum?"},{property:"og:type",content:"article"},{property:"og:url",content:"https://lightningdevkit.org/blockchain_data/confirmed_transactions/"},{property:"og:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:title",content:"Confirmed Transactions"},{name:"twitter:description",content:"Up until this point, we've explored how to notify LDK of chain activity using\nblocks. But what if you're sourcing chain activity from a place that doesn't\nprovide a block-centric interface, like Electrum?"},{name:"twitter:url",content:"https://lightningdevkit.org/blockchain_data/confirmed_transactions/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Lightning, LDK, Lightning Dev Kit, Documentation"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Lightning"},{property:"article:tag",content:"LDK"},{property:"article:tag",content:"Lightning Dev Kit"},{property:"article:tag",content:"Documentation"}]},regularPath:"/blockchain_data/confirmed_transactions.html",relativePath:"blockchain_data/confirmed_transactions.md",key:"v-7da54c6f",path:"/blockchain_data/confirmed_transactions/",codeSwitcherOptions:{},lastUpdated:"4/30/2024, 6:58:57 PM",lastUpdatedTimestamp:1714503537e3},{title:"Full Blocks",frontmatter:{meta:[{property:"og:site_name",content:"Lightning Dev Kit Documentation"},{property:"og:title",content:"Full Blocks"},{property:"og:description",content:"If your Lightning node is backed by a Bitcoin full node, the operation is\nstraight forward: call the appropriate methods on `ChannelManager` and"},{property:"og:type",content:"article"},{property:"og:url",content:"https://lightningdevkit.org/blockchain_data/full_blocks/"},{property:"og:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:title",content:"Full Blocks"},{name:"twitter:description",content:"If your Lightning node is backed by a Bitcoin full node, the operation is\nstraight forward: call the appropriate methods on `ChannelManager` and"},{name:"twitter:url",content:"https://lightningdevkit.org/blockchain_data/full_blocks/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Lightning, LDK, Lightning Dev Kit, Documentation"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Lightning"},{property:"article:tag",content:"LDK"},{property:"article:tag",content:"Lightning Dev Kit"},{property:"article:tag",content:"Documentation"}]},regularPath:"/blockchain_data/full_blocks.html",relativePath:"blockchain_data/full_blocks.md",key:"v-3efb3c3e",path:"/blockchain_data/full_blocks/",codeSwitcherOptions:{},lastUpdated:"4/30/2024, 6:58:57 PM",lastUpdatedTimestamp:1714503537e3},{title:"Introduction",frontmatter:{meta:[{property:"og:site_name",content:"Lightning Dev Kit Documentation"},{property:"og:title",content:"Introduction"},{property:"og:description",content:"In this guide, we'll explore how to provide chain data to LDK upon startup and\nas new blocks are mined. This allows LDK to maintain channel state and monitor\nfor on-chain channel activity."},{property:"og:type",content:"article"},{property:"og:url",content:"https://lightningdevkit.org/blockchain_data/introduction/"},{property:"og:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:title",content:"Introduction"},{name:"twitter:description",content:"In this guide, we'll explore how to provide chain data to LDK upon startup and\nas new blocks are mined. This allows LDK to maintain channel state and monitor\nfor on-chain channel activity."},{name:"twitter:url",content:"https://lightningdevkit.org/blockchain_data/introduction/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Lightning, LDK, Lightning Dev Kit, Documentation"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Lightning"},{property:"article:tag",content:"LDK"},{property:"article:tag",content:"Lightning Dev Kit"},{property:"article:tag",content:"Documentation"}]},regularPath:"/blockchain_data/introduction.html",relativePath:"blockchain_data/introduction.md",key:"v-2f9b6cb6",path:"/blockchain_data/introduction/",headers:[{level:2,title:"Introduction",slug:"introduction"}],codeSwitcherOptions:{},lastUpdated:"4/30/2024, 6:58:57 PM",lastUpdatedTimestamp:1714503537e3},{title:"Pre-filtered Blocks",frontmatter:{meta:[{property:"og:site_name",content:"Lightning Dev Kit Documentation"},{property:"og:title",content:"Pre-filtered Blocks"},{property:"og:description",content:"For environments that are resource constrained, receiving and processing all\ntransaction data may not be feasible. LDK handles this case by signaling back\nwhich transactions and outputs it is interested in. This information can then be\nused to filter blocks prior to sending them to your node."},{property:"og:type",content:"article"},{property:"og:url",content:"https://lightningdevkit.org/blockchain_data/pre_filtered_blocks/"},{property:"og:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:title",content:"Pre-filtered Blocks"},{name:"twitter:description",content:"For environments that are resource constrained, receiving and processing all\ntransaction data may not be feasible. LDK handles this case by signaling back\nwhich transactions and outputs it is interested in. This information can then be\nused to filter blocks prior to sending them to your node."},{name:"twitter:url",content:"https://lightningdevkit.org/blockchain_data/pre_filtered_blocks/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Lightning, LDK, Lightning Dev Kit, Documentation"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Lightning"},{property:"article:tag",content:"LDK"},{property:"article:tag",content:"Lightning Dev Kit"},{property:"article:tag",content:"Documentation"}]},regularPath:"/blockchain_data/pre_filtered_blocks.html",relativePath:"blockchain_data/pre_filtered_blocks.md",key:"v-66b18f61",path:"/blockchain_data/pre_filtered_blocks/",codeSwitcherOptions:{},lastUpdated:"4/30/2024, 6:58:57 PM",lastUpdatedTimestamp:1714503537e3},{title:"Transaction Broadcasting",frontmatter:{meta:[{property:"og:site_name",content:"Lightning Dev Kit Documentation"},{property:"og:title",content:"Transaction Broadcasting"},{property:"og:description",content:"Inevitably, LDK will need to broadcast transactions on your behalf. As you\nnotify it of blocks, it will determine if it should broadcast a transaction and\ndo so using an implementation of `BroadcasterInterface` that you have provided."},{property:"og:type",content:"article"},{property:"og:url",content:"https://lightningdevkit.org/blockchain_data/transaction_broadcasting/"},{property:"og:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:title",content:"Transaction Broadcasting"},{name:"twitter:description",content:"Inevitably, LDK will need to broadcast transactions on your behalf. As you\nnotify it of blocks, it will determine if it should broadcast a transaction and\ndo so using an implementation of `BroadcasterInterface` that you have provided."},{name:"twitter:url",content:"https://lightningdevkit.org/blockchain_data/transaction_broadcasting/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Lightning, LDK, Lightning Dev Kit, Documentation"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Lightning"},{property:"article:tag",content:"LDK"},{property:"article:tag",content:"Lightning Dev Kit"},{property:"article:tag",content:"Documentation"}]},regularPath:"/blockchain_data/transaction_broadcasting.html",relativePath:"blockchain_data/transaction_broadcasting.md",key:"v-6b753255",path:"/blockchain_data/transaction_broadcasting/",codeSwitcherOptions:{},lastUpdated:"4/30/2024, 6:58:57 PM",lastUpdatedTimestamp:1714503537e3},{title:"Closing a Channel",frontmatter:{meta:[{property:"og:site_name",content:"Lightning Dev Kit Documentation"},{property:"og:title",content:"Closing a Channel"},{property:"og:description",content:"Begins the process of closing a channel. After this call plus some timeout, no new HTLCs will be accepted on the given channel, and after additional timeout/the closing of all pending HTLCs, the channel will be closed on chain."},{property:"og:type",content:"article"},{property:"og:url",content:"https://lightningdevkit.org/building-a-node-with-ldk/closing-a-channel/"},{property:"og:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:title",content:"Closing a Channel"},{name:"twitter:description",content:"Begins the process of closing a channel. After this call plus some timeout, no new HTLCs will be accepted on the given channel, and after additional timeout/the closing of all pending HTLCs, the channel will be closed on chain."},{name:"twitter:url",content:"https://lightningdevkit.org/building-a-node-with-ldk/closing-a-channel/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Lightning, LDK, Lightning Dev Kit, Documentation"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Lightning"},{property:"article:tag",content:"LDK"},{property:"article:tag",content:"Lightning Dev Kit"},{property:"article:tag",content:"Documentation"}]},regularPath:"/building-a-node-with-ldk/closing-a-channel.html",relativePath:"building-a-node-with-ldk/closing-a-channel.md",key:"v-0c8784ee",path:"/building-a-node-with-ldk/closing-a-channel/",codeSwitcherOptions:{},lastUpdated:"4/30/2024, 6:58:57 PM",lastUpdatedTimestamp:1714503537e3},{title:"Connect to Peers",frontmatter:{meta:[{property:"og:site_name",content:"Lightning Dev Kit Documentation"},{property:"og:title",content:"Connect to Peers"},{property:"og:description",content:"In this section you'll learn how to join the lightning network."},{property:"og:type",content:"article"},{property:"og:url",content:"https://lightningdevkit.org/building-a-node-with-ldk/connect-to-peers/"},{property:"og:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:title",content:"Connect to Peers"},{name:"twitter:description",content:"In this section you'll learn how to join the lightning network."},{name:"twitter:url",content:"https://lightningdevkit.org/building-a-node-with-ldk/connect-to-peers/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Lightning, LDK, Lightning Dev Kit, Documentation"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Lightning"},{property:"article:tag",content:"LDK"},{property:"article:tag",content:"Lightning Dev Kit"},{property:"article:tag",content:"Documentation"}]},regularPath:"/building-a-node-with-ldk/connect-to-peers.html",relativePath:"building-a-node-with-ldk/connect-to-peers.md",key:"v-2e33a981",path:"/building-a-node-with-ldk/connect-to-peers/",codeSwitcherOptions:{},lastUpdated:"4/30/2024, 6:58:57 PM",lastUpdatedTimestamp:1714503537e3},{title:"Getting started",frontmatter:{meta:[{property:"og:site_name",content:"Lightning Dev Kit Documentation"},{property:"og:title",content:"Getting started"},{property:"og:description",content:"Welcome to the Lightning Development Kit documentation!"},{property:"og:type",content:"article"},{property:"og:url",content:"https://lightningdevkit.org/building-a-node-with-ldk/installation/"},{property:"og:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:title",content:"Getting started"},{name:"twitter:description",content:"Welcome to the Lightning Development Kit documentation!"},{name:"twitter:url",content:"https://lightningdevkit.org/building-a-node-with-ldk/installation/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Lightning, LDK, Lightning Dev Kit, Documentation"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Lightning"},{property:"article:tag",content:"LDK"},{property:"article:tag",content:"Lightning Dev Kit"},{property:"article:tag",content:"Documentation"}]},regularPath:"/building-a-node-with-ldk/installation.html",relativePath:"building-a-node-with-ldk/installation.md",key:"v-208c95fe",path:"/building-a-node-with-ldk/installation/",headers:[{level:2,title:"Installation",slug:"installation"}],codeSwitcherOptions:{},lastUpdated:"4/30/2024, 6:58:57 PM",lastUpdatedTimestamp:1714503537e3},{title:"Building a Node with LDK",frontmatter:{meta:[{property:"og:site_name",content:"Lightning Dev Kit Documentation"},{property:"og:title",content:"Building a Node with LDK"},{property:"og:description",content:"For an integrated example of an LDK node in Rust, see the Sample Nodehttps://github.com/lightningdevkit/ldk-sample"},{property:"og:type",content:"article"},{property:"og:url",content:"https://lightningdevkit.org/building-a-node-with-ldk/introduction/"},{property:"og:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:title",content:"Building a Node with LDK"},{name:"twitter:description",content:"For an integrated example of an LDK node in Rust, see the Sample Nodehttps://github.com/lightningdevkit/ldk-sample"},{name:"twitter:url",content:"https://lightningdevkit.org/building-a-node-with-ldk/introduction/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Lightning, LDK, Lightning Dev Kit, Documentation"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Lightning"},{property:"article:tag",content:"LDK"},{property:"article:tag",content:"Lightning Dev Kit"},{property:"article:tag",content:"Documentation"}]},regularPath:"/building-a-node-with-ldk/introduction.html",relativePath:"building-a-node-with-ldk/introduction.md",key:"v-4e009901",path:"/building-a-node-with-ldk/introduction/",headers:[{level:2,title:"Learn how to build a basic LDK node from scratch",slug:"learn-how-to-build-a-basic-ldk-node-from-scratch"},{level:3,title:"Foundational Components",slug:"foundational-components"}],codeSwitcherOptions:{},lastUpdated:"4/30/2024, 6:58:57 PM",lastUpdatedTimestamp:1714503537e3},{title:"Handling Events",frontmatter:{meta:[{property:"og:site_name",content:"Lightning Dev Kit Documentation"},{property:"og:title",content:"Handling Events"},{property:"og:description",content:"LDK requires that you handle many different events throughout your app's life cycle. You can learn more by reading about our event-driven architecture/introduction/architecture.md."},{property:"og:type",content:"article"},{property:"og:url",content:"https://lightningdevkit.org/building-a-node-with-ldk/handling-events/"},{property:"og:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:title",content:"Handling Events"},{name:"twitter:description",content:"LDK requires that you handle many different events throughout your app's life cycle. You can learn more by reading about our event-driven architecture/introduction/architecture.md."},{name:"twitter:url",content:"https://lightningdevkit.org/building-a-node-with-ldk/handling-events/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Lightning, LDK, Lightning Dev Kit, Documentation"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Lightning"},{property:"article:tag",content:"LDK"},{property:"article:tag",content:"Lightning Dev Kit"},{property:"article:tag",content:"Documentation"}]},regularPath:"/building-a-node-with-ldk/handling-events.html",relativePath:"building-a-node-with-ldk/handling-events.md",key:"v-4215c085",path:"/building-a-node-with-ldk/handling-events/",codeSwitcherOptions:{},lastUpdated:"4/30/2024, 6:58:57 PM",lastUpdatedTimestamp:1714503537e3},{title:"Opening a Channel",frontmatter:{meta:[{property:"og:site_name",content:"Lightning Dev Kit Documentation"},{property:"og:title",content:"Opening a Channel"},{property:"og:description",content:"Channels are the basic building blocks of the Lightning Network. With channels, you can transact not only with your immediate peers but with others on the network. Let's explore how to open a channel with LDK."},{property:"og:type",content:"article"},{property:"og:url",content:"https://lightningdevkit.org/building-a-node-with-ldk/opening-a-channel/"},{property:"og:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:title",content:"Opening a Channel"},{name:"twitter:description",content:"Channels are the basic building blocks of the Lightning Network. With channels, you can transact not only with your immediate peers but with others on the network. Let's explore how to open a channel with LDK."},{name:"twitter:url",content:"https://lightningdevkit.org/building-a-node-with-ldk/opening-a-channel/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Lightning, LDK, Lightning Dev Kit, Documentation"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Lightning"},{property:"article:tag",content:"LDK"},{property:"article:tag",content:"Lightning Dev Kit"},{property:"article:tag",content:"Documentation"}]},regularPath:"/building-a-node-with-ldk/opening-a-channel.html",relativePath:"building-a-node-with-ldk/opening-a-channel.md",key:"v-f958b67a",path:"/building-a-node-with-ldk/opening-a-channel/",codeSwitcherOptions:{},lastUpdated:"4/30/2024, 6:58:57 PM",lastUpdatedTimestamp:1714503537e3},{title:"Receiving Payments",frontmatter:{meta:[{property:"og:site_name",content:"Lightning Dev Kit Documentation"},{property:"og:title",content:"Receiving Payments"},{property:"og:description",content:"To receive a payment, you'll need to create an invoice of your own with an\namount and description. `ChannelManager` contains the remaining information\nneeded for the invoice. Use the provided utility to generate an invoice and\nregister a pending payment in `ChannelManager`."},{property:"og:type",content:"article"},{property:"og:url",content:"https://lightningdevkit.org/building-a-node-with-ldk/receiving-payments/"},{property:"og:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:title",content:"Receiving Payments"},{name:"twitter:description",content:"To receive a payment, you'll need to create an invoice of your own with an\namount and description. `ChannelManager` contains the remaining information\nneeded for the invoice. Use the provided utility to generate an invoice and\nregister a pending payment in `ChannelManager`."},{name:"twitter:url",content:"https://lightningdevkit.org/building-a-node-with-ldk/receiving-payments/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Lightning, LDK, Lightning Dev Kit, Documentation"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Lightning"},{property:"article:tag",content:"LDK"},{property:"article:tag",content:"Lightning Dev Kit"},{property:"article:tag",content:"Documentation"}]},regularPath:"/building-a-node-with-ldk/receiving-payments.html",relativePath:"building-a-node-with-ldk/receiving-payments.md",key:"v-44e9497e",path:"/building-a-node-with-ldk/receiving-payments/",codeSwitcherOptions:{},lastUpdated:"4/30/2024, 6:58:57 PM",lastUpdatedTimestamp:1714503537e3},{title:"Sending Payments",frontmatter:{meta:[{property:"og:site_name",content:"Lightning Dev Kit Documentation"},{property:"og:title",content:"Sending Payments"},{property:"og:description",content:"Lightning payments are used to pay invoices, which are typically encoded as a\nstring in accordance with BOLT 11. After parsing the invoice, you'll need to\nfind a route from your node to the recipient and then make the payment using"},{property:"og:type",content:"article"},{property:"og:url",content:"https://lightningdevkit.org/building-a-node-with-ldk/sending-payments/"},{property:"og:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:title",content:"Sending Payments"},{name:"twitter:description",content:"Lightning payments are used to pay invoices, which are typically encoded as a\nstring in accordance with BOLT 11. After parsing the invoice, you'll need to\nfind a route from your node to the recipient and then make the payment using"},{name:"twitter:url",content:"https://lightningdevkit.org/building-a-node-with-ldk/sending-payments/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Lightning, LDK, Lightning Dev Kit, Documentation"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Lightning"},{property:"article:tag",content:"LDK"},{property:"article:tag",content:"Lightning Dev Kit"},{property:"article:tag",content:"Documentation"}]},regularPath:"/building-a-node-with-ldk/sending-payments.html",relativePath:"building-a-node-with-ldk/sending-payments.md",key:"v-1f59967e",path:"/building-a-node-with-ldk/sending-payments/",codeSwitcherOptions:{},lastUpdated:"4/30/2024, 6:58:57 PM",lastUpdatedTimestamp:1714503537e3},{title:"Setting up a PeerManager",frontmatter:{meta:[{property:"og:site_name",content:"Lightning Dev Kit Documentation"},{property:"og:title",content:"Setting up a PeerManager"},{property:"og:description",content:"The `PeerManager` is responsible for managing a set of peer connections and data associated with those peers."},{property:"og:type",content:"article"},{property:"og:url",content:"https://lightningdevkit.org/building-a-node-with-ldk/setting-up-a-peer-manager/"},{property:"og:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:title",content:"Setting up a PeerManager"},{name:"twitter:description",content:"The `PeerManager` is responsible for managing a set of peer connections and data associated with those peers."},{name:"twitter:url",content:"https://lightningdevkit.org/building-a-node-with-ldk/setting-up-a-peer-manager/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Lightning, LDK, Lightning Dev Kit, Documentation"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Lightning"},{property:"article:tag",content:"LDK"},{property:"article:tag",content:"Lightning Dev Kit"},{property:"article:tag",content:"Documentation"}]},regularPath:"/building-a-node-with-ldk/setting-up-a-peer-manager.html",relativePath:"building-a-node-with-ldk/setting-up-a-peer-manager.md",key:"v-f0ae247e",path:"/building-a-node-with-ldk/setting-up-a-peer-manager/",headers:[{level:2,title:"Adding a PeerManager",slug:"adding-a-peermanager"}],codeSwitcherOptions:{},lastUpdated:"4/30/2024, 6:58:57 PM",lastUpdatedTimestamp:1714503537e3},{title:"Setting up a ChannelManager",frontmatter:{meta:[{property:"og:site_name",content:"Lightning Dev Kit Documentation"},{property:"og:title",content:"Setting up a ChannelManager"},{property:"og:description",content:"The `ChannelManager` is responsible for several tasks related to managing channel state. This includes keeping track of many channels, sending messages to appropriate channels, creating channels and more."},{property:"og:type",content:"article"},{property:"og:url",content:"https://lightningdevkit.org/building-a-node-with-ldk/setting-up-a-channel-manager/"},{property:"og:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:title",content:"Setting up a ChannelManager"},{name:"twitter:description",content:"The `ChannelManager` is responsible for several tasks related to managing channel state. This includes keeping track of many channels, sending messages to appropriate channels, creating channels and more."},{name:"twitter:url",content:"https://lightningdevkit.org/building-a-node-with-ldk/setting-up-a-channel-manager/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Lightning, LDK, Lightning Dev Kit, Documentation"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Lightning"},{property:"article:tag",content:"LDK"},{property:"article:tag",content:"Lightning Dev Kit"},{property:"article:tag",content:"Documentation"}]},regularPath:"/building-a-node-with-ldk/setting-up-a-channel-manager.html",relativePath:"building-a-node-with-ldk/setting-up-a-channel-manager.md",key:"v-3cfeb3fe",path:"/building-a-node-with-ldk/setting-up-a-channel-manager/",headers:[{level:2,title:"Adding a ChannelManager",slug:"adding-a-channelmanager"},{level:3,title:"Initialize the FeeEstimator",slug:"initialize-the-feeestimator"},{level:3,title:"Initialize the Router",slug:"initialize-the-router"},{level:3,title:"Initialize the Logger",slug:"initialize-the-logger"},{level:3,title:"Initialize the BroadcasterInterface",slug:"initialize-the-broadcasterinterface"},{level:3,title:"Initialize Persist",slug:"initialize-persist"},{level:3,title:"Start Background Processing",slug:"start-background-processing"},{level:3,title:"Regularly Broadcast Node Announcement",slug:"regularly-broadcast-node-announcement"},{level:3,title:"Optional: Initialize the Transaction Filter",slug:"optional-initialize-the-transaction-filter"},{level:3,title:"Initialize the ChainMonitor",slug:"initialize-the-chainmonitor"},{level:3,title:"Initialize the KeysManager",slug:"initialize-the-keysmanager"},{level:3,title:"Read ChannelMonitor state from disk",slug:"read-channelmonitor-state-from-disk"},{level:3,title:"Initialize the ChannelManager",slug:"initialize-the-channelmanager"},{level:3,title:"Sync ChannelMonitors and ChannelManager to chain tip",slug:"sync-channelmonitors-and-channelmanager-to-chain-tip"},{level:3,title:"Optional: Initialize P2PGossipSync or RapidGossipSync",slug:"optional-initialize-p2pgossipsync-or-rapidgossipsync"},{level:3,title:"Optional: Initialize Probabilistic Scorer",slug:"optional-initialize-probabilistic-scorer"}],codeSwitcherOptions:{},lastUpdated:"4/30/2024, 6:58:57 PM",lastUpdatedTimestamp:1714503537e3},{frontmatter:{cases:!0,sidebar:!1,tagline:"Bitcoin applications building with LDK",description:"A list of bitcoin applications and services building with LDK",actionText:"Add your project",actionLink:"https://github.com/orgs/lightningdevkit/discussions/1554",features:[{title:"Mutiny",details:"A self-custodial lightning wallet that runs in the browser",image:"/img/mutiny-featured.png",imageAlt:"mutiny logo",caseStudyLink:"/blog/mutiny-uses-ldk-the-first-lightning-wallet-for-the-web/"},{title:"Cash App",details:"Send and spend, bank, and buy stocks or bitcoin ",image:"/img/cash-app-logo.png",imageAlt:"cash app logo",caseStudyLink:"/blog/cashapp-enables-lightning-withdrawals-and-deposits-using-ldk/"},{title:"Bitkit",details:"Bitkit hands you the keys to your money, profile, contacts, and web accounts",image:"/img/bitkit.svg",imageAlt:"",caseStudyLink:"/blog/bitkit-uses-ldk-to-build-the-ultimate-alternative-to-custodial-wallets/"}],editLink:!1,lastUpdated:!1,meta:[{property:"og:site_name",content:"Lightning Dev Kit Documentation"},{property:"og:title",content:"Bitcoin applications building with LDK"},{property:"og:description",content:"A list of bitcoin applications and services building with LDK"},{property:"og:type",content:"article"},{property:"og:url",content:"https://lightningdevkit.org/case-studies/"},{property:"og:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:title",content:"Bitcoin applications building with LDK"},{name:"twitter:description",content:"A list of bitcoin applications and services building with LDK"},{name:"twitter:url",content:"https://lightningdevkit.org/case-studies/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Lightning, LDK, Lightning Dev Kit, Documentation"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Lightning"},{property:"article:tag",content:"LDK"},{property:"article:tag",content:"Lightning Dev Kit"},{property:"article:tag",content:"Documentation"}]},regularPath:"/case-studies.html",relativePath:"case-studies.md",key:"v-1df9ba79",path:"/case-studies/",codeSwitcherOptions:{},lastUpdated:"4/30/2024, 6:58:57 PM",lastUpdatedTimestamp:1714503537e3},{title:"Examples",frontmatter:{meta:[{property:"og:site_name",content:"Lightning Dev Kit Documentation"},{property:"og:title",content:"Examples"},{property:"og:description",content:"Click the links below and learn from community-built example projects"},{property:"og:type",content:"article"},{property:"og:url",content:"https://lightningdevkit.org/examples/"},{property:"og:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:title",content:"Examples"},{name:"twitter:description",content:"Click the links below and learn from community-built example projects"},{name:"twitter:url",content:"https://lightningdevkit.org/examples/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Lightning, LDK, Lightning Dev Kit, Documentation"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Lightning"},{property:"article:tag",content:"LDK"},{property:"article:tag",content:"Lightning Dev Kit"},{property:"article:tag",content:"Documentation"}]},regularPath:"/examples.html",relativePath:"examples.md",key:"v-5e36ef8a",path:"/examples/",headers:[{level:3,title:"Rust Sample Node",slug:"rust-sample-node"},{level:3,title:"Kotlin/Android Sample App",slug:"kotlinandroid-sample-app"},{level:3,title:"Swift/iOS Sample App",slug:"swiftios-sample-app"},{level:3,title:"Rust node with sample Lightning Signer integration",slug:"rust-node-with-sample-lightning-signer-integration"},{level:3,title:"Rust node with sample Tor integration",slug:"rust-node-with-sample-tor-integration"},{level:3,title:"LDK Node",slug:"ldk-node"},{level:3,title:"LDK Node Rust Sample",slug:"ldk-node-rust-sample"},{level:3,title:"LDK Node Swift Sample App",slug:"ldk-node-swift-sample-app"},{level:3,title:"LDK Node Swift Sample app using Bitcoin Design Guide",slug:"ldk-node-swift-sample-app-using-bitcoin-design-guide"},{level:3,title:"LDK Node Flutter Sample App",slug:"ldk-node-flutter-sample-app"},{level:3,title:"LDK Node React Native Sample App",slug:"ldk-node-react-native-sample-app"},{level:3,title:"LDK Node Sample Desktop App",slug:"ldk-node-sample-desktop-app"}],codeSwitcherOptions:{},lastUpdated:"4/30/2024, 6:58:57 PM",lastUpdatedTimestamp:1714503537e3},{title:"Home",frontmatter:{home:!0,heroText:"Build Lightning applications your way with LDK",tagline:"A complete Lightning implementation packaged as an SDK",actionText:"Get started",actionLink:"/introduction/",features:[{title:"Flexible and customizable ",details:"Persistence. Networking. Chain sourcing. Routing. Key management. You name it. LDK easily configures to your application’s needs.",image:"customizable"},{title:"High performance",details:"As lightweight and compact as you need it to be, LDK performs on small-footprint devices and scales in the cloud.",image:"focus"},{title:"Any language, any platform",details:"LDK provides a multi-language native API. Run a Lightning node on mobile, web, HSMs, LSPs, or your existing infrastructure.",image:"mobile"}],promo:!0,promoImage:"ldk-node",promoTitle:"LDK Node",promoDescription:"Build a mobile Lightning wallet fast with our ready-to-go solution",promoActionText:"Get Started",promoActionLink:"https://docs.rs/ldk-node/*/ldk_node/",meta:[{property:"og:site_name",content:"Lightning Dev Kit Documentation"},{property:"og:title",content:"A complete Lightning implementation packaged as an SDK"},{property:"og:type",content:"article"},{property:"og:url",content:"https://lightningdevkit.org/"},{property:"og:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:title",content:"A complete Lightning implementation packaged as an SDK"},{name:"twitter:url",content:"https://lightningdevkit.org/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Lightning, LDK, Lightning Dev Kit, Documentation"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Lightning"},{property:"article:tag",content:"LDK"},{property:"article:tag",content:"Lightning Dev Kit"},{property:"article:tag",content:"Documentation"}]},regularPath:"/",relativePath:"index.md",key:"v-197bd04c",path:"/",codeSwitcherOptions:{},lastUpdated:"4/30/2024, 6:58:57 PM",lastUpdatedTimestamp:1714503537e3},{title:"Blockchain Data",frontmatter:{meta:[{property:"og:site_name",content:"Lightning Dev Kit Documentation"},{property:"og:title",content:"Blockchain Data"},{property:"og:description",content:"LDK provides a simple `blockconnected`/`blockdisconnected` API which you pass block headers and transaction information to. LDK also provides an API for getting information about transactions it wishes to be informed of, which is compatible with Electrum server requests/neutrino filtering/etc."},{property:"og:type",content:"article"},{property:"og:url",content:"https://lightningdevkit.org/introduction/blockchain_data/"},{property:"og:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:title",content:"Blockchain Data"},{name:"twitter:description",content:"LDK provides a simple `blockconnected`/`blockdisconnected` API which you pass block headers and transaction information to. LDK also provides an API for getting information about transactions it wishes to be informed of, which is compatible with Electrum server requests/neutrino filtering/etc."},{name:"twitter:url",content:"https://lightningdevkit.org/introduction/blockchain_data/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Lightning, LDK, Lightning Dev Kit, Documentation"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Lightning"},{property:"article:tag",content:"LDK"},{property:"article:tag",content:"Lightning Dev Kit"},{property:"article:tag",content:"Documentation"}]},regularPath:"/introduction/blockchain_data.html",relativePath:"introduction/blockchain_data.md",key:"v-7495ad8d",path:"/introduction/blockchain_data/",codeSwitcherOptions:{},lastUpdated:"4/30/2024, 6:58:57 PM",lastUpdatedTimestamp:1714503537e3},{title:"Architecture",frontmatter:{meta:[{property:"og:site_name",content:"Lightning Dev Kit Documentation"},{property:"og:title",content:"Architecture"},{property:"og:description",content:"Firstly, LDK is not a daemon, but rather its own implementation of the Lightning protocol written as an SDK and designed to be compiled and executed in your application. "},{property:"og:type",content:"article"},{property:"og:url",content:"https://lightningdevkit.org/introduction/architecture/"},{property:"og:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:title",content:"Architecture"},{name:"twitter:description",content:"Firstly, LDK is not a daemon, but rather its own implementation of the Lightning protocol written as an SDK and designed to be compiled and executed in your application. "},{name:"twitter:url",content:"https://lightningdevkit.org/introduction/architecture/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Lightning, LDK, Lightning Dev Kit, Documentation"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Lightning"},{property:"article:tag",content:"LDK"},{property:"article:tag",content:"Lightning Dev Kit"},{property:"article:tag",content:"Documentation"}]},regularPath:"/introduction/architecture.html",relativePath:"introduction/architecture.md",key:"v-d599223e",path:"/introduction/architecture/",codeSwitcherOptions:{},lastUpdated:"4/30/2024, 6:58:57 PM",lastUpdatedTimestamp:1714503537e3},{title:"LDK Code of Conduct",frontmatter:{meta:[{property:"og:site_name",content:"Lightning Dev Kit Documentation"},{property:"og:title",content:"LDK Code of Conduct"},{property:"og:description",content:"The LDK community is open to pretty much anyone. To ensure that project forums such as the Discord server and GitHub repository are open and friendly, we count on maintainers and project representatives to behave in a way that is not disruptive to LDK's culture or to any one participant's well-being."},{property:"og:type",content:"article"},{property:"og:url",content:"https://lightningdevkit.org/code_of_conduct/"},{property:"og:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:title",content:"LDK Code of Conduct"},{name:"twitter:description",content:"The LDK community is open to pretty much anyone. To ensure that project forums such as the Discord server and GitHub repository are open and friendly, we count on maintainers and project representatives to behave in a way that is not disruptive to LDK's culture or to any one participant's well-being."},{name:"twitter:url",content:"https://lightningdevkit.org/code_of_conduct/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Lightning, LDK, Lightning Dev Kit, Documentation"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Lightning"},{property:"article:tag",content:"LDK"},{property:"article:tag",content:"Lightning Dev Kit"},{property:"article:tag",content:"Documentation"}]},regularPath:"/code_of_conduct.html",relativePath:"code_of_conduct.md",key:"v-acaf8bbe",path:"/code_of_conduct/",headers:[{level:2,title:"The Code of Conduct Team",slug:"the-code-of-conduct-team"},{level:2,title:"The Code of Conduct Team’s Responsibilities",slug:"the-code-of-conduct-team-s-responsibilities"},{level:2,title:"Possible responses to an incident include:",slug:"possible-responses-to-an-incident-include"},{level:3,title:"Taking no further action:",slug:"taking-no-further-action"},{level:3,title:"Simple warning:",slug:"simple-warning"},{level:3,title:"Final warning:",slug:"final-warning"},{level:3,title:"2-3 months imposed break:",slug:"2-3-months-imposed-break"},{level:3,title:"Extended or permanent ban:",slug:"extended-or-permanent-ban"}],codeSwitcherOptions:{},lastUpdated:"4/30/2024, 6:58:57 PM",lastUpdatedTimestamp:1714503537e3},{title:"Introduction",frontmatter:{meta:[{property:"og:site_name",content:"Lightning Dev Kit Documentation"},{property:"og:title",content:"Introduction"},{property:"og:description",content:"Lightning Development Kit LDK is a full and completely standalone Lightning implementation with supporting modules enabling greater flexibility."},{property:"og:type",content:"article"},{property:"og:url",content:"https://lightningdevkit.org/introduction/"},{property:"og:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:title",content:"Introduction"},{name:"twitter:description",content:"Lightning Development Kit LDK is a full and completely standalone Lightning implementation with supporting modules enabling greater flexibility."},{name:"twitter:url",content:"https://lightningdevkit.org/introduction/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Lightning, LDK, Lightning Dev Kit, Documentation"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Lightning"},{property:"article:tag",content:"LDK"},{property:"article:tag",content:"Lightning Dev Kit"},{property:"article:tag",content:"Documentation"}]},regularPath:"/introduction/",relativePath:"introduction/index.md",key:"v-2615480c",path:"/introduction/",headers:[{level:2,title:"References",slug:"references"},{level:3,title:"Rust Documentation",slug:"rust-documentation"},{level:3,title:"Swift LDK Documentation",slug:"swift-ldk-documentation"},{level:3,title:"Rust Sample Node",slug:"rust-sample-node"},{level:3,title:"Architecture",slug:"architecture"}],codeSwitcherOptions:{},lastUpdated:"4/30/2024, 6:58:57 PM",lastUpdatedTimestamp:1714503537e3},{title:"Networking",frontmatter:{meta:[{property:"og:site_name",content:"Lightning Dev Kit Documentation"},{property:"og:title",content:"Networking"},{property:"og:description",content:"To enable you to run a full Lightning node on an embedded machine, LDK doesn't specify exactly how to connect to another node at all! The default implementation uses TCP sockets, but, e.g., if you wanted to run your full Lightning node on a hardware wallet, you could, by piping the Lightning network messages over USB/serial and then sending them in a TCP socket from another machine."},{property:"og:type",content:"article"},{property:"og:url",content:"https://lightningdevkit.org/introduction/networking/"},{property:"og:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:title",content:"Networking"},{name:"twitter:description",content:"To enable you to run a full Lightning node on an embedded machine, LDK doesn't specify exactly how to connect to another node at all! The default implementation uses TCP sockets, but, e.g., if you wanted to run your full Lightning node on a hardware wallet, you could, by piping the Lightning network messages over USB/serial and then sending them in a TCP socket from another machine."},{name:"twitter:url",content:"https://lightningdevkit.org/introduction/networking/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Lightning, LDK, Lightning Dev Kit, Documentation"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Lightning"},{property:"article:tag",content:"LDK"},{property:"article:tag",content:"Lightning Dev Kit"},{property:"article:tag",content:"Documentation"}]},regularPath:"/introduction/networking.html",relativePath:"introduction/networking.md",key:"v-2c8ce301",path:"/introduction/networking/",codeSwitcherOptions:{},lastUpdated:"4/30/2024, 6:58:57 PM",lastUpdatedTimestamp:1714503537e3},{title:"Persistent Storage",frontmatter:{meta:[{property:"og:site_name",content:"Lightning Dev Kit Documentation"},{property:"og:title",content:"Persistent Storage"},{property:"og:description",content:"You can store the channel state any way you want - whether Google Drive/iCloud, a local disk, any key-value store/database/a remote server, or any combination of them - LDK provides a clean API, where objects can be serialized into simple binary blobs, and stored in any way you wish."},{property:"og:type",content:"article"},{property:"og:url",content:"https://lightningdevkit.org/introduction/persistent_storage/"},{property:"og:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:title",content:"Persistent Storage"},{name:"twitter:description",content:"You can store the channel state any way you want - whether Google Drive/iCloud, a local disk, any key-value store/database/a remote server, or any combination of them - LDK provides a clean API, where objects can be serialized into simple binary blobs, and stored in any way you wish."},{name:"twitter:url",content:"https://lightningdevkit.org/introduction/persistent_storage/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Lightning, LDK, Lightning Dev Kit, Documentation"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Lightning"},{property:"article:tag",content:"LDK"},{property:"article:tag",content:"Lightning Dev Kit"},{property:"article:tag",content:"Documentation"}]},regularPath:"/introduction/persistent_storage.html",relativePath:"introduction/persistent_storage.md",key:"v-6f688c61",path:"/introduction/persistent_storage/",codeSwitcherOptions:{},lastUpdated:"4/30/2024, 6:58:57 PM",lastUpdatedTimestamp:1714503537e3},{title:"Peer Management",frontmatter:{meta:[{property:"og:site_name",content:"Lightning Dev Kit Documentation"},{property:"og:title",content:"Peer Management"},{property:"og:description",content:"One of the first things you'll need to do when building your own Lightning node is connect to a peer. In LDK this is handled by the `PeerManager`https://docs.rs/lightning//lightning/ln/peerhandler/struct.PeerManager.html."},{property:"og:type",content:"article"},{property:"og:url",content:"https://lightningdevkit.org/introduction/peer-management/"},{property:"og:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:title",content:"Peer Management"},{name:"twitter:description",content:"One of the first things you'll need to do when building your own Lightning node is connect to a peer. In LDK this is handled by the `PeerManager`https://docs.rs/lightning//lightning/ln/peerhandler/struct.PeerManager.html."},{name:"twitter:url",content:"https://lightningdevkit.org/introduction/peer-management/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Lightning, LDK, Lightning Dev Kit, Documentation"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Lightning"},{property:"article:tag",content:"LDK"},{property:"article:tag",content:"Lightning Dev Kit"},{property:"article:tag",content:"Documentation"}]},regularPath:"/introduction/peer-management.html",relativePath:"introduction/peer-management.md",key:"v-9b98f9ca",path:"/introduction/peer-management/",codeSwitcherOptions:{},lastUpdated:"4/30/2024, 6:58:57 PM",lastUpdatedTimestamp:1714503537e3},{title:"Private Key Management",frontmatter:{meta:[{property:"og:site_name",content:"Lightning Dev Kit Documentation"},{property:"og:title",content:"Private Key Management"},{property:"og:description",content:"LDK provides a default implementation for key management, but you can choose to provide private keys to LDK in any way you wish following a simple API. LDK even supports a generic API for signing transactions, allowing you to run LDK without any private keys in memory and/or putting private keys only on hardware wallets."},{property:"og:type",content:"article"},{property:"og:url",content:"https://lightningdevkit.org/introduction/private_key_management/"},{property:"og:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:title",content:"Private Key Management"},{name:"twitter:description",content:"LDK provides a default implementation for key management, but you can choose to provide private keys to LDK in any way you wish following a simple API. LDK even supports a generic API for signing transactions, allowing you to run LDK without any private keys in memory and/or putting private keys only on hardware wallets."},{name:"twitter:url",content:"https://lightningdevkit.org/introduction/private_key_management/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Lightning, LDK, Lightning Dev Kit, Documentation"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Lightning"},{property:"article:tag",content:"LDK"},{property:"article:tag",content:"Lightning Dev Kit"},{property:"article:tag",content:"Documentation"}]},regularPath:"/introduction/private_key_management.html",relativePath:"introduction/private_key_management.md",key:"v-73ba0ae1",path:"/introduction/private_key_management/",codeSwitcherOptions:{},lastUpdated:"4/30/2024, 6:58:57 PM",lastUpdatedTimestamp:1714503537e3},{title:"Random Number Generation",frontmatter:{meta:[{property:"og:site_name",content:"Lightning Dev Kit Documentation"},{property:"og:title",content:"Random Number Generation"},{property:"og:description",content:"LDK aims to make no system calls, it is therefore restricted from generating its own randomness."},{property:"og:type",content:"article"},{property:"og:url",content:"https://lightningdevkit.org/introduction/random_number_generation/"},{property:"og:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:title",content:"Random Number Generation"},{name:"twitter:description",content:"LDK aims to make no system calls, it is therefore restricted from generating its own randomness."},{name:"twitter:url",content:"https://lightningdevkit.org/introduction/random_number_generation/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Lightning, LDK, Lightning Dev Kit, Documentation"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Lightning"},{property:"article:tag",content:"LDK"},{property:"article:tag",content:"Lightning Dev Kit"},{property:"article:tag",content:"Documentation"}]},regularPath:"/introduction/random_number_generation.html",relativePath:"introduction/random_number_generation.md",key:"v-0a5ecb01",path:"/introduction/random_number_generation/",codeSwitcherOptions:{},lastUpdated:"4/30/2024, 6:58:57 PM",lastUpdatedTimestamp:1714503537e3},{title:"Transactions",frontmatter:{meta:[{property:"og:site_name",content:"Lightning Dev Kit Documentation"},{property:"og:title",content:"Transactions"},{property:"og:description",content:"Clients running a light client may wish to filter for transactions on a separate server, in which case LDK will tell them about transactions to filter for. "},{property:"og:type",content:"article"},{property:"og:url",content:"https://lightningdevkit.org/introduction/transactions/"},{property:"og:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:title",content:"Transactions"},{name:"twitter:description",content:"Clients running a light client may wish to filter for transactions on a separate server, in which case LDK will tell them about transactions to filter for. "},{name:"twitter:url",content:"https://lightningdevkit.org/introduction/transactions/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Lightning, LDK, Lightning Dev Kit, Documentation"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Lightning"},{property:"article:tag",content:"LDK"},{property:"article:tag",content:"Lightning Dev Kit"},{property:"article:tag",content:"Documentation"}]},regularPath:"/introduction/transactions.html",relativePath:"introduction/transactions.md",key:"v-8b8ac0be",path:"/introduction/transactions/",headers:[{level:2,title:"Transaction Filtering",slug:"transaction-filtering"},{level:2,title:"Fee Estimation",slug:"fee-estimation"},{level:2,title:"Transaction Broadcasting",slug:"transaction-broadcasting"}],codeSwitcherOptions:{},lastUpdated:"4/30/2024, 6:58:57 PM",lastUpdatedTimestamp:1714503537e3},{title:"Use Cases for LDK",frontmatter:{meta:[{property:"og:site_name",content:"Lightning Dev Kit Documentation"},{property:"og:title",content:"Use Cases for LDK"},{property:"og:description",content:"The standard Lightning use case is running a standalone node on one's laptop.\nHere's some other use cases that LDK supports."},{property:"og:type",content:"article"},{property:"og:url",content:"https://lightningdevkit.org/introduction/use-cases/"},{property:"og:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:title",content:"Use Cases for LDK"},{name:"twitter:description",content:"The standard Lightning use case is running a standalone node on one's laptop.\nHere's some other use cases that LDK supports."},{name:"twitter:url",content:"https://lightningdevkit.org/introduction/use-cases/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Lightning, LDK, Lightning Dev Kit, Documentation"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Lightning"},{property:"article:tag",content:"LDK"},{property:"article:tag",content:"Lightning Dev Kit"},{property:"article:tag",content:"Documentation"}]},regularPath:"/introduction/use-cases.html",relativePath:"introduction/use-cases.md",key:"v-2e6cd4fd",path:"/introduction/use-cases/",headers:[{level:2,title:"Mobile Devices",slug:"mobile-devices"},{level:2,title:"HSMs (Hardware Security Modules)",slug:"hsms-hardware-security-modules"},{level:2,title:"Production Lightning Nodes",slug:"production-lightning-nodes"}],codeSwitcherOptions:{},lastUpdated:"4/30/2024, 6:58:57 PM",lastUpdatedTimestamp:1714503537e3},{title:"Wallet Management",frontmatter:{meta:[{property:"og:site_name",content:"Lightning Dev Kit Documentation"},{property:"og:title",content:"Wallet Management"},{property:"og:description",content:'LDK owns on-chain funds as long as they are claimable as a part of a Lightning output which can be contested - once a channel is closed and all on-chain outputs are spendable only by you, LDK provides you notifications that a UTXO is "yours" again and it is up to you to spend it as you wish. '},{property:"og:type",content:"article"},{property:"og:url",content:"https://lightningdevkit.org/introduction/wallet_management/"},{property:"og:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:title",content:"Wallet Management"},{name:"twitter:description",content:'LDK owns on-chain funds as long as they are claimable as a part of a Lightning output which can be contested - once a channel is closed and all on-chain outputs are spendable only by you, LDK provides you notifications that a UTXO is "yours" again and it is up to you to spend it as you wish. '},{name:"twitter:url",content:"https://lightningdevkit.org/introduction/wallet_management/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Lightning, LDK, Lightning Dev Kit, Documentation"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Lightning"},{property:"article:tag",content:"LDK"},{property:"article:tag",content:"Lightning Dev Kit"},{property:"article:tag",content:"Documentation"}]},regularPath:"/introduction/wallet_management.html",relativePath:"introduction/wallet_management.md",key:"v-c4171d36",path:"/introduction/wallet_management/",codeSwitcherOptions:{},lastUpdated:"4/30/2024, 6:58:57 PM",lastUpdatedTimestamp:1714503537e3},{title:"Language Bindings",frontmatter:{meta:[{property:"og:site_name",content:"Lightning Dev Kit Documentation"},{property:"og:title",content:"Language Bindings"},{property:"og:description",content:"TODO"},{property:"og:type",content:"article"},{property:"og:url",content:"https://lightningdevkit.org/language_bindings/"},{property:"og:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:title",content:"Language Bindings"},{name:"twitter:description",content:"TODO"},{name:"twitter:url",content:"https://lightningdevkit.org/language_bindings/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Lightning, LDK, Lightning Dev Kit, Documentation"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Lightning"},{property:"article:tag",content:"LDK"},{property:"article:tag",content:"Lightning Dev Kit"},{property:"article:tag",content:"Documentation"}]},regularPath:"/language_bindings.html",relativePath:"language_bindings.md",key:"v-21d81ac1",path:"/language_bindings/",codeSwitcherOptions:{},lastUpdated:"4/30/2024, 6:58:57 PM",lastUpdatedTimestamp:1714503537e3},{title:"Key Management",frontmatter:{meta:[{property:"og:site_name",content:"Lightning Dev Kit Documentation"},{property:"og:title",content:"Key Management"},{property:"og:description",content:"LDK provides a simple default `KeysManager` implementation that takes a 32-byte seed for use as a BIP 32 extended key and derives keys from that. Check out the Rust docshttps://docs.rs/lightning//lightning/sign/struct.KeysManager.html."},{property:"og:type",content:"article"},{property:"og:url",content:"https://lightningdevkit.org/key_management/"},{property:"og:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:title",content:"Key Management"},{name:"twitter:description",content:"LDK provides a simple default `KeysManager` implementation that takes a 32-byte seed for use as a BIP 32 extended key and derives keys from that. Check out the Rust docshttps://docs.rs/lightning//lightning/sign/struct.KeysManager.html."},{name:"twitter:url",content:"https://lightningdevkit.org/key_management/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Lightning, LDK, Lightning Dev Kit, Documentation"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Lightning"},{property:"article:tag",content:"LDK"},{property:"article:tag",content:"Lightning Dev Kit"},{property:"article:tag",content:"Documentation"}]},regularPath:"/key_management.html",relativePath:"key_management.md",key:"v-50f91cc7",path:"/key_management/",codeSwitcherOptions:{},lastUpdated:"4/30/2024, 6:58:57 PM",lastUpdatedTimestamp:1714503537e3},{title:"Data Persistence",frontmatter:{meta:[{property:"og:site_name",content:"Lightning Dev Kit Documentation"},{property:"og:title",content:"Data Persistence"},{property:"og:description",content:"TODO"},{property:"og:type",content:"article"},{property:"og:url",content:"https://lightningdevkit.org/persist/"},{property:"og:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:title",content:"Data Persistence"},{name:"twitter:description",content:"TODO"},{name:"twitter:url",content:"https://lightningdevkit.org/persist/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Lightning, LDK, Lightning Dev Kit, Documentation"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Lightning"},{property:"article:tag",content:"LDK"},{property:"article:tag",content:"Lightning Dev Kit"},{property:"article:tag",content:"Documentation"}]},regularPath:"/persist.html",relativePath:"persist.md",key:"v-102e5c3e",path:"/persist/",codeSwitcherOptions:{},lastUpdated:"4/30/2024, 6:58:57 PM",lastUpdatedTimestamp:1714503537e3},{title:"Running a sample LDK node",frontmatter:{meta:[{property:"og:site_name",content:"Lightning Dev Kit Documentation"},{property:"og:title",content:"Running a sample LDK node"},{property:"og:description",content:"Let's run our first LDK node. We'll ensure we have a compatible Rust toolchain installed, setup Polar to create a local Lightning network and then start running the node."},{property:"og:type",content:"article"},{property:"og:url",content:"https://lightningdevkit.org/running-a-sample-ldk-node/"},{property:"og:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:title",content:"Running a sample LDK node"},{name:"twitter:description",content:"Let's run our first LDK node. We'll ensure we have a compatible Rust toolchain installed, setup Polar to create a local Lightning network and then start running the node."},{name:"twitter:url",content:"https://lightningdevkit.org/running-a-sample-ldk-node/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Lightning, LDK, Lightning Dev Kit, Documentation"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Lightning"},{property:"article:tag",content:"LDK"},{property:"article:tag",content:"Lightning Dev Kit"},{property:"article:tag",content:"Documentation"}]},regularPath:"/running-a-sample-ldk-node.html",relativePath:"running-a-sample-ldk-node.md",key:"v-1d645dc1",path:"/running-a-sample-ldk-node/",headers:[{level:2,title:"Installing Rust",slug:"installing-rust"},{level:2,title:"Setup Polar",slug:"setup-polar"},{level:2,title:"Running the LDK Sample Node",slug:"running-the-ldk-sample-node"}],codeSwitcherOptions:{},lastUpdated:"4/30/2024, 6:58:57 PM",lastUpdatedTimestamp:1714503537e3},{frontmatter:{layout:"IndexPost",title:"Blog",meta:[{property:"og:site_name",content:"Lightning Dev Kit Documentation"},{property:"og:type",content:"article"},{property:"og:url",content:"https://lightningdevkit.org/blog/"},{property:"og:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:url",content:"https://lightningdevkit.org/blog/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Lightning, LDK, Lightning Dev Kit, Documentation"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Lightning"},{property:"article:tag",content:"LDK"},{property:"article:tag",content:"Lightning Dev Kit"},{property:"article:tag",content:"Documentation"}]},regularPath:"/blog/",key:"v-424df898",path:"/blog/",codeSwitcherOptions:{}},{frontmatter:{layout:"FrontmatterKey",title:"Tags",meta:[{property:"og:site_name",content:"Lightning Dev Kit Documentation"},{property:"og:type",content:"article"},{property:"og:url",content:"https://lightningdevkit.org/blog/tags/"},{property:"og:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:url",content:"https://lightningdevkit.org/blog/tags/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Lightning, LDK, Lightning Dev Kit, Documentation"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Lightning"},{property:"article:tag",content:"LDK"},{property:"article:tag",content:"Lightning Dev Kit"},{property:"article:tag",content:"Documentation"}]},regularPath:"/blog/tags/",key:"v-619df59e",path:"/blog/tags/",codeSwitcherOptions:{}},{frontmatter:{layout:"FrontmatterKey",title:"Authors",meta:[{property:"og:site_name",content:"Lightning Dev Kit Documentation"},{property:"og:type",content:"article"},{property:"og:url",content:"https://lightningdevkit.org/blog/author/"},{property:"og:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:url",content:"https://lightningdevkit.org/blog/author/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Lightning, LDK, Lightning Dev Kit, Documentation"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Lightning"},{property:"article:tag",content:"LDK"},{property:"article:tag",content:"Lightning Dev Kit"},{property:"article:tag",content:"Documentation"}]},regularPath:"/blog/author/",key:"v-b0968728",path:"/blog/author/",codeSwitcherOptions:{}},{frontmatter:{layout:"FrontmatterPagination",title:"Channels ",meta:[{property:"og:site_name",content:"Lightning Dev Kit Documentation"},{property:"og:type",content:"article"},{property:"og:url",content:"https://lightningdevkit.org/blog/tags/Channels/"},{property:"og:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:url",content:"https://lightningdevkit.org/blog/tags/Channels/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Lightning, LDK, Lightning Dev Kit, Documentation"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Lightning"},{property:"article:tag",content:"LDK"},{property:"article:tag",content:"Lightning Dev Kit"},{property:"article:tag",content:"Documentation"}]},regularPath:"/blog/tags/Channels/",key:"v-07a81b3e",path:"/blog/tags/Channels/",codeSwitcherOptions:{}},{frontmatter:{layout:"FrontmatterPagination",title:"Anchor Outputs ",meta:[{property:"og:site_name",content:"Lightning Dev Kit Documentation"},{property:"og:type",content:"article"},{property:"og:url",content:"https://lightningdevkit.org/blog/tags/Anchor Outputs/"},{property:"og:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:url",content:"https://lightningdevkit.org/blog/tags/Anchor Outputs/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Lightning, LDK, Lightning Dev Kit, Documentation"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Lightning"},{property:"article:tag",content:"LDK"},{property:"article:tag",content:"Lightning Dev Kit"},{property:"article:tag",content:"Documentation"}]},regularPath:"/blog/tags/Anchor%20Outputs/",key:"v-2d66714d",path:"/blog/tags/Anchor Outputs/",codeSwitcherOptions:{}},{frontmatter:{layout:"FrontmatterPagination",title:"Fees ",meta:[{property:"og:site_name",content:"Lightning Dev Kit Documentation"},{property:"og:type",content:"article"},{property:"og:url",content:"https://lightningdevkit.org/blog/tags/Fees/"},{property:"og:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:url",content:"https://lightningdevkit.org/blog/tags/Fees/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Lightning, LDK, Lightning Dev Kit, Documentation"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Lightning"},{property:"article:tag",content:"LDK"},{property:"article:tag",content:"Lightning Dev Kit"},{property:"article:tag",content:"Documentation"}]},regularPath:"/blog/tags/Fees/",key:"v-3d7abd24",path:"/blog/tags/Fees/",codeSwitcherOptions:{}},{frontmatter:{layout:"FrontmatterPagination",title:"Self-custody ",meta:[{property:"og:site_name",content:"Lightning Dev Kit Documentation"},{property:"og:type",content:"article"},{property:"og:url",content:"https://lightningdevkit.org/blog/tags/Self-custody/"},{property:"og:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:url",content:"https://lightningdevkit.org/blog/tags/Self-custody/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Lightning, LDK, Lightning Dev Kit, Documentation"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Lightning"},{property:"article:tag",content:"LDK"},{property:"article:tag",content:"Lightning Dev Kit"},{property:"article:tag",content:"Documentation"}]},regularPath:"/blog/tags/Self-custody/",key:"v-45d354a1",path:"/blog/tags/Self-custody/",codeSwitcherOptions:{}},{frontmatter:{layout:"FrontmatterPagination",title:"Mobile ",meta:[{property:"og:site_name",content:"Lightning Dev Kit Documentation"},{property:"og:type",content:"article"},{property:"og:url",content:"https://lightningdevkit.org/blog/tags/Mobile/"},{property:"og:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:url",content:"https://lightningdevkit.org/blog/tags/Mobile/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Lightning, LDK, Lightning Dev Kit, Documentation"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Lightning"},{property:"article:tag",content:"LDK"},{property:"article:tag",content:"Lightning Dev Kit"},{property:"article:tag",content:"Documentation"}]},regularPath:"/blog/tags/Mobile/",key:"v-4cee384f",path:"/blog/tags/Mobile/",codeSwitcherOptions:{}},{frontmatter:{layout:"FrontmatterPagination",title:"Case Studies ",meta:[{property:"og:site_name",content:"Lightning Dev Kit Documentation"},{property:"og:type",content:"article"},{property:"og:url",content:"https://lightningdevkit.org/blog/tags/Case Studies/"},{property:"og:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:url",content:"https://lightningdevkit.org/blog/tags/Case Studies/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Lightning, LDK, Lightning Dev Kit, Documentation"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Lightning"},{property:"article:tag",content:"LDK"},{property:"article:tag",content:"Lightning Dev Kit"},{property:"article:tag",content:"Documentation"}]},regularPath:"/blog/tags/Case%20Studies/",key:"v-2571507d",path:"/blog/tags/Case Studies/",codeSwitcherOptions:{}},{frontmatter:{layout:"FrontmatterPagination",title:"Offers ",meta:[{property:"og:site_name",content:"Lightning Dev Kit Documentation"},{property:"og:type",content:"article"},{property:"og:url",content:"https://lightningdevkit.org/blog/tags/Offers/"},{property:"og:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:url",content:"https://lightningdevkit.org/blog/tags/Offers/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Lightning, LDK, Lightning Dev Kit, Documentation"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Lightning"},{property:"article:tag",content:"LDK"},{property:"article:tag",content:"Lightning Dev Kit"},{property:"article:tag",content:"Documentation"}]},regularPath:"/blog/tags/Offers/",key:"v-b0d4940c",path:"/blog/tags/Offers/",codeSwitcherOptions:{}},{frontmatter:{layout:"FrontmatterPagination",title:"Onion Messages ",meta:[{property:"og:site_name",content:"Lightning Dev Kit Documentation"},{property:"og:type",content:"article"},{property:"og:url",content:"https://lightningdevkit.org/blog/tags/Onion Messages/"},{property:"og:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:url",content:"https://lightningdevkit.org/blog/tags/Onion Messages/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Lightning, LDK, Lightning Dev Kit, Documentation"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Lightning"},{property:"article:tag",content:"LDK"},{property:"article:tag",content:"Lightning Dev Kit"},{property:"article:tag",content:"Documentation"}]},regularPath:"/blog/tags/Onion%20Messages/",key:"v-d885a66a",path:"/blog/tags/Onion Messages/",codeSwitcherOptions:{}},{frontmatter:{layout:"FrontmatterPagination",title:"Privacy ",meta:[{property:"og:site_name",content:"Lightning Dev Kit Documentation"},{property:"og:type",content:"article"},{property:"og:url",content:"https://lightningdevkit.org/blog/tags/Privacy/"},{property:"og:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:url",content:"https://lightningdevkit.org/blog/tags/Privacy/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Lightning, LDK, Lightning Dev Kit, Documentation"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Lightning"},{property:"article:tag",content:"LDK"},{property:"article:tag",content:"Lightning Dev Kit"},{property:"article:tag",content:"Documentation"}]},regularPath:"/blog/tags/Privacy/",key:"v-33d32965",path:"/blog/tags/Privacy/",codeSwitcherOptions:{}},{frontmatter:{layout:"FrontmatterPagination",title:"Gossip ",meta:[{property:"og:site_name",content:"Lightning Dev Kit Documentation"},{property:"og:type",content:"article"},{property:"og:url",content:"https://lightningdevkit.org/blog/tags/Gossip/"},{property:"og:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:url",content:"https://lightningdevkit.org/blog/tags/Gossip/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Lightning, LDK, Lightning Dev Kit, Documentation"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Lightning"},{property:"article:tag",content:"LDK"},{property:"article:tag",content:"Lightning Dev Kit"},{property:"article:tag",content:"Documentation"}]},regularPath:"/blog/tags/Gossip/",key:"v-107ce622",path:"/blog/tags/Gossip/",codeSwitcherOptions:{}},{frontmatter:{layout:"FrontmatterPagination",title:"Network Graph ",meta:[{property:"og:site_name",content:"Lightning Dev Kit Documentation"},{property:"og:type",content:"article"},{property:"og:url",content:"https://lightningdevkit.org/blog/tags/Network Graph/"},{property:"og:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:url",content:"https://lightningdevkit.org/blog/tags/Network Graph/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Lightning, LDK, Lightning Dev Kit, Documentation"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Lightning"},{property:"article:tag",content:"LDK"},{property:"article:tag",content:"Lightning Dev Kit"},{property:"article:tag",content:"Documentation"}]},regularPath:"/blog/tags/Network%20Graph/",key:"v-288bb6f4",path:"/blog/tags/Network Graph/",codeSwitcherOptions:{}},{frontmatter:{layout:"FrontmatterPagination",title:"Enterprise ",meta:[{property:"og:site_name",content:"Lightning Dev Kit Documentation"},{property:"og:type",content:"article"},{property:"og:url",content:"https://lightningdevkit.org/blog/tags/Enterprise/"},{property:"og:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:url",content:"https://lightningdevkit.org/blog/tags/Enterprise/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Lightning, LDK, Lightning Dev Kit, Documentation"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Lightning"},{property:"article:tag",content:"LDK"},{property:"article:tag",content:"Lightning Dev Kit"},{property:"article:tag",content:"Documentation"}]},regularPath:"/blog/tags/Enterprise/",key:"v-75584720",path:"/blog/tags/Enterprise/",codeSwitcherOptions:{}},{frontmatter:{layout:"FrontmatterPagination",title:"Phantom ",meta:[{property:"og:site_name",content:"Lightning Dev Kit Documentation"},{property:"og:type",content:"article"},{property:"og:url",content:"https://lightningdevkit.org/blog/tags/Phantom/"},{property:"og:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:url",content:"https://lightningdevkit.org/blog/tags/Phantom/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Lightning, LDK, Lightning Dev Kit, Documentation"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Lightning"},{property:"article:tag",content:"LDK"},{property:"article:tag",content:"Lightning Dev Kit"},{property:"article:tag",content:"Documentation"}]},regularPath:"/blog/tags/Phantom/",key:"v-14c62680",path:"/blog/tags/Phantom/",codeSwitcherOptions:{}},{frontmatter:{layout:"FrontmatterPagination",title:"Bitcoin ",meta:[{property:"og:site_name",content:"Lightning Dev Kit Documentation"},{property:"og:type",content:"article"},{property:"og:url",content:"https://lightningdevkit.org/blog/tags/Bitcoin/"},{property:"og:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:url",content:"https://lightningdevkit.org/blog/tags/Bitcoin/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Lightning, LDK, Lightning Dev Kit, Documentation"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Lightning"},{property:"article:tag",content:"LDK"},{property:"article:tag",content:"Lightning Dev Kit"},{property:"article:tag",content:"Documentation"}]},regularPath:"/blog/tags/Bitcoin/",key:"v-89aabae2",path:"/blog/tags/Bitcoin/",codeSwitcherOptions:{}},{frontmatter:{layout:"FrontmatterPagination",title:"LDK ",meta:[{property:"og:site_name",content:"Lightning Dev Kit Documentation"},{property:"og:type",content:"article"},{property:"og:url",content:"https://lightningdevkit.org/blog/tags/LDK/"},{property:"og:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:url",content:"https://lightningdevkit.org/blog/tags/LDK/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Lightning, LDK, Lightning Dev Kit, Documentation"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Lightning"},{property:"article:tag",content:"LDK"},{property:"article:tag",content:"Lightning Dev Kit"},{property:"article:tag",content:"Documentation"}]},regularPath:"/blog/tags/LDK/",key:"v-5f1ce94c",path:"/blog/tags/LDK/",codeSwitcherOptions:{}},{frontmatter:{layout:"FrontmatterPagination",title:"Roadmap ",meta:[{property:"og:site_name",content:"Lightning Dev Kit Documentation"},{property:"og:type",content:"article"},{property:"og:url",content:"https://lightningdevkit.org/blog/tags/Roadmap/"},{property:"og:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:url",content:"https://lightningdevkit.org/blog/tags/Roadmap/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Lightning, LDK, Lightning Dev Kit, Documentation"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Lightning"},{property:"article:tag",content:"LDK"},{property:"article:tag",content:"Lightning Dev Kit"},{property:"article:tag",content:"Documentation"}]},regularPath:"/blog/tags/Roadmap/",key:"v-5643d131",path:"/blog/tags/Roadmap/",codeSwitcherOptions:{}},{frontmatter:{layout:"FrontmatterPagination",title:"Non-Custodial ",meta:[{property:"og:site_name",content:"Lightning Dev Kit Documentation"},{property:"og:type",content:"article"},{property:"og:url",content:"https://lightningdevkit.org/blog/tags/Non-Custodial/"},{property:"og:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:url",content:"https://lightningdevkit.org/blog/tags/Non-Custodial/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Lightning, LDK, Lightning Dev Kit, Documentation"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Lightning"},{property:"article:tag",content:"LDK"},{property:"article:tag",content:"Lightning Dev Kit"},{property:"article:tag",content:"Documentation"}]},regularPath:"/blog/tags/Non-Custodial/",key:"v-0bfa2c21",path:"/blog/tags/Non-Custodial/",codeSwitcherOptions:{}},{frontmatter:{layout:"FrontmatterPagination",title:"liquidity ",meta:[{property:"og:site_name",content:"Lightning Dev Kit Documentation"},{property:"og:type",content:"article"},{property:"og:url",content:"https://lightningdevkit.org/blog/tags/liquidity/"},{property:"og:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:url",content:"https://lightningdevkit.org/blog/tags/liquidity/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Lightning, LDK, Lightning Dev Kit, Documentation"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Lightning"},{property:"article:tag",content:"LDK"},{property:"article:tag",content:"Lightning Dev Kit"},{property:"article:tag",content:"Documentation"}]},regularPath:"/blog/tags/liquidity/",key:"v-2520b09b",path:"/blog/tags/liquidity/",codeSwitcherOptions:{}},{frontmatter:{layout:"FrontmatterPagination",title:"0-Conf Channels ",meta:[{property:"og:site_name",content:"Lightning Dev Kit Documentation"},{property:"og:type",content:"article"},{property:"og:url",content:"https://lightningdevkit.org/blog/tags/0-Conf Channels/"},{property:"og:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:url",content:"https://lightningdevkit.org/blog/tags/0-Conf Channels/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Lightning, LDK, Lightning Dev Kit, Documentation"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Lightning"},{property:"article:tag",content:"LDK"},{property:"article:tag",content:"Lightning Dev Kit"},{property:"article:tag",content:"Documentation"}]},regularPath:"/blog/tags/0-Conf%20Channels/",key:"v-026b604a",path:"/blog/tags/0-Conf Channels/",codeSwitcherOptions:{}},{frontmatter:{layout:"FrontmatterPagination",title:"Wilmer Paulino ",meta:[{property:"og:site_name",content:"Lightning Dev Kit Documentation"},{property:"og:type",content:"article"},{property:"og:url",content:"https://lightningdevkit.org/blog/author/Wilmer Paulino/"},{property:"og:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:url",content:"https://lightningdevkit.org/blog/author/Wilmer Paulino/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Lightning, LDK, Lightning Dev Kit, Documentation"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Lightning"},{property:"article:tag",content:"LDK"},{property:"article:tag",content:"Lightning Dev Kit"},{property:"article:tag",content:"Documentation"}]},regularPath:"/blog/author/Wilmer%20Paulino/",key:"v-27610544",path:"/blog/author/Wilmer Paulino/",codeSwitcherOptions:{}},{frontmatter:{layout:"FrontmatterPagination",title:"Elias Rohrer ",meta:[{property:"og:site_name",content:"Lightning Dev Kit Documentation"},{property:"og:type",content:"article"},{property:"og:url",content:"https://lightningdevkit.org/blog/author/Elias Rohrer/"},{property:"og:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:url",content:"https://lightningdevkit.org/blog/author/Elias Rohrer/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Lightning, LDK, Lightning Dev Kit, Documentation"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Lightning"},{property:"article:tag",content:"LDK"},{property:"article:tag",content:"Lightning Dev Kit"},{property:"article:tag",content:"Documentation"}]},regularPath:"/blog/author/Elias%20Rohrer/",key:"v-580ef260",path:"/blog/author/Elias Rohrer/",codeSwitcherOptions:{}},{frontmatter:{layout:"FrontmatterPagination",title:"Matt Carvalho ",meta:[{property:"og:site_name",content:"Lightning Dev Kit Documentation"},{property:"og:type",content:"article"},{property:"og:url",content:"https://lightningdevkit.org/blog/author/Matt Carvalho/"},{property:"og:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:url",content:"https://lightningdevkit.org/blog/author/Matt Carvalho/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Lightning, LDK, Lightning Dev Kit, Documentation"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Lightning"},{property:"article:tag",content:"LDK"},{property:"article:tag",content:"Lightning Dev Kit"},{property:"article:tag",content:"Documentation"}]},regularPath:"/blog/author/Matt%20Carvalho/",key:"v-5e0b95d8",path:"/blog/author/Matt Carvalho/",codeSwitcherOptions:{}},{frontmatter:{layout:"FrontmatterPagination",title:"Jeff Czyz ",meta:[{property:"og:site_name",content:"Lightning Dev Kit Documentation"},{property:"og:type",content:"article"},{property:"og:url",content:"https://lightningdevkit.org/blog/author/Jeff Czyz/"},{property:"og:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:url",content:"https://lightningdevkit.org/blog/author/Jeff Czyz/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Lightning, LDK, Lightning Dev Kit, Documentation"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Lightning"},{property:"article:tag",content:"LDK"},{property:"article:tag",content:"Lightning Dev Kit"},{property:"article:tag",content:"Documentation"}]},regularPath:"/blog/author/Jeff%20Czyz/",key:"v-bf9b8e8a",path:"/blog/author/Jeff Czyz/",codeSwitcherOptions:{}},{frontmatter:{layout:"FrontmatterPagination",title:"Ryan Loomba ",meta:[{property:"og:site_name",content:"Lightning Dev Kit Documentation"},{property:"og:type",content:"article"},{property:"og:url",content:"https://lightningdevkit.org/blog/author/Ryan Loomba/"},{property:"og:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:url",content:"https://lightningdevkit.org/blog/author/Ryan Loomba/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Lightning, LDK, Lightning Dev Kit, Documentation"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Lightning"},{property:"article:tag",content:"LDK"},{property:"article:tag",content:"Lightning Dev Kit"},{property:"article:tag",content:"Documentation"}]},regularPath:"/blog/author/Ryan%20Loomba/",key:"v-571fde2c",path:"/blog/author/Ryan Loomba/",codeSwitcherOptions:{}},{frontmatter:{layout:"FrontmatterPagination",title:"Arik Sosman ",meta:[{property:"og:site_name",content:"Lightning Dev Kit Documentation"},{property:"og:type",content:"article"},{property:"og:url",content:"https://lightningdevkit.org/blog/author/Arik Sosman/"},{property:"og:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:url",content:"https://lightningdevkit.org/blog/author/Arik Sosman/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Lightning, LDK, Lightning Dev Kit, Documentation"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Lightning"},{property:"article:tag",content:"LDK"},{property:"article:tag",content:"Lightning Dev Kit"},{property:"article:tag",content:"Documentation"}]},regularPath:"/blog/author/Arik%20Sosman/",key:"v-79994b30",path:"/blog/author/Arik Sosman/",codeSwitcherOptions:{}},{frontmatter:{layout:"FrontmatterPagination",title:"Valentine Wallace ",meta:[{property:"og:site_name",content:"Lightning Dev Kit Documentation"},{property:"og:type",content:"article"},{property:"og:url",content:"https://lightningdevkit.org/blog/author/Valentine Wallace/"},{property:"og:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:url",content:"https://lightningdevkit.org/blog/author/Valentine Wallace/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Lightning, LDK, Lightning Dev Kit, Documentation"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Lightning"},{property:"article:tag",content:"LDK"},{property:"article:tag",content:"Lightning Dev Kit"},{property:"article:tag",content:"Documentation"}]},regularPath:"/blog/author/Valentine%20Wallace/",key:"v-54403322",path:"/blog/author/Valentine Wallace/",codeSwitcherOptions:{}},{frontmatter:{layout:"FrontmatterPagination",title:"Conor Okus ",meta:[{property:"og:site_name",content:"Lightning Dev Kit Documentation"},{property:"og:type",content:"article"},{property:"og:url",content:"https://lightningdevkit.org/blog/author/Conor Okus/"},{property:"og:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:url",content:"https://lightningdevkit.org/blog/author/Conor Okus/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Lightning, LDK, Lightning Dev Kit, Documentation"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Lightning"},{property:"article:tag",content:"LDK"},{property:"article:tag",content:"Lightning Dev Kit"},{property:"article:tag",content:"Documentation"}]},regularPath:"/blog/author/Conor%20Okus/",key:"v-044cdb6b",path:"/blog/author/Conor Okus/",codeSwitcherOptions:{}},{frontmatter:{layout:"FrontmatterPagination",title:"Steve Lee ",meta:[{property:"og:site_name",content:"Lightning Dev Kit Documentation"},{property:"og:type",content:"article"},{property:"og:url",content:"https://lightningdevkit.org/blog/author/Steve Lee/"},{property:"og:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:url",content:"https://lightningdevkit.org/blog/author/Steve Lee/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Lightning, LDK, Lightning Dev Kit, Documentation"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Lightning"},{property:"article:tag",content:"LDK"},{property:"article:tag",content:"Lightning Dev Kit"},{property:"article:tag",content:"Documentation"}]},regularPath:"/blog/author/Steve%20Lee/",key:"v-39b7f2bf",path:"/blog/author/Steve Lee/",codeSwitcherOptions:{}},{frontmatter:{layout:"FrontmatterPagination",title:"Ben Carman ",meta:[{property:"og:site_name",content:"Lightning Dev Kit Documentation"},{property:"og:type",content:"article"},{property:"og:url",content:"https://lightningdevkit.org/blog/author/Ben Carman/"},{property:"og:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:url",content:"https://lightningdevkit.org/blog/author/Ben Carman/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Lightning, LDK, Lightning Dev Kit, Documentation"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Lightning"},{property:"article:tag",content:"LDK"},{property:"article:tag",content:"Lightning Dev Kit"},{property:"article:tag",content:"Documentation"}]},regularPath:"/blog/author/Ben%20Carman/",key:"v-6a051305",path:"/blog/author/Ben Carman/",codeSwitcherOptions:{}},{frontmatter:{layout:"FrontmatterPagination",title:"John Cantrell ",meta:[{property:"og:site_name",content:"Lightning Dev Kit Documentation"},{property:"og:type",content:"article"},{property:"og:url",content:"https://lightningdevkit.org/blog/author/John Cantrell/"},{property:"og:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:url",content:"https://lightningdevkit.org/blog/author/John Cantrell/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Lightning, LDK, Lightning Dev Kit, Documentation"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Lightning"},{property:"article:tag",content:"LDK"},{property:"article:tag",content:"Lightning Dev Kit"},{property:"article:tag",content:"Documentation"}]},regularPath:"/blog/author/John%20Cantrell/",key:"v-c06ffaa8",path:"/blog/author/John Cantrell/",codeSwitcherOptions:{}},{frontmatter:{layout:"FrontmatterPagination",title:"Sergi Delgado ",meta:[{property:"og:site_name",content:"Lightning Dev Kit Documentation"},{property:"og:type",content:"article"},{property:"og:url",content:"https://lightningdevkit.org/blog/author/Sergi Delgado/"},{property:"og:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:url",content:"https://lightningdevkit.org/blog/author/Sergi Delgado/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Lightning, LDK, Lightning Dev Kit, Documentation"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Lightning"},{property:"article:tag",content:"LDK"},{property:"article:tag",content:"Lightning Dev Kit"},{property:"article:tag",content:"Documentation"}]},regularPath:"/blog/author/Sergi%20Delgado/",key:"v-0c9ef90c",path:"/blog/author/Sergi Delgado/",codeSwitcherOptions:{}},{frontmatter:{layout:"FrontmatterPagination",title:"Matt Corallo ",meta:[{property:"og:site_name",content:"Lightning Dev Kit Documentation"},{property:"og:type",content:"article"},{property:"og:url",content:"https://lightningdevkit.org/blog/author/Matt Corallo/"},{property:"og:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:url",content:"https://lightningdevkit.org/blog/author/Matt Corallo/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Lightning, LDK, Lightning Dev Kit, Documentation"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Lightning"},{property:"article:tag",content:"LDK"},{property:"article:tag",content:"Lightning Dev Kit"},{property:"article:tag",content:"Documentation"}]},regularPath:"/blog/author/Matt%20Corallo/",key:"v-438a3c44",path:"/blog/author/Matt Corallo/",codeSwitcherOptions:{}},{frontmatter:{layout:"DirectoryPagination",title:"Page 2",meta:[{property:"og:site_name",content:"Lightning Dev Kit Documentation"},{property:"og:type",content:"article"},{property:"og:url",content:"https://lightningdevkit.org/blog/page/2/"},{property:"og:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:url",content:"https://lightningdevkit.org/blog/page/2/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Lightning, LDK, Lightning Dev Kit, Documentation"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Lightning"},{property:"article:tag",content:"LDK"},{property:"article:tag",content:"Lightning Dev Kit"},{property:"article:tag",content:"Documentation"}]},regularPath:"/blog/page/2/",key:"v-c3507bb6",path:"/blog/page/2/",codeSwitcherOptions:{}}],themeConfig:{domain:"https://lightningdevkit.org",logo:"/img/logo.svg",displayAllHeaders:!1,repo:"lightningdevkit/lightningdevkit.org",docsDir:"docs",docsBranch:"main",editLinks:!0,sidebarDepth:0,algolia:{indexName:"lightningdevkit",appId:"BH4D9OD16A",apiKey:"17ed8a4e16a1cb7d94da4e96f2ff817f",algoliaOptions:{typoTolerance:"min"},autocompleteOptions:{openOnFocus:!0}},nav:[{text:"Docs",link:"/introduction/"},{text:"Case Studies",link:"/case-studies/"},{text:"Blog",link:"/blog/"},{text:"Discord",link:"https://discord.gg/5AcknnMfBw",rel:"noopener noreferrer"},{text:"GitHub",link:"https://github.com/lightningdevkit",rel:"noopener noreferrer"}],sidebar:{"/_blog/":[{title:"Blog",collapsable:!1,children:[["/blog/","Articles"],["/blog/tags/","Tags"],["/blog/author/","Authors"]]}],"/blog/":[{title:"Blog",collapsable:!1,children:[["/blog/","Articles"],["/blog/tags/","Tags"],["/blog/author/","Authors"]]}],"/":[{title:"Documentation",collapsable:!1,children:[{title:"Introduction",path:"/introduction/",collapsable:!0,children:[["/introduction/use-cases","Use Cases"],["/introduction/architecture","Architecture"],["/introduction/peer-management","Peer Management"],["/introduction/persistent_storage","Persistent Storage"],["/introduction/blockchain_data","Blockchain Data"],["/introduction/wallet_management","Wallet Management"],["/introduction/networking","Networking"],["/introduction/private_key_management","Private Key Management"],["/introduction/transactions","Transactions"],["/introduction/random_number_generation","Random Number Generation"]]},{title:"Building a node with LDK",collapsable:!0,children:[["/building-a-node-with-ldk/introduction","Introduction"],["/building-a-node-with-ldk/installation","Installation"],["/building-a-node-with-ldk/setting-up-a-channel-manager","Setting up a Channel Manager"],["/building-a-node-with-ldk/handling-events","Handling Events"],["/building-a-node-with-ldk/setting-up-a-peer-manager","Setting up a Peer Manager"],["/building-a-node-with-ldk/connect-to-peers","Connect to Peers"],["/building-a-node-with-ldk/opening-a-channel","Opening a Channel"],["/building-a-node-with-ldk/sending-payments","Sending Payments"],["/building-a-node-with-ldk/receiving-payments","Receiving Payments"],["/building-a-node-with-ldk/closing-a-channel","Closing a Channel"]]},"/running-a-sample-ldk-node",{title:"Blockchain Data",collapsable:!0,children:[["/blockchain_data/introduction","Introduction"],["/blockchain_data/chain_activity","Chain Activity"],["/blockchain_data/block_source","Block Source"],["/blockchain_data/full_blocks","Full Blocks"],["/blockchain_data/pre_filtered_blocks","Pre-filtered Blocks"],["/blockchain_data/confirmed_transactions","Confirmed Transactions"],["/blockchain_data/transaction_broadcasting","Transaction Broadcasting"]]},"/key_management","/examples"]},{title:"API Reference",collapsable:!1,children:[{title:"Rust",collapsable:!0,children:[["https://docs.rs/lightning/*/lightning/","lightning"],["https://docs.rs/lightning-background-processor/*/lightning_background_processor/","lightning-background-processor"],["https://docs.rs/lightning-block-sync/*/lightning_block_sync/","lightning-block-sync"],["https://docs.rs/lightning-invoice/*/lightning_invoice/","lightning-invoice"],["https://docs.rs/lightning-net-tokio/*/lightning_net_tokio/","lightning-net-tokio"],["https://docs.rs/lightning-persister/*/lightning_persister/","lightning-persister"],["https://docs.rs/lightning-rapid-gossip-sync/*/lightning_rapid_gossip_sync/","lightning-rapid-gossip-sync"],["https://docs.rs/lightning-transaction-sync/*/lightning_transaction_sync/","lightning-transaction-sync"],["https://docs.rs/lightning-custom-message/*/lightning_custom_message/","lightning-custom-message"]]},["https://github.com/arik-so/SwiftLightning/tree/master/Documentation","Swift"]]}]},footer:{links:[{title:"Docs",children:[{text:"Introduction",link:"/introduction/"},{text:"Building a node with LDK",link:"/building-a-node-with-ldk/introduction"},{text:"Running a sample LDK node",link:"/running-a-sample-ldk-node/"},{text:"Architecture",link:"/introduction/architecture/"},{text:"Blockchain Data",link:"/blockchain_data/introduction/"},{text:"Key Management",link:"/key_management/"},{text:"Examples",link:"/examples/"}]},{title:"Community",children:[{text:"GitHub",link:"https://github.com/lightningdevkit",rel:"noopener noreferrer"},{text:"Twitter",link:"https://twitter.com/lightningdevkit",rel:"noopener noreferrer"},{text:"Chat on Discord",link:"https://discord.gg/5AcknnMfBw",rel:"noopener noreferrer"},{text:"LDK Calendar",link:"https://calendar.google.com/calendar/embed?src=c_e6fv6vlshbpoob2mmbvblkkoj4%40group.calendar.google.com",rel:"noopener noreferrer"},{text:"LDK Review Club",link:"http://ldk.reviews/",rel:"noopener noreferrer"},{text:"Code of Conduct",link:"/code_of_conduct",rel:"noopener noreferrer"}]},{title:"Resources",children:[{text:"Case Studies",link:"/case-studies/"},{text:"Blog",link:"/blog/"}]},{title:"Other",children:[{text:"Bitcoin Dev Kit",link:"https://bitcoindevkit.org/",rel:"noopener noreferrer"},{text:"Reporting a Vulnerability",link:"https://github.com/lightningdevkit/rust-lightning/blob/main/SECURITY.md",rel:"noopener noreferrer"}]}],copyright:"Copyright © 2024 LDK Developers"}}},{COLOR_MODES:Mc,STORE_ATTR:Ac,setColorMode:jc}=n(112),Bc=t=>"Enter"===t.code||13===(t.keyCode||t.which),Fc=t=>{const e=t.target.matches("#algolia-search-input")&&Bc(t);(t.target.matches(".ds-dropdown-menu *")||e)&&document.getElementById("algolia-search-input").blur(),t.target.matches(".ytEmbed")&&(t.preventDefault(),(t=>{const e=t.querySelector("iframe[data-src]");if(e){const t=e.getAttribute("data-src");e.setAttribute("src",t)}})(t.target))};if("undefined"==typeof process||"server"!==process.env.VUE_ENV){const t=window.matchMedia("(prefers-color-scheme: dark)").matches?Mc[1]:Mc[0],e=window.localStorage.getItem(Ac);jc(Mc.includes(e)?e:t)}n(242);Hn.component("Badge",()=>Promise.all([n.e(0),n.e(14)]).then(n.bind(null,437))),Hn.component("CodeBlock",()=>Promise.all([n.e(0),n.e(15)]).then(n.bind(null,382))),Hn.component("CodeGroup",()=>Promise.all([n.e(0),n.e(16)]).then(n.bind(null,383)));n(243);var Rc={props:{color:{required:!1,default:"rgb(66, 185, 131)"}}},Nc=(n(244),Object(Cc.a)(Rc,(function(){return(0,this._self._c)("div",{staticClass:"spinner",style:{background:this.color}})}),[],!1,null,"1bbcb91a",null).exports);const Ic={name:"Mermaid",props:{id:{type:String,required:!0},graph:{type:String,required:!0}},data:()=>({svg:void 0}),render(t){return void 0===this.svg?t("Loading"):t("div",{domProps:{innerHTML:this.svg,style:"width: 100%"}})},mounted(){n.e(68).then(n.t.bind(null,372,7)).then(t=>{t.initialize({startOnLoad:!0});let e=document.createElement("div");document.body.appendChild(e),t.render(this.id,this.graph,t=>{this.svg=t,document.body.removeChild(e)},e)})},components:{Loading:Nc}};var Uc=n(95),zc=n.n(Uc);n(245);Hn.component("CodeSwitcher",()=>n.e(28).then(n.bind(null,384)));var qc={tags:{Channels:{key:"Channels",scope:"tags",path:"/blog/tags/Channels/",pageKeys:["v-109b7b6a"]},"Anchor Outputs":{key:"Anchor Outputs",scope:"tags",path:"/blog/tags/Anchor Outputs/",pageKeys:["v-109b7b6a"]},Fees:{key:"Fees",scope:"tags",path:"/blog/tags/Fees/",pageKeys:["v-109b7b6a"]},"Self-custody":{key:"Self-custody",scope:"tags",path:"/blog/tags/Self-custody/",pageKeys:["v-0f4e007e"]},Mobile:{key:"Mobile",scope:"tags",path:"/blog/tags/Mobile/",pageKeys:["v-0f4e007e","v-67ea603f"]},"Case Studies":{key:"Case Studies",scope:"tags",path:"/blog/tags/Case Studies/",pageKeys:["v-59a63080","v-e02a8a76","v-61c088e6","v-394e384e","v-4ffe1afe"]},Offers:{key:"Offers",scope:"tags",path:"/blog/tags/Offers/",pageKeys:["v-6018492a","v-7b672071"]},"Onion Messages":{key:"Onion Messages",scope:"tags",path:"/blog/tags/Onion Messages/",pageKeys:["v-6018492a","v-7b672071"]},Privacy:{key:"Privacy",scope:"tags",path:"/blog/tags/Privacy/",pageKeys:["v-6018492a"]},Gossip:{key:"Gossip",scope:"tags",path:"/blog/tags/Gossip/",pageKeys:["v-2578306f"]},"Network Graph":{key:"Network Graph",scope:"tags",path:"/blog/tags/Network Graph/",pageKeys:["v-2578306f"]},Enterprise:{key:"Enterprise",scope:"tags",path:"/blog/tags/Enterprise/",pageKeys:["v-177ef1fe"]},Phantom:{key:"Phantom",scope:"tags",path:"/blog/tags/Phantom/",pageKeys:["v-177ef1fe"]},Bitcoin:{key:"Bitcoin",scope:"tags",path:"/blog/tags/Bitcoin/",pageKeys:["v-eebe6fe6"]},LDK:{key:"LDK",scope:"tags",path:"/blog/tags/LDK/",pageKeys:["v-eebe6fe6"]},Roadmap:{key:"Roadmap",scope:"tags",path:"/blog/tags/Roadmap/",pageKeys:["v-7b0f0961"]},"Non-Custodial":{key:"Non-Custodial",scope:"tags",path:"/blog/tags/Non-Custodial/",pageKeys:["v-67ea603f"]},liquidity:{key:"liquidity",scope:"tags",path:"/blog/tags/liquidity/",pageKeys:["v-4c78f51d"]},"0-Conf Channels":{key:"0-Conf Channels",scope:"tags",path:"/blog/tags/0-Conf Channels/",pageKeys:["v-3843152b"]}},author:{"Wilmer Paulino":{key:"Wilmer Paulino",scope:"author",path:"/blog/author/Wilmer Paulino/",pageKeys:["v-109b7b6a"]},"Elias Rohrer":{key:"Elias Rohrer",scope:"author",path:"/blog/author/Elias Rohrer/",pageKeys:["v-0f4e007e"]},"Matt Carvalho":{key:"Matt Carvalho",scope:"author",path:"/blog/author/Matt Carvalho/",pageKeys:["v-59a63080"]},"Jeff Czyz":{key:"Jeff Czyz",scope:"author",path:"/blog/author/Jeff Czyz/",pageKeys:["v-6018492a"]},"Ryan Loomba":{key:"Ryan Loomba",scope:"author",path:"/blog/author/Ryan Loomba/",pageKeys:["v-e02a8a76"]},"Arik Sosman":{key:"Arik Sosman",scope:"author",path:"/blog/author/Arik Sosman/",pageKeys:["v-2578306f"]},"Valentine Wallace":{key:"Valentine Wallace",scope:"author",path:"/blog/author/Valentine Wallace/",pageKeys:["v-177ef1fe","v-7b672071"]},"Conor Okus":{key:"Conor Okus",scope:"author",path:"/blog/author/Conor Okus/",pageKeys:["v-eebe6fe6"]},"Steve Lee":{key:"Steve Lee",scope:"author",path:"/blog/author/Steve Lee/",pageKeys:["v-7b0f0961"]},"Ben Carman":{key:"Ben Carman",scope:"author",path:"/blog/author/Ben Carman/",pageKeys:["v-61c088e6"]},"John Cantrell":{key:"John Cantrell",scope:"author",path:"/blog/author/John Cantrell/",pageKeys:["v-394e384e","v-4c78f51d","v-3843152b"]},"Sergi Delgado":{key:"Sergi Delgado",scope:"author",path:"/blog/author/Sergi Delgado/",pageKeys:["v-4ffe1afe"]},"Matt Corallo":{key:"Matt Corallo",scope:"author",path:"/blog/author/Matt Corallo/",pageKeys:["v-67ea603f"]}}};class Wc{constructor(t,e){this._metaMap=Object.assign({},t),Object.keys(this._metaMap).forEach(t=>{const{pageKeys:n}=this._metaMap[t];this._metaMap[t].pages=n.map(t=>function(t,e){for(let n=0;n{const{pages:n,path:i}=this._metaMap[e];t.push({name:e,pages:n,path:i})}),t}getItemByName(t){return this._metaMap[t]}}var Hc={blog:(t,e)=>{const i=n(45);return i(t.frontmatter.date)-i(e.frontmatter.date)>0?-1:1},tags:(t,e)=>{const i=n(45);return i(t.frontmatter.date)-i(e.frontmatter.date)>0?-1:1},author:(t,e)=>{const i=n(45);return i(t.frontmatter.date)-i(e.frontmatter.date)>0?-1:1}},Vc={blog:function(t,e,n){return t.pid===n&&t.id===e},tags:function(t,e,n){const i=e;return["tags"].some(e=>{const n=t.frontmatter[e];return Array.isArray(n)?n.some(t=>t==i):n==i})},author:function(t,e,n){const i=e;return["author","authors"].some(e=>{const n=t.frontmatter[e];return Array.isArray(n)?n.some(t=>t==i):n==i})}},Gc=[{pid:"blog",id:"blog",filter:Vc.blog,sorter:Hc.blog,pages:[{path:"/blog/",interval:[0,9]},{path:"/blog/page/2/",interval:[10,16]}],prevText:"Prev",nextText:"Next"},{pid:"tags",id:"Channels",filter:Vc.tags,sorter:Hc.tags,pages:[{path:"/blog/tags/Channels/",interval:[0,1]}],prevText:"Prev",nextText:"Next"},{pid:"tags",id:"Anchor Outputs",filter:Vc.tags,sorter:Hc.tags,pages:[{path:"/blog/tags/Anchor Outputs/",interval:[0,1]}],prevText:"Prev",nextText:"Next"},{pid:"tags",id:"Fees",filter:Vc.tags,sorter:Hc.tags,pages:[{path:"/blog/tags/Fees/",interval:[0,1]}],prevText:"Prev",nextText:"Next"},{pid:"tags",id:"Self-custody",filter:Vc.tags,sorter:Hc.tags,pages:[{path:"/blog/tags/Self-custody/",interval:[0,1]}],prevText:"Prev",nextText:"Next"},{pid:"tags",id:"Mobile",filter:Vc.tags,sorter:Hc.tags,pages:[{path:"/blog/tags/Mobile/",interval:[0,2]}],prevText:"Prev",nextText:"Next"},{pid:"tags",id:"Case Studies",filter:Vc.tags,sorter:Hc.tags,pages:[{path:"/blog/tags/Case Studies/",interval:[0,5]}],prevText:"Prev",nextText:"Next"},{pid:"tags",id:"Offers",filter:Vc.tags,sorter:Hc.tags,pages:[{path:"/blog/tags/Offers/",interval:[0,2]}],prevText:"Prev",nextText:"Next"},{pid:"tags",id:"Onion Messages",filter:Vc.tags,sorter:Hc.tags,pages:[{path:"/blog/tags/Onion Messages/",interval:[0,2]}],prevText:"Prev",nextText:"Next"},{pid:"tags",id:"Privacy",filter:Vc.tags,sorter:Hc.tags,pages:[{path:"/blog/tags/Privacy/",interval:[0,1]}],prevText:"Prev",nextText:"Next"},{pid:"tags",id:"Gossip",filter:Vc.tags,sorter:Hc.tags,pages:[{path:"/blog/tags/Gossip/",interval:[0,1]}],prevText:"Prev",nextText:"Next"},{pid:"tags",id:"Network Graph",filter:Vc.tags,sorter:Hc.tags,pages:[{path:"/blog/tags/Network Graph/",interval:[0,1]}],prevText:"Prev",nextText:"Next"},{pid:"tags",id:"Enterprise",filter:Vc.tags,sorter:Hc.tags,pages:[{path:"/blog/tags/Enterprise/",interval:[0,1]}],prevText:"Prev",nextText:"Next"},{pid:"tags",id:"Phantom",filter:Vc.tags,sorter:Hc.tags,pages:[{path:"/blog/tags/Phantom/",interval:[0,1]}],prevText:"Prev",nextText:"Next"},{pid:"tags",id:"Bitcoin",filter:Vc.tags,sorter:Hc.tags,pages:[{path:"/blog/tags/Bitcoin/",interval:[0,1]}],prevText:"Prev",nextText:"Next"},{pid:"tags",id:"LDK",filter:Vc.tags,sorter:Hc.tags,pages:[{path:"/blog/tags/LDK/",interval:[0,1]}],prevText:"Prev",nextText:"Next"},{pid:"tags",id:"Roadmap",filter:Vc.tags,sorter:Hc.tags,pages:[{path:"/blog/tags/Roadmap/",interval:[0,1]}],prevText:"Prev",nextText:"Next"},{pid:"tags",id:"Non-Custodial",filter:Vc.tags,sorter:Hc.tags,pages:[{path:"/blog/tags/Non-Custodial/",interval:[0,1]}],prevText:"Prev",nextText:"Next"},{pid:"tags",id:"liquidity",filter:Vc.tags,sorter:Hc.tags,pages:[{path:"/blog/tags/liquidity/",interval:[0,1]}],prevText:"Prev",nextText:"Next"},{pid:"tags",id:"0-Conf Channels",filter:Vc.tags,sorter:Hc.tags,pages:[{path:"/blog/tags/0-Conf Channels/",interval:[0,1]}],prevText:"Prev",nextText:"Next"},{pid:"author",id:"Wilmer Paulino",filter:Vc.author,sorter:Hc.author,pages:[{path:"/blog/author/Wilmer Paulino/",interval:[0,1]}],prevText:"Prev",nextText:"Next"},{pid:"author",id:"Elias Rohrer",filter:Vc.author,sorter:Hc.author,pages:[{path:"/blog/author/Elias Rohrer/",interval:[0,1]}],prevText:"Prev",nextText:"Next"},{pid:"author",id:"Matt Carvalho",filter:Vc.author,sorter:Hc.author,pages:[{path:"/blog/author/Matt Carvalho/",interval:[0,1]}],prevText:"Prev",nextText:"Next"},{pid:"author",id:"Jeff Czyz",filter:Vc.author,sorter:Hc.author,pages:[{path:"/blog/author/Jeff Czyz/",interval:[0,1]}],prevText:"Prev",nextText:"Next"},{pid:"author",id:"Ryan Loomba",filter:Vc.author,sorter:Hc.author,pages:[{path:"/blog/author/Ryan Loomba/",interval:[0,1]}],prevText:"Prev",nextText:"Next"},{pid:"author",id:"Arik Sosman",filter:Vc.author,sorter:Hc.author,pages:[{path:"/blog/author/Arik Sosman/",interval:[0,1]}],prevText:"Prev",nextText:"Next"},{pid:"author",id:"Valentine Wallace",filter:Vc.author,sorter:Hc.author,pages:[{path:"/blog/author/Valentine Wallace/",interval:[0,2]}],prevText:"Prev",nextText:"Next"},{pid:"author",id:"Conor Okus",filter:Vc.author,sorter:Hc.author,pages:[{path:"/blog/author/Conor Okus/",interval:[0,1]}],prevText:"Prev",nextText:"Next"},{pid:"author",id:"Steve Lee",filter:Vc.author,sorter:Hc.author,pages:[{path:"/blog/author/Steve Lee/",interval:[0,1]}],prevText:"Prev",nextText:"Next"},{pid:"author",id:"Ben Carman",filter:Vc.author,sorter:Hc.author,pages:[{path:"/blog/author/Ben Carman/",interval:[0,1]}],prevText:"Prev",nextText:"Next"},{pid:"author",id:"John Cantrell",filter:Vc.author,sorter:Hc.author,pages:[{path:"/blog/author/John Cantrell/",interval:[0,3]}],prevText:"Prev",nextText:"Next"},{pid:"author",id:"Sergi Delgado",filter:Vc.author,sorter:Hc.author,pages:[{path:"/blog/author/Sergi Delgado/",interval:[0,1]}],prevText:"Prev",nextText:"Next"},{pid:"author",id:"Matt Corallo",filter:Vc.author,sorter:Hc.author,pages:[{path:"/blog/author/Matt Corallo/",interval:[0,1]}],prevText:"Prev",nextText:"Next"}],Jc=n(96);const Zc=n.n(Jc)()("plugin-blog:pagination");class Yc{constructor(t,e,n){Zc("pagination",t);const{pages:i,prevText:r,nextText:o}=t,{path:a}=n;this._prevText=r,this._nextText=o;for(let t=0,e=i.length;tt.filter(e,t.id,t.pid)).sort(t.sorter)}setIndexPage(t){this._indexPage=t}get length(){return this._paginationPages.length}get pages(){const[t,e]=this._currentPage.interval;return this._matchedPages.slice(t,e+1)}get hasPrev(){return 0!==this.paginationIndex}get prevLink(){return this.hasPrev?this.paginationIndex-1==0&&this._indexPage?this._indexPage:this._paginationPages[this.paginationIndex-1].path:null}get hasNext(){return this.paginationIndex!==this.length-1}get nextLink(){return this.hasNext?this._paginationPages[this.paginationIndex+1].path:null}get prevText(){return this._prevText}get nextText(){return this._nextText}getSpecificPageLink(t){return this._paginationPages[t].path}}const Xc=new class{constructor(t){this.paginations=t}get pages(){return Hn.$vuepress.$get("siteData").pages}getPagination(t,e,n){Zc("id",e),Zc("pid",t);const i=this.paginations.filter(n=>n.id===e&&n.pid===t)[0];return new Yc(i,this.pages,n)}}(Gc);var Qc={comment:{enabled:!1,service:""},email:{enabled:!1},feed:{rss:!1,atom:!1,json:!1}},ts=[({router:t})=>{"undefined"!=typeof process&&"server"===process.env.VUE_ENV||t.onReady(()=>{const{app:e}=t;e.$once("hook:mounted",()=>{setTimeout(()=>{const{hash:t}=document.location;if(t.length>1){const e=t.substring(1),n=document.getElementById(e);n&&n.scrollIntoView()}},500)}),document.addEventListener("click",Fc),document.addEventListener("keyup",t=>{Bc(t)&&Fc(t)})})},{},({Vue:t})=>{t.mixin({computed:{$dataBlock(){return this.$options.__data__block__}}})},{},{},({Vue:t})=>{t.component("CodeCopy",Sc)},({Vue:t})=>{t.component("Mermaid",Ic)},({Vue:t})=>t.use(zc.a),{},{},({Vue:t})=>{const e=Object.keys(qc).map(t=>{const e=qc[t],n="$"+t;return{[n](){const{pages:t}=this.$site;return new Wc(e,t)},["$current"+(t.charAt(0).toUpperCase()+t.slice(1))](){const t=this.$route.meta.id;return this[n].getItemByName(t)}}}).reduce((t,e)=>(Object.assign(t,e),t),{});e.$frontmatterKey=function(){const t=this["$"+this.$route.meta.id];return t||null},t.mixin({computed:e})},({Vue:t})=>{t.mixin({computed:{$pagination(){return this.$route.meta.pid&&this.$route.meta.id?this.$getPagination(this.$route.meta.pid,this.$route.meta.id):null}},methods:{$getPagination(t,e){return e=e||t,Xc.getPagination(t,e,this.$route)}}})},({Vue:t})=>{const e={$service:()=>Qc};t.mixin({computed:e})}],es=[];class ns extends class{constructor(){this.store=new Hn({data:{state:{}}})}$get(t){return this.store.state[t]}$set(t,e){Hn.set(this.store.state,t,e)}$emit(...t){this.store.$emit(...t)}$on(...t){this.store.$on(...t)}}{}Object.assign(ns.prototype,{getPageAsyncComponent:ac,getLayoutAsyncComponent:cc,getAsyncComponent:sc,getVueComponent:lc});var is={install(t){const e=new ns;t.$vuepress=e,t.prototype.$vuepress=e}};function rs(t,e){const n=e.toLowerCase();return t.options.routes.some(t=>t.path.toLowerCase()===n)}var os={props:{pageKey:String,slotKey:{type:String,default:"default"}},render(t){const e=this.pageKey||this.$parent.$page.key;return uc("pageKey",e),Hn.component(e)||Hn.component(e,ac(e)),Hn.component(e)?t(e):t("")}},as={functional:!0,props:{slotKey:String,required:!0},render:(t,{props:e,slots:n})=>t("div",{class:["content__"+e.slotKey]},n()[e.slotKey])},cs={computed:{openInNewWindowTitle(){return this.$themeLocaleConfig.openNewWindowText||"(opens new window)"}}},ss=(n(248),n(249),Object(Cc.a)(cs,(function(){var t=this._self._c;return t("span",[t("svg",{staticClass:"icon outbound",attrs:{xmlns:"http://www.w3.org/2000/svg","aria-hidden":"true",focusable:"false",x:"0px",y:"0px",viewBox:"0 0 100 100",width:"15",height:"15"}},[t("path",{attrs:{fill:"currentColor",d:"M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"}}),this._v(" "),t("polygon",{attrs:{fill:"currentColor",points:"45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"}})]),this._v(" "),t("span",{staticClass:"sr-only"},[this._v(this._s(this.openInNewWindowTitle))])])}),[],!1,null,null,null).exports),ls={functional:!0,render(t,{parent:e,children:n}){if(e._isMounted)return n;e.$once("hook:mounted",()=>{e.$forceUpdate()})}};Hn.config.productionTip=!1,Hn.use(qa),Hn.use(is),Hn.mixin(function(t,e,n=Hn){!function(t){t.locales&&Object.keys(t.locales).forEach(e=>{t.locales[e].path=e});Object.freeze(t)}(e),n.$vuepress.$set("siteData",e);const i=new(t(n.$vuepress.$get("siteData"))),r=Object.getOwnPropertyDescriptors(Object.getPrototypeOf(i)),o={};return Object.keys(r).reduce((t,e)=>(e.startsWith("$")&&(t[e]=r[e].get),t),o),{computed:o}}(t=>class{setPage(t){this.__page=t}get $site(){return t}get $themeConfig(){return this.$site.themeConfig}get $frontmatter(){return this.$page.frontmatter}get $localeConfig(){const{locales:t={}}=this.$site;let e,n;for(const i in t)"/"===i?n=t[i]:0===this.$page.path.indexOf(i)&&(e=t[i]);return e||n||{}}get $siteTitle(){return this.$localeConfig.title||this.$site.title||""}get $canonicalUrl(){const{canonicalUrl:t}=this.$page.frontmatter;return"string"==typeof t&&t}get $title(){const t=this.$page,{metaTitle:e}=this.$page.frontmatter;if("string"==typeof e)return e;const n=this.$siteTitle,i=t.frontmatter.home?null:t.frontmatter.title||t.title;return n?i?i+" | "+n:n:i||"VuePress"}get $description(){const t=function(t){if(t){const e=t.filter(t=>"description"===t.name)[0];if(e)return e.content}}(this.$page.frontmatter.meta);return t||(this.$page.frontmatter.description||this.$localeConfig.description||this.$site.description||"")}get $lang(){return this.$page.frontmatter.lang||this.$localeConfig.lang||"en-US"}get $localePath(){return this.$localeConfig.path||"/"}get $themeLocaleConfig(){return(this.$site.themeConfig.locales||{})[this.$localePath]||{}}get $page(){return this.__page?this.__page:function(t,e){for(let n=0;nn||(t.hash?!Hn.$vuepress.$get("disableScrollBehavior")&&{selector:decodeURIComponent(t.hash)}:{x:0,y:0})});!function(t){t.beforeEach((e,n,i)=>{if(rs(t,e.path))i();else if(/(\/|\.html)$/.test(e.path))if(/\/$/.test(e.path)){const n=e.path.replace(/\/$/,"")+".html";rs(t,n)?i(n):i()}else i();else{const n=e.path+"/",r=e.path+".html";rs(t,r)?i(r):rs(t,n)?i(n):i()}})}(n);const i={};try{await Promise.all(ts.filter(t=>"function"==typeof t).map(e=>e({Vue:Hn,options:i,router:n,siteData:Ec,isServer:t})))}catch(t){console.error(t)}return{app:new Hn(Object.assign(i,{router:n,render:t=>t("div",{attrs:{id:"app"}},[t("RouterView",{ref:"layout"}),t("div",{class:"global-ui"},es.map(e=>t(e)))])})),router:n}}(!1).then(({app:t,router:e})=>{e.onReady(()=>{t.$mount("#app")})})}]); \ No newline at end of file +var i=Object.freeze({}),r=Array.isArray;function o(t){return null==t}function a(t){return null!=t}function c(t){return!0===t}function s(t){return"string"==typeof t||"number"==typeof t||"symbol"==typeof t||"boolean"==typeof t}function l(t){return"function"==typeof t}function p(t){return null!==t&&"object"==typeof t}var u=Object.prototype.toString;function g(t){return"[object Object]"===u.call(t)}function d(t){return"[object RegExp]"===u.call(t)}function h(t){var e=parseFloat(String(t));return e>=0&&Math.floor(e)===e&&isFinite(t)}function f(t){return a(t)&&"function"==typeof t.then&&"function"==typeof t.catch}function m(t){return null==t?"":Array.isArray(t)||g(t)&&t.toString===u?JSON.stringify(t,null,2):String(t)}function v(t){var e=parseFloat(t);return isNaN(e)?t:e}function y(t,e){for(var n=Object.create(null),i=t.split(","),r=0;r-1)return t.splice(i,1)}}var k=Object.prototype.hasOwnProperty;function _(t,e){return k.call(t,e)}function L(t){var e=Object.create(null);return function(n){return e[n]||(e[n]=t(n))}}var D=/-(\w)/g,x=L((function(t){return t.replace(D,(function(t,e){return e?e.toUpperCase():""}))})),P=L((function(t){return t.charAt(0).toUpperCase()+t.slice(1)})),C=/\B([A-Z])/g,S=L((function(t){return t.replace(C,"-$1").toLowerCase()}));var K=Function.prototype.bind?function(t,e){return t.bind(e)}:function(t,e){function n(n){var i=arguments.length;return i?i>1?t.apply(e,arguments):t.call(e,n):t.call(e)}return n._length=t.length,n};function O(t,e){e=e||0;for(var n=t.length-e,i=new Array(n);n--;)i[n]=t[n+e];return i}function T(t,e){for(var n in e)t[n]=e[n];return t}function $(t){for(var e={},n=0;n0,X=J&&J.indexOf("edge/")>0;J&&J.indexOf("android");var Q=J&&/iphone|ipad|ipod|ios/.test(J);J&&/chrome\/\d+/.test(J),J&&/phantomjs/.test(J);var tt,et=J&&J.match(/firefox\/(\d+)/),nt={}.watch,it=!1;if(G)try{var rt={};Object.defineProperty(rt,"passive",{get:function(){it=!0}}),window.addEventListener("test-passive",null,rt)}catch(t){}var ot=function(){return void 0===tt&&(tt=!G&&"undefined"!=typeof global&&(global.process&&"server"===global.process.env.VUE_ENV)),tt},at=G&&window.__VUE_DEVTOOLS_GLOBAL_HOOK__;function ct(t){return"function"==typeof t&&/native code/.test(t.toString())}var st,lt="undefined"!=typeof Symbol&&ct(Symbol)&&"undefined"!=typeof Reflect&&ct(Reflect.ownKeys);st="undefined"!=typeof Set&&ct(Set)?Set:function(){function t(){this.set=Object.create(null)}return t.prototype.has=function(t){return!0===this.set[t]},t.prototype.add=function(t){this.set[t]=!0},t.prototype.clear=function(){this.set=Object.create(null)},t}();var pt=null;function ut(t){void 0===t&&(t=null),t||pt&&pt._scope.off(),pt=t,t&&t._scope.on()}var gt=function(){function t(t,e,n,i,r,o,a,c){this.tag=t,this.data=e,this.children=n,this.text=i,this.elm=r,this.ns=void 0,this.context=o,this.fnContext=void 0,this.fnOptions=void 0,this.fnScopeId=void 0,this.key=e&&e.key,this.componentOptions=a,this.componentInstance=void 0,this.parent=void 0,this.raw=!1,this.isStatic=!1,this.isRootInsert=!0,this.isComment=!1,this.isCloned=!1,this.isOnce=!1,this.asyncFactory=c,this.asyncMeta=void 0,this.isAsyncPlaceholder=!1}return Object.defineProperty(t.prototype,"child",{get:function(){return this.componentInstance},enumerable:!1,configurable:!0}),t}(),dt=function(t){void 0===t&&(t="");var e=new gt;return e.text=t,e.isComment=!0,e};function ht(t){return new gt(void 0,void 0,void 0,String(t))}function ft(t){var e=new gt(t.tag,t.data,t.children&&t.children.slice(),t.text,t.elm,t.context,t.componentOptions,t.asyncFactory);return e.ns=t.ns,e.isStatic=t.isStatic,e.key=t.key,e.isComment=t.isComment,e.fnContext=t.fnContext,e.fnOptions=t.fnOptions,e.fnScopeId=t.fnScopeId,e.asyncMeta=t.asyncMeta,e.isCloned=!0,e}var mt=0,vt=[],yt=function(){function t(){this._pending=!1,this.id=mt++,this.subs=[]}return t.prototype.addSub=function(t){this.subs.push(t)},t.prototype.removeSub=function(t){this.subs[this.subs.indexOf(t)]=null,this._pending||(this._pending=!0,vt.push(this))},t.prototype.depend=function(e){t.target&&t.target.addDep(this)},t.prototype.notify=function(t){var e=this.subs.filter((function(t){return t}));for(var n=0,i=e.length;n0&&(Jt((l=t(l,"".concat(n||"","_").concat(i)))[0])&&Jt(u)&&(g[p]=ht(u.text+l[0].text),l.shift()),g.push.apply(g,l)):s(l)?Jt(u)?g[p]=ht(u.text+l):""!==l&&g.push(ht(l)):Jt(l)&&Jt(u)?g[p]=ht(u.text+l.text):(c(e._isVList)&&a(l.tag)&&o(l.key)&&a(n)&&(l.key="__vlist".concat(n,"_").concat(i,"__")),g.push(l)));return g}(t):void 0}function Jt(t){return a(t)&&a(t.text)&&!1===t.isComment}function Zt(t,e){var n,i,o,c,s=null;if(r(t)||"string"==typeof t)for(s=new Array(t.length),n=0,i=t.length;n0,c=e?!!e.$stable:!a,s=e&&e.$key;if(e){if(e._normalized)return e._normalized;if(c&&r&&r!==i&&s===r.$key&&!a&&!r.$hasNormal)return r;for(var l in o={},e)e[l]&&"$"!==l[0]&&(o[l]=fe(t,n,l,e[l]))}else o={};for(var p in n)p in o||(o[p]=me(n,p));return e&&Object.isExtensible(e)&&(e._normalized=o),W(o,"$stable",c),W(o,"$key",s),W(o,"$hasNormal",a),o}function fe(t,e,n,i){var o=function(){var e=pt;ut(t);var n=arguments.length?i.apply(null,arguments):i({}),o=(n=n&&"object"==typeof n&&!r(n)?[n]:Gt(n))&&n[0];return ut(e),n&&(!o||1===n.length&&o.isComment&&!de(o))?void 0:n};return i.proxy&&Object.defineProperty(e,n,{get:o,enumerable:!0,configurable:!0}),o}function me(t,e){return function(){return t[e]}}function ve(t){return{get attrs(){if(!t._attrsProxy){var e=t._attrsProxy={};W(e,"_v_attr_proxy",!0),ye(e,t.$attrs,i,t,"$attrs")}return t._attrsProxy},get listeners(){t._listenersProxy||ye(t._listenersProxy={},t.$listeners,i,t,"$listeners");return t._listenersProxy},get slots(){return function(t){t._slotsProxy||we(t._slotsProxy={},t.$scopedSlots);return t._slotsProxy}(t)},emit:K(t.$emit,t),expose:function(e){e&&Object.keys(e).forEach((function(n){return Rt(t,e,n)}))}}}function ye(t,e,n,i,r){var o=!1;for(var a in e)a in t?e[a]!==n[a]&&(o=!0):(o=!0,be(t,a,i,r));for(var a in t)a in e||(o=!0,delete t[a]);return o}function be(t,e,n,i){Object.defineProperty(t,e,{enumerable:!0,configurable:!0,get:function(){return n[i][e]}})}function we(t,e){for(var n in e)t[n]=e[n];for(var n in t)n in e||delete t[n]}var ke=null;function _e(t,e){return(t.__esModule||lt&&"Module"===t[Symbol.toStringTag])&&(t=t.default),p(t)?e.extend(t):t}function Le(t){if(r(t))for(var e=0;edocument.createEvent("Event").timeStamp&&(sn=function(){return ln.now()})}var pn=function(t,e){if(t.post){if(!e.post)return 1}else if(e.post)return-1;return t.id-e.id};function un(){var t,e;for(cn=sn(),on=!0,tn.sort(pn),an=0;anan&&tn[n].id>t.id;)n--;tn.splice(n+1,0,t)}else tn.push(t);rn||(rn=!0,Fe(un))}}function dn(t,e){if(t){for(var n=Object.create(null),i=lt?Reflect.ownKeys(t):Object.keys(t),r=0;r-1)if(o&&!_(r,"default"))a=!1;else if(""===a||a===S(t)){var s=An(String,r.type);(s<0||c-1:"string"==typeof t?t.split(",").indexOf(e)>-1:!!d(t)&&t.test(e)}function Zn(t,e){var n=t.cache,i=t.keys,r=t._vnode;for(var o in n){var a=n[o];if(a){var c=a.name;c&&!e(c)&&Yn(n,o,i,r)}}}function Yn(t,e,n,i){var r=t[e];!r||i&&r.tag===i.tag||r.componentInstance.$destroy(),t[e]=null,w(n,e)}Hn.prototype._init=function(t){var e=this;e._uid=qn++,e._isVue=!0,e.__v_skip=!0,e._scope=new It(!0),e._scope._vm=!0,t&&t._isComponent?function(t,e){var n=t.$options=Object.create(t.constructor.options),i=e._parentVnode;n.parent=e.parent,n._parentVnode=i;var r=i.componentOptions;n.propsData=r.propsData,n._parentListeners=r.listeners,n._renderChildren=r.children,n._componentTag=r.tag,e.render&&(n.render=e.render,n.staticRenderFns=e.staticRenderFns)}(e,t):e.$options=Kn(Wn(e.constructor),t||{},e),e._renderProxy=e,e._self=e,function(t){var e=t.$options,n=e.parent;if(n&&!e.abstract){for(;n.$options.abstract&&n.$parent;)n=n.$parent;n.$children.push(t)}t.$parent=n,t.$root=n?n.$root:t,t.$children=[],t.$refs={},t._provided=n?n._provided:Object.create(null),t._watcher=null,t._inactive=null,t._directInactive=!1,t._isMounted=!1,t._isDestroyed=!1,t._isBeingDestroyed=!1}(e),function(t){t._events=Object.create(null),t._hasHookEvent=!1;var e=t.$options._parentListeners;e&&Ge(t,e)}(e),function(t){t._vnode=null,t._staticTrees=null;var e=t.$options,n=t.$vnode=e._parentVnode,r=n&&n.context;t.$slots=ue(e._renderChildren,r),t.$scopedSlots=n?he(t.$parent,n.data.scopedSlots,t.$slots):i,t._c=function(e,n,i,r){return De(t,e,n,i,r,!1)},t.$createElement=function(e,n,i,r){return De(t,e,n,i,r,!0)};var o=n&&n.data;Tt(t,"$attrs",o&&o.attrs||i,null,!0),Tt(t,"$listeners",e._parentListeners||i,null,!0)}(e),Qe(e,"beforeCreate",void 0,!1),function(t){var e=dn(t.$options.inject,t);e&&(Ct(!1),Object.keys(e).forEach((function(n){Tt(t,n,e[n])})),Ct(!0))}(e),Fn(e),function(t){var e=t.$options.provide;if(e){var n=l(e)?e.call(t):e;if(!p(n))return;for(var i=Ut(t),r=lt?Reflect.ownKeys(n):Object.keys(n),o=0;o1?O(n):n;for(var i=O(arguments,1),r='event handler for "'.concat(t,'"'),o=0,a=n.length;oparseInt(this.max)&&Yn(t,e[0],e,this._vnode),this.vnodeToCache=null}}},created:function(){this.cache=Object.create(null),this.keys=[]},destroyed:function(){for(var t in this.cache)Yn(this.cache,t,this.keys)},mounted:function(){var t=this;this.cacheVNode(),this.$watch("include",(function(e){Zn(t,(function(t){return Jn(e,t)}))})),this.$watch("exclude",(function(e){Zn(t,(function(t){return!Jn(e,t)}))}))},updated:function(){this.cacheVNode()},render:function(){var t=this.$slots.default,e=Le(t),n=e&&e.componentOptions;if(n){var i=Gn(n),r=this.include,o=this.exclude;if(r&&(!i||!Jn(r,i))||o&&i&&Jn(o,i))return e;var a=this.cache,c=this.keys,s=null==e.key?n.Ctor.cid+(n.tag?"::".concat(n.tag):""):e.key;a[s]?(e.componentInstance=a[s].componentInstance,w(c,s),c.push(s)):(this.vnodeToCache=e,this.keyToCache=s),e.data.keepAlive=!0}return e||t&&t[0]}}};!function(t){var e={get:function(){return U}};Object.defineProperty(t,"config",e),t.util={warn:_n,extend:T,mergeOptions:Kn,defineReactive:Tt},t.set=$t,t.delete=Et,t.nextTick=Fe,t.observable=function(t){return Ot(t),t},t.options=Object.create(null),N.forEach((function(e){t.options[e+"s"]=Object.create(null)})),t.options._base=t,T(t.options.components,Qn),function(t){t.use=function(t){var e=this._installedPlugins||(this._installedPlugins=[]);if(e.indexOf(t)>-1)return this;var n=O(arguments,1);return n.unshift(this),l(t.install)?t.install.apply(t,n):l(t)&&t.apply(null,n),e.push(t),this}}(t),function(t){t.mixin=function(t){return this.options=Kn(this.options,t),this}}(t),Vn(t),function(t){N.forEach((function(e){t[e]=function(t,n){return n?("component"===e&&g(n)&&(n.name=n.name||t,n=this.options._base.extend(n)),"directive"===e&&l(n)&&(n={bind:n,update:n}),this.options[e+"s"][t]=n,n):this.options[e+"s"][t]}}))}(t)}(Hn),Object.defineProperty(Hn.prototype,"$isServer",{get:ot}),Object.defineProperty(Hn.prototype,"$ssrContext",{get:function(){return this.$vnode&&this.$vnode.ssrContext}}),Object.defineProperty(Hn,"FunctionalRenderContext",{value:hn}),Hn.version="2.7.14";var ti=y("style,class"),ei=y("input,textarea,option,select,progress"),ni=y("contenteditable,draggable,spellcheck"),ii=y("events,caret,typing,plaintext-only"),ri=y("allowfullscreen,async,autofocus,autoplay,checked,compact,controls,declare,default,defaultchecked,defaultmuted,defaultselected,defer,disabled,enabled,formnovalidate,hidden,indeterminate,inert,ismap,itemscope,loop,multiple,muted,nohref,noresize,noshade,novalidate,nowrap,open,pauseonexit,readonly,required,reversed,scoped,seamless,selected,sortable,truespeed,typemustmatch,visible"),oi="http://www.w3.org/1999/xlink",ai=function(t){return":"===t.charAt(5)&&"xlink"===t.slice(0,5)},ci=function(t){return ai(t)?t.slice(6,t.length):""},si=function(t){return null==t||!1===t};function li(t){for(var e=t.data,n=t,i=t;a(i.componentInstance);)(i=i.componentInstance._vnode)&&i.data&&(e=pi(i.data,e));for(;a(n=n.parent);)n&&n.data&&(e=pi(e,n.data));return function(t,e){if(a(t)||a(e))return ui(t,gi(e));return""}(e.staticClass,e.class)}function pi(t,e){return{staticClass:ui(t.staticClass,e.staticClass),class:a(t.class)?[t.class,e.class]:e.class}}function ui(t,e){return t?e?t+" "+e:t:e||""}function gi(t){return Array.isArray(t)?function(t){for(var e,n="",i=0,r=t.length;i-1?ji(t,e,n):ri(e)?si(n)?t.removeAttribute(e):(n="allowfullscreen"===e&&"EMBED"===t.tagName?"true":e,t.setAttribute(e,n)):ni(e)?t.setAttribute(e,function(t,e){return si(e)||"false"===e?"false":"contenteditable"===t&&ii(e)?e:"true"}(e,n)):ai(e)?si(n)?t.removeAttributeNS(oi,ci(e)):t.setAttributeNS(oi,e,n):ji(t,e,n)}function ji(t,e,n){if(si(n))t.removeAttribute(e);else{if(Z&&!Y&&"TEXTAREA"===t.tagName&&"placeholder"===e&&""!==n&&!t.__ieph){var i=function(e){e.stopImmediatePropagation(),t.removeEventListener("input",i)};t.addEventListener("input",i),t.__ieph=!0}t.setAttribute(e,n)}}var Bi={create:Mi,update:Mi};function Fi(t,e){var n=e.elm,i=e.data,r=t.data;if(!(o(i.staticClass)&&o(i.class)&&(o(r)||o(r.staticClass)&&o(r.class)))){var c=li(e),s=n._transitionClasses;a(s)&&(c=ui(c,gi(s))),c!==n._prevClass&&(n.setAttribute("class",c),n._prevClass=c)}}var Ri,Ni={create:Fi,update:Fi};function Ii(t,e,n){var i=Ri;return function r(){var o=e.apply(null,arguments);null!==o&&qi(t,r,n,i)}}var Ui=Oe&&!(et&&Number(et[1])<=53);function zi(t,e,n,i){if(Ui){var r=cn,o=e;e=o._wrapper=function(t){if(t.target===t.currentTarget||t.timeStamp>=r||t.timeStamp<=0||t.target.ownerDocument!==document)return o.apply(this,arguments)}}Ri.addEventListener(t,e,it?{capture:n,passive:i}:n)}function qi(t,e,n,i){(i||Ri).removeEventListener(t,e._wrapper||e,n)}function Wi(t,e){if(!o(t.data.on)||!o(e.data.on)){var n=e.data.on||{},i=t.data.on||{};Ri=e.elm||t.elm,function(t){if(a(t.__r)){var e=Z?"change":"input";t[e]=[].concat(t.__r,t[e]||[]),delete t.__r}a(t.__c)&&(t.change=[].concat(t.__c,t.change||[]),delete t.__c)}(n),Wt(n,i,zi,qi,Ii,e.context),Ri=void 0}}var Hi,Vi={create:Wi,update:Wi,destroy:function(t){return Wi(t,Li)}};function Gi(t,e){if(!o(t.data.domProps)||!o(e.data.domProps)){var n,i,r=e.elm,s=t.data.domProps||{},l=e.data.domProps||{};for(n in(a(l.__ob__)||c(l._v_attr_proxy))&&(l=e.data.domProps=T({},l)),s)n in l||(r[n]="");for(n in l){if(i=l[n],"textContent"===n||"innerHTML"===n){if(e.children&&(e.children.length=0),i===s[n])continue;1===r.childNodes.length&&r.removeChild(r.childNodes[0])}if("value"===n&&"PROGRESS"!==r.tagName){r._value=i;var p=o(i)?"":String(i);Ji(r,p)&&(r.value=p)}else if("innerHTML"===n&&fi(r.tagName)&&o(r.innerHTML)){(Hi=Hi||document.createElement("div")).innerHTML="".concat(i,"");for(var u=Hi.firstChild;r.firstChild;)r.removeChild(r.firstChild);for(;u.firstChild;)r.appendChild(u.firstChild)}else if(i!==s[n])try{r[n]=i}catch(t){}}}}function Ji(t,e){return!t.composing&&("OPTION"===t.tagName||function(t,e){var n=!0;try{n=document.activeElement!==t}catch(t){}return n&&t.value!==e}(t,e)||function(t,e){var n=t.value,i=t._vModifiers;if(a(i)){if(i.number)return v(n)!==v(e);if(i.trim)return n.trim()!==e.trim()}return n!==e}(t,e))}var Zi={create:Gi,update:Gi},Yi=L((function(t){var e={},n=/:(.+)/;return t.split(/;(?![^(]*\))/g).forEach((function(t){if(t){var i=t.split(n);i.length>1&&(e[i[0].trim()]=i[1].trim())}})),e}));function Xi(t){var e=Qi(t.style);return t.staticStyle?T(t.staticStyle,e):e}function Qi(t){return Array.isArray(t)?$(t):"string"==typeof t?Yi(t):t}var tr,er=/^--/,nr=/\s*!important$/,ir=function(t,e,n){if(er.test(e))t.style.setProperty(e,n);else if(nr.test(n))t.style.setProperty(S(e),n.replace(nr,""),"important");else{var i=or(e);if(Array.isArray(n))for(var r=0,o=n.length;r-1?e.split(sr).forEach((function(e){return t.classList.add(e)})):t.classList.add(e);else{var n=" ".concat(t.getAttribute("class")||""," ");n.indexOf(" "+e+" ")<0&&t.setAttribute("class",(n+e).trim())}}function pr(t,e){if(e&&(e=e.trim()))if(t.classList)e.indexOf(" ")>-1?e.split(sr).forEach((function(e){return t.classList.remove(e)})):t.classList.remove(e),t.classList.length||t.removeAttribute("class");else{for(var n=" ".concat(t.getAttribute("class")||""," "),i=" "+e+" ";n.indexOf(i)>=0;)n=n.replace(i," ");(n=n.trim())?t.setAttribute("class",n):t.removeAttribute("class")}}function ur(t){if(t){if("object"==typeof t){var e={};return!1!==t.css&&T(e,gr(t.name||"v")),T(e,t),e}return"string"==typeof t?gr(t):void 0}}var gr=L((function(t){return{enterClass:"".concat(t,"-enter"),enterToClass:"".concat(t,"-enter-to"),enterActiveClass:"".concat(t,"-enter-active"),leaveClass:"".concat(t,"-leave"),leaveToClass:"".concat(t,"-leave-to"),leaveActiveClass:"".concat(t,"-leave-active")}})),dr=G&&!Y,hr="transition",fr="transitionend",mr="animation",vr="animationend";dr&&(void 0===window.ontransitionend&&void 0!==window.onwebkittransitionend&&(hr="WebkitTransition",fr="webkitTransitionEnd"),void 0===window.onanimationend&&void 0!==window.onwebkitanimationend&&(mr="WebkitAnimation",vr="webkitAnimationEnd"));var yr=G?window.requestAnimationFrame?window.requestAnimationFrame.bind(window):setTimeout:function(t){return t()};function br(t){yr((function(){yr(t)}))}function wr(t,e){var n=t._transitionClasses||(t._transitionClasses=[]);n.indexOf(e)<0&&(n.push(e),lr(t,e))}function kr(t,e){t._transitionClasses&&w(t._transitionClasses,e),pr(t,e)}function _r(t,e,n){var i=Dr(t,e),r=i.type,o=i.timeout,a=i.propCount;if(!r)return n();var c="transition"===r?fr:vr,s=0,l=function(){t.removeEventListener(c,p),n()},p=function(e){e.target===t&&++s>=a&&l()};setTimeout((function(){s0&&(n="transition",p=a,u=o.length):"animation"===e?l>0&&(n="animation",p=l,u=s.length):u=(n=(p=Math.max(a,l))>0?a>l?"transition":"animation":null)?"transition"===n?o.length:s.length:0,{type:n,timeout:p,propCount:u,hasTransform:"transition"===n&&Lr.test(i[hr+"Property"])}}function xr(t,e){for(;t.length1}function Tr(t,e){!0!==e.data.show&&Cr(e)}var $r=function(t){var e,n,i={},l=t.modules,p=t.nodeOps;for(e=0;eh?w(t,o(n[v+1])?null:n[v+1].elm,n,d,v,i):d>v&&_(e,u,h)}(u,f,v,n,l):a(v)?(a(t.text)&&p.setTextContent(u,""),w(u,null,v,0,v.length-1,n)):a(f)?_(f,0,f.length-1):a(t.text)&&p.setTextContent(u,""):t.text!==e.text&&p.setTextContent(u,e.text),a(h)&&a(d=h.hook)&&a(d=d.postpatch)&&d(t,e)}}}function P(t,e,n){if(c(n)&&a(t.parent))t.parent.data.pendingInsert=e;else for(var i=0;i-1,a.selected!==o&&(a.selected=o);else if(j(Br(a),i))return void(t.selectedIndex!==c&&(t.selectedIndex=c));r||(t.selectedIndex=-1)}}function jr(t,e){return e.every((function(e){return!j(e,t)}))}function Br(t){return"_value"in t?t._value:t.value}function Fr(t){t.target.composing=!0}function Rr(t){t.target.composing&&(t.target.composing=!1,Nr(t.target,"input"))}function Nr(t,e){var n=document.createEvent("HTMLEvents");n.initEvent(e,!0,!0),t.dispatchEvent(n)}function Ir(t){return!t.componentInstance||t.data&&t.data.transition?t:Ir(t.componentInstance._vnode)}var Ur={model:Er,show:{bind:function(t,e,n){var i=e.value,r=(n=Ir(n)).data&&n.data.transition,o=t.__vOriginalDisplay="none"===t.style.display?"":t.style.display;i&&r?(n.data.show=!0,Cr(n,(function(){t.style.display=o}))):t.style.display=i?o:"none"},update:function(t,e,n){var i=e.value;!i!=!e.oldValue&&((n=Ir(n)).data&&n.data.transition?(n.data.show=!0,i?Cr(n,(function(){t.style.display=t.__vOriginalDisplay})):Sr(n,(function(){t.style.display="none"}))):t.style.display=i?t.__vOriginalDisplay:"none")},unbind:function(t,e,n,i,r){r||(t.style.display=t.__vOriginalDisplay)}}},zr={name:String,appear:Boolean,css:Boolean,mode:String,type:String,enterClass:String,leaveClass:String,enterToClass:String,leaveToClass:String,enterActiveClass:String,leaveActiveClass:String,appearClass:String,appearActiveClass:String,appearToClass:String,duration:[Number,String,Object]};function qr(t){var e=t&&t.componentOptions;return e&&e.Ctor.options.abstract?qr(Le(e.children)):t}function Wr(t){var e={},n=t.$options;for(var i in n.propsData)e[i]=t[i];var r=n._parentListeners;for(var i in r)e[x(i)]=r[i];return e}function Hr(t,e){if(/\d-keep-alive$/.test(e.tag))return t("keep-alive",{props:e.componentOptions.propsData})}var Vr=function(t){return t.tag||de(t)},Gr=function(t){return"show"===t.name},Jr={name:"transition",props:zr,abstract:!0,render:function(t){var e=this,n=this.$slots.default;if(n&&(n=n.filter(Vr)).length){0;var i=this.mode;0;var r=n[0];if(function(t){for(;t=t.parent;)if(t.data.transition)return!0}(this.$vnode))return r;var o=qr(r);if(!o)return r;if(this._leaving)return Hr(t,r);var a="__transition-".concat(this._uid,"-");o.key=null==o.key?o.isComment?a+"comment":a+o.tag:s(o.key)?0===String(o.key).indexOf(a)?o.key:a+o.key:o.key;var c=(o.data||(o.data={})).transition=Wr(this),l=this._vnode,p=qr(l);if(o.data.directives&&o.data.directives.some(Gr)&&(o.data.show=!0),p&&p.data&&!function(t,e){return e.key===t.key&&e.tag===t.tag}(o,p)&&!de(p)&&(!p.componentInstance||!p.componentInstance._vnode.isComment)){var u=p.data.transition=T({},c);if("out-in"===i)return this._leaving=!0,Ht(u,"afterLeave",(function(){e._leaving=!1,e.$forceUpdate()})),Hr(t,r);if("in-out"===i){if(de(o))return l;var g,d=function(){g()};Ht(c,"afterEnter",d),Ht(c,"enterCancelled",d),Ht(u,"delayLeave",(function(t){g=t}))}}return r}}},Zr=T({tag:String,moveClass:String},zr);function Yr(t){t.elm._moveCb&&t.elm._moveCb(),t.elm._enterCb&&t.elm._enterCb()}function Xr(t){t.data.newPos=t.elm.getBoundingClientRect()}function Qr(t){var e=t.data.pos,n=t.data.newPos,i=e.left-n.left,r=e.top-n.top;if(i||r){t.data.moved=!0;var o=t.elm.style;o.transform=o.WebkitTransform="translate(".concat(i,"px,").concat(r,"px)"),o.transitionDuration="0s"}}delete Zr.mode;var to={Transition:Jr,TransitionGroup:{props:Zr,beforeMount:function(){var t=this,e=this._update;this._update=function(n,i){var r=Ze(t);t.__patch__(t._vnode,t.kept,!1,!0),t._vnode=t.kept,r(),e.call(t,n,i)}},render:function(t){for(var e=this.tag||this.$vnode.data.tag||"span",n=Object.create(null),i=this.prevChildren=this.children,r=this.$slots.default||[],o=this.children=[],a=Wr(this),c=0;c-1?vi[t]=e.constructor===window.HTMLUnknownElement||e.constructor===window.HTMLElement:vi[t]=/HTMLUnknownElement/.test(e.toString())},T(Hn.options.directives,Ur),T(Hn.options.components,to),Hn.prototype.__patch__=G?$r:E,Hn.prototype.$mount=function(t,e){return function(t,e,n){var i;t.$el=e,t.$options.render||(t.$options.render=dt),Qe(t,"beforeMount"),i=function(){t._update(t._render(),n)},new qe(t,i,E,{before:function(){t._isMounted&&!t._isDestroyed&&Qe(t,"beforeUpdate")}},!0),n=!1;var r=t._preWatchers;if(r)for(var o=0;o=0&&(e=t.slice(i),t=t.slice(0,i));var r=t.indexOf("?");return r>=0&&(n=t.slice(r+1),t=t.slice(0,r)),{path:t,query:n,hash:e}}(r.path||""),l=e&&e.path||"/",p=s.path?_o(s.path,l,n||r.append):l,u=function(t,e,n){void 0===e&&(e={});var i,r=n||so;try{i=r(t||"")}catch(t){i={}}for(var o in e){var a=e[o];i[o]=Array.isArray(a)?a.map(co):co(a)}return i}(s.query,r.query,i&&i.options.parseQuery),g=r.hash||s.hash;return g&&"#"!==g.charAt(0)&&(g="#"+g),{_normalized:!0,path:p,query:u,hash:g}}var zo,qo=function(){},Wo={name:"RouterLink",props:{to:{type:[String,Object],required:!0},tag:{type:String,default:"a"},custom:Boolean,exact:Boolean,exactPath:Boolean,append:Boolean,replace:Boolean,activeClass:String,exactActiveClass:String,ariaCurrentValue:{type:String,default:"page"},event:{type:[String,Array],default:"click"}},render:function(t){var e=this,n=this.$router,i=this.$route,r=n.resolve(this.to,i,this.append),o=r.location,a=r.route,c=r.href,s={},l=n.options.linkActiveClass,p=n.options.linkExactActiveClass,u=null==l?"router-link-active":l,g=null==p?"router-link-exact-active":p,d=null==this.activeClass?u:this.activeClass,h=null==this.exactActiveClass?g:this.exactActiveClass,f=a.redirectedFrom?uo(null,Uo(a.redirectedFrom),null,n):a;s[h]=vo(i,f,this.exactPath),s[d]=this.exact||this.exactPath?s[h]:function(t,e){return 0===t.path.replace(po,"/").indexOf(e.path.replace(po,"/"))&&(!e.hash||t.hash===e.hash)&&function(t,e){for(var n in e)if(!(n in t))return!1;return!0}(t.query,e.query)}(i,f);var m=s[h]?this.ariaCurrentValue:null,v=function(t){Ho(t)&&(e.replace?n.replace(o,qo):n.push(o,qo))},y={click:Ho};Array.isArray(this.event)?this.event.forEach((function(t){y[t]=v})):y[this.event]=v;var b={class:s},w=!this.$scopedSlots.$hasNormal&&this.$scopedSlots.default&&this.$scopedSlots.default({href:c,route:a,navigate:v,isActive:s[d],isExactActive:s[h]});if(w){if(1===w.length)return w[0];if(w.length>1||!w.length)return 0===w.length?t():t("span",{},w)}if("a"===this.tag)b.on=y,b.attrs={href:c,"aria-current":m};else{var k=function t(e){var n;if(e)for(var i=0;i-1&&(c.params[g]=n.params[g]);return c.path=Io(p.path,c.params),s(p,c,a)}if(c.path){c.params={};for(var d=0;d-1}function La(t,e){return _a(t)&&t._isRouter&&(null==e||t.type===e)}function Da(t,e,n){var i=function(r){r>=t.length?n():t[r]?e(t[r],(function(){i(r+1)})):i(r+1)};i(0)}function xa(t){return function(e,n,i){var r=!1,o=0,a=null;Pa(t,(function(t,e,n,c){if("function"==typeof t&&void 0===t.cid){r=!0,o++;var s,l=Ka((function(e){var r;((r=e).__esModule||Sa&&"Module"===r[Symbol.toStringTag])&&(e=e.default),t.resolved="function"==typeof e?e:zo.extend(e),n.components[c]=e,--o<=0&&i()})),p=Ka((function(t){var e="Failed to resolve async component "+c+": "+t;a||(a=_a(t)?t:new Error(e),i(a))}));try{s=t(l,p)}catch(t){p(t)}if(s)if("function"==typeof s.then)s.then(l,p);else{var u=s.component;u&&"function"==typeof u.then&&u.then(l,p)}}})),r||i()}}function Pa(t,e){return Ca(t.map((function(t){return Object.keys(t.components).map((function(n){return e(t.components[n],t.instances[n],t,n)}))})))}function Ca(t){return Array.prototype.concat.apply([],t)}var Sa="function"==typeof Symbol&&"symbol"==typeof Symbol.toStringTag;function Ka(t){var e=!1;return function(){for(var n=[],i=arguments.length;i--;)n[i]=arguments[i];if(!e)return e=!0,t.apply(this,n)}}var Oa=function(t,e){this.router=t,this.base=function(t){if(!t)if(Vo){var e=document.querySelector("base");t=(t=e&&e.getAttribute("href")||"/").replace(/^https?:\/\/[^\/]+/,"")}else t="/";"/"!==t.charAt(0)&&(t="/"+t);return t.replace(/\/$/,"")}(e),this.current=ho,this.pending=null,this.ready=!1,this.readyCbs=[],this.readyErrorCbs=[],this.errorCbs=[],this.listeners=[]};function Ta(t,e,n,i){var r=Pa(t,(function(t,i,r,o){var a=function(t,e){"function"!=typeof t&&(t=zo.extend(t));return t.options[e]}(t,e);if(a)return Array.isArray(a)?a.map((function(t){return n(t,i,r,o)})):n(a,i,r,o)}));return Ca(i?r.reverse():r)}function $a(t,e){if(e)return function(){return t.apply(e,arguments)}}Oa.prototype.listen=function(t){this.cb=t},Oa.prototype.onReady=function(t,e){this.ready?t():(this.readyCbs.push(t),e&&this.readyErrorCbs.push(e))},Oa.prototype.onError=function(t){this.errorCbs.push(t)},Oa.prototype.transitionTo=function(t,e,n){var i,r=this;try{i=this.router.match(t,this.current)}catch(t){throw this.errorCbs.forEach((function(e){e(t)})),t}var o=this.current;this.confirmTransition(i,(function(){r.updateRoute(i),e&&e(i),r.ensureURL(),r.router.afterHooks.forEach((function(t){t&&t(i,o)})),r.ready||(r.ready=!0,r.readyCbs.forEach((function(t){t(i)})))}),(function(t){n&&n(t),t&&!r.ready&&(La(t,va.redirected)&&o===ho||(r.ready=!0,r.readyErrorCbs.forEach((function(e){e(t)}))))}))},Oa.prototype.confirmTransition=function(t,e,n){var i=this,r=this.current;this.pending=t;var o,a,c=function(t){!La(t)&&_a(t)&&(i.errorCbs.length?i.errorCbs.forEach((function(e){e(t)})):console.error(t)),n&&n(t)},s=t.matched.length-1,l=r.matched.length-1;if(vo(t,r)&&s===l&&t.matched[s]===r.matched[l])return this.ensureURL(),t.hash&&oa(this.router,r,t,!1),c(((a=wa(o=r,t,va.duplicated,'Avoided redundant navigation to current location: "'+o.fullPath+'".')).name="NavigationDuplicated",a));var p=function(t,e){var n,i=Math.max(t.length,e.length);for(n=0;n0)){var e=this.router,n=e.options.scrollBehavior,i=ha&&n;i&&this.listeners.push(ra());var r=function(){var n=t.current,r=Ma(t.base);t.current===ho&&r===t._startLocation||t.transitionTo(r,(function(t){i&&oa(e,t,n,!0)}))};window.addEventListener("popstate",r),this.listeners.push((function(){window.removeEventListener("popstate",r)}))}},e.prototype.go=function(t){window.history.go(t)},e.prototype.push=function(t,e,n){var i=this,r=this.current;this.transitionTo(t,(function(t){fa(Lo(i.base+t.fullPath)),oa(i.router,t,r,!1),e&&e(t)}),n)},e.prototype.replace=function(t,e,n){var i=this,r=this.current;this.transitionTo(t,(function(t){ma(Lo(i.base+t.fullPath)),oa(i.router,t,r,!1),e&&e(t)}),n)},e.prototype.ensureURL=function(t){if(Ma(this.base)!==this.current.fullPath){var e=Lo(this.base+this.current.fullPath);t?fa(e):ma(e)}},e.prototype.getCurrentLocation=function(){return Ma(this.base)},e}(Oa);function Ma(t){var e=window.location.pathname,n=e.toLowerCase(),i=t.toLowerCase();return!t||n!==i&&0!==n.indexOf(Lo(i+"/"))||(e=e.slice(t.length)),(e||"/")+window.location.search+window.location.hash}var Aa=function(t){function e(e,n,i){t.call(this,e,n),i&&function(t){var e=Ma(t);if(!/^\/#/.test(e))return window.location.replace(Lo(t+"/#"+e)),!0}(this.base)||ja()}return t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e,e.prototype.setupListeners=function(){var t=this;if(!(this.listeners.length>0)){var e=this.router.options.scrollBehavior,n=ha&&e;n&&this.listeners.push(ra());var i=function(){var e=t.current;ja()&&t.transitionTo(Ba(),(function(i){n&&oa(t.router,i,e,!0),ha||Na(i.fullPath)}))},r=ha?"popstate":"hashchange";window.addEventListener(r,i),this.listeners.push((function(){window.removeEventListener(r,i)}))}},e.prototype.push=function(t,e,n){var i=this,r=this.current;this.transitionTo(t,(function(t){Ra(t.fullPath),oa(i.router,t,r,!1),e&&e(t)}),n)},e.prototype.replace=function(t,e,n){var i=this,r=this.current;this.transitionTo(t,(function(t){Na(t.fullPath),oa(i.router,t,r,!1),e&&e(t)}),n)},e.prototype.go=function(t){window.history.go(t)},e.prototype.ensureURL=function(t){var e=this.current.fullPath;Ba()!==e&&(t?Ra(e):Na(e))},e.prototype.getCurrentLocation=function(){return Ba()},e}(Oa);function ja(){var t=Ba();return"/"===t.charAt(0)||(Na("/"+t),!1)}function Ba(){var t=window.location.href,e=t.indexOf("#");return e<0?"":t=t.slice(e+1)}function Fa(t){var e=window.location.href,n=e.indexOf("#");return(n>=0?e.slice(0,n):e)+"#"+t}function Ra(t){ha?fa(Fa(t)):window.location.hash=t}function Na(t){ha?ma(Fa(t)):window.location.replace(Fa(t))}var Ia=function(t){function e(e,n){t.call(this,e,n),this.stack=[],this.index=-1}return t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e,e.prototype.push=function(t,e,n){var i=this;this.transitionTo(t,(function(t){i.stack=i.stack.slice(0,i.index+1).concat(t),i.index++,e&&e(t)}),n)},e.prototype.replace=function(t,e,n){var i=this;this.transitionTo(t,(function(t){i.stack=i.stack.slice(0,i.index).concat(t),e&&e(t)}),n)},e.prototype.go=function(t){var e=this,n=this.index+t;if(!(n<0||n>=this.stack.length)){var i=this.stack[n];this.confirmTransition(i,(function(){var t=e.current;e.index=n,e.updateRoute(i),e.router.afterHooks.forEach((function(e){e&&e(i,t)}))}),(function(t){La(t,va.duplicated)&&(e.index=n)}))}},e.prototype.getCurrentLocation=function(){var t=this.stack[this.stack.length-1];return t?t.fullPath:"/"},e.prototype.ensureURL=function(){},e}(Oa),Ua=function(t){void 0===t&&(t={}),this.app=null,this.apps=[],this.options=t,this.beforeHooks=[],this.resolveHooks=[],this.afterHooks=[],this.matcher=Zo(t.routes||[],this);var e=t.mode||"hash";switch(this.fallback="history"===e&&!ha&&!1!==t.fallback,this.fallback&&(e="hash"),Vo||(e="abstract"),this.mode=e,e){case"history":this.history=new Ea(this,t.base);break;case"hash":this.history=new Aa(this,t.base,this.fallback);break;case"abstract":this.history=new Ia(this,t.base);break;default:0}},za={currentRoute:{configurable:!0}};Ua.prototype.match=function(t,e,n){return this.matcher.match(t,e,n)},za.currentRoute.get=function(){return this.history&&this.history.current},Ua.prototype.init=function(t){var e=this;if(this.apps.push(t),t.$once("hook:destroyed",(function(){var n=e.apps.indexOf(t);n>-1&&e.apps.splice(n,1),e.app===t&&(e.app=e.apps[0]||null),e.app||e.history.teardown()})),!this.app){this.app=t;var n=this.history;if(n instanceof Ea||n instanceof Aa){var i=function(t){n.setupListeners(),function(t){var i=n.current,r=e.options.scrollBehavior;ha&&r&&"fullPath"in t&&oa(e,t,i,!1)}(t)};n.transitionTo(n.getCurrentLocation(),i,i)}n.listen((function(t){e.apps.forEach((function(e){e._route=t}))}))}},Ua.prototype.beforeEach=function(t){return Wa(this.beforeHooks,t)},Ua.prototype.beforeResolve=function(t){return Wa(this.resolveHooks,t)},Ua.prototype.afterEach=function(t){return Wa(this.afterHooks,t)},Ua.prototype.onReady=function(t,e){this.history.onReady(t,e)},Ua.prototype.onError=function(t){this.history.onError(t)},Ua.prototype.push=function(t,e,n){var i=this;if(!e&&!n&&"undefined"!=typeof Promise)return new Promise((function(e,n){i.history.push(t,e,n)}));this.history.push(t,e,n)},Ua.prototype.replace=function(t,e,n){var i=this;if(!e&&!n&&"undefined"!=typeof Promise)return new Promise((function(e,n){i.history.replace(t,e,n)}));this.history.replace(t,e,n)},Ua.prototype.go=function(t){this.history.go(t)},Ua.prototype.back=function(){this.go(-1)},Ua.prototype.forward=function(){this.go(1)},Ua.prototype.getMatchedComponents=function(t){var e=t?t.matched?t:this.resolve(t).route:this.currentRoute;return e?[].concat.apply([],e.matched.map((function(t){return Object.keys(t.components).map((function(e){return t.components[e]}))}))):[]},Ua.prototype.resolve=function(t,e,n){var i=Uo(t,e=e||this.history.current,n,this),r=this.match(i,e),o=r.redirectedFrom||r.fullPath;return{location:i,route:r,href:function(t,e,n){var i="hash"===n?"#"+e:e;return t?Lo(t+"/"+i):i}(this.history.base,o,this.mode),normalizedTo:i,resolved:r}},Ua.prototype.getRoutes=function(){return this.matcher.getRoutes()},Ua.prototype.addRoute=function(t,e){this.matcher.addRoute(t,e),this.history.current!==ho&&this.history.transitionTo(this.history.getCurrentLocation())},Ua.prototype.addRoutes=function(t){this.matcher.addRoutes(t),this.history.current!==ho&&this.history.transitionTo(this.history.getCurrentLocation())},Object.defineProperties(Ua.prototype,za);var qa=Ua;function Wa(t,e){return t.push(e),function(){var n=t.indexOf(e);n>-1&&t.splice(n,1)}}Ua.install=function t(e){if(!t.installed||zo!==e){t.installed=!0,zo=e;var n=function(t){return void 0!==t},i=function(t,e){var i=t.$options._parentVnode;n(i)&&n(i=i.data)&&n(i=i.registerRouteInstance)&&i(t,e)};e.mixin({beforeCreate:function(){n(this.$options.router)?(this._routerRoot=this,this._router=this.$options.router,this._router.init(this),e.util.defineReactive(this,"_route",this._router.history.current)):this._routerRoot=this.$parent&&this.$parent._routerRoot||this,i(this,this)},destroyed:function(){i(this)}}),Object.defineProperty(e.prototype,"$router",{get:function(){return this._routerRoot._router}}),Object.defineProperty(e.prototype,"$route",{get:function(){return this._routerRoot._route}}),e.component("RouterView",wo),e.component("RouterLink",Wo);var r=e.config.optionMergeStrategies;r.beforeRouteEnter=r.beforeRouteLeave=r.beforeRouteUpdate=r.created}},Ua.version="3.6.5",Ua.isNavigationFailure=La,Ua.NavigationFailureType=va,Ua.START_LOCATION=ho,Vo&&window.Vue&&window.Vue.use(Ua);n(53);n(46),n(109);var Ha={NotFound:()=>Promise.all([n.e(0),n.e(1),n.e(27)]).then(n.bind(null,377)),Layout:()=>Promise.all([n.e(0),n.e(1),n.e(10)]).then(n.bind(null,376)),DirectoryPagination:()=>Promise.all([n.e(0),n.e(1),n.e(5)]).then(n.bind(null,378)),FrontmatterKey:()=>Promise.all([n.e(0),n.e(1),n.e(18)]).then(n.bind(null,379)),FrontmatterPagination:()=>Promise.all([n.e(0),n.e(1),n.e(6)]).then(n.bind(null,380)),IndexPost:()=>Promise.all([n.e(0),n.e(1),n.e(8)]).then(n.bind(null,281)),Post:()=>Promise.all([n.e(0),n.e(1),n.e(9)]).then(n.bind(null,381))},Va={"v-109b7b6a":()=>n.e(29).then(n.bind(null,385)),"v-0f4e007e":()=>n.e(30).then(n.bind(null,386)),"v-2578306f":()=>n.e(31).then(n.bind(null,387)),"v-6018492a":()=>n.e(12).then(n.bind(null,388)),"v-59a63080":()=>n.e(19).then(n.bind(null,389)),"v-e02a8a76":()=>n.e(20).then(n.bind(null,390)),"v-eebe6fe6":()=>n.e(32).then(n.bind(null,391)),"v-7b0f0961":()=>n.e(21).then(n.bind(null,392)),"v-61c088e6":()=>n.e(33).then(n.bind(null,393)),"v-177ef1fe":()=>n.e(17).then(n.bind(null,394)),"v-7b672071":()=>n.e(13).then(n.bind(null,395)),"v-394e384e":()=>n.e(22).then(n.bind(null,396)),"v-67ea603f":()=>n.e(34).then(n.bind(null,397)),"v-4ffe1afe":()=>n.e(23).then(n.bind(null,398)),"v-4c78f51d":()=>n.e(35).then(n.bind(null,399)),"v-3843152b":()=>n.e(36).then(n.bind(null,400)),"v-e5335502":()=>n.e(37).then(n.bind(null,401)),"v-3dc27382":()=>n.e(38).then(n.bind(null,402)),"v-3efb3c3e":()=>n.e(40).then(n.bind(null,403)),"v-7da54c6f":()=>n.e(39).then(n.bind(null,404)),"v-2f9b6cb6":()=>n.e(24).then(n.bind(null,405)),"v-66b18f61":()=>n.e(41).then(n.bind(null,406)),"v-6b753255":()=>n.e(42).then(n.bind(null,407)),"v-0c8784ee":()=>n.e(43).then(n.bind(null,408)),"v-2e33a981":()=>n.e(44).then(n.bind(null,409)),"v-4215c085":()=>n.e(45).then(n.bind(null,410)),"v-208c95fe":()=>n.e(46).then(n.bind(null,411)),"v-4e009901":()=>n.e(47).then(n.bind(null,412)),"v-f958b67a":()=>n.e(48).then(n.bind(null,413)),"v-44e9497e":()=>n.e(49).then(n.bind(null,414)),"v-3cfeb3fe":()=>n.e(51).then(n.bind(null,415)),"v-f0ae247e":()=>n.e(52).then(n.bind(null,416)),"v-1f59967e":()=>n.e(50).then(n.bind(null,417)),"v-1df9ba79":()=>n.e(7).then(n.bind(null,418)),"v-acaf8bbe":()=>n.e(53).then(n.bind(null,419)),"v-5e36ef8a":()=>n.e(54).then(n.bind(null,420)),"v-197bd04c":()=>n.e(11).then(n.bind(null,421)),"v-d599223e":()=>n.e(25).then(n.bind(null,422)),"v-7495ad8d":()=>n.e(55).then(n.bind(null,423)),"v-2615480c":()=>n.e(56).then(n.bind(null,424)),"v-2c8ce301":()=>n.e(57).then(n.bind(null,425)),"v-6f688c61":()=>n.e(58).then(n.bind(null,426)),"v-9b98f9ca":()=>n.e(26).then(n.bind(null,427)),"v-73ba0ae1":()=>n.e(59).then(n.bind(null,428)),"v-0a5ecb01":()=>n.e(60).then(n.bind(null,429)),"v-8b8ac0be":()=>n.e(61).then(n.bind(null,430)),"v-2e6cd4fd":()=>n.e(62).then(n.bind(null,431)),"v-c4171d36":()=>n.e(63).then(n.bind(null,432)),"v-21d81ac1":()=>n.e(65).then(n.bind(null,433)),"v-50f91cc7":()=>n.e(64).then(n.bind(null,434)),"v-102e5c3e":()=>n.e(66).then(n.bind(null,435)),"v-1d645dc1":()=>n.e(67).then(n.bind(null,436))};function Ga(t){const e=Object.create(null);return function(n){return e[n]||(e[n]=t(n))}}const Ja=/-(\w)/g,Za=Ga(t=>t.replace(Ja,(t,e)=>e?e.toUpperCase():"")),Ya=/\B([A-Z])/g,Xa=Ga(t=>t.replace(Ya,"-$1").toLowerCase()),Qa=Ga(t=>t.charAt(0).toUpperCase()+t.slice(1));function tc(t,e){if(!e)return;if(t(e))return t(e);return e.includes("-")?t(Qa(Za(e))):t(Qa(e))||t(Xa(e))}const ec=Object.assign({},Ha,Va),nc=t=>ec[t],ic=t=>Va[t],rc=t=>Ha[t],oc=t=>Hn.component(t);function ac(t){return tc(ic,t)}function cc(t){return tc(rc,t)}function sc(t){return tc(nc,t)}function lc(t){return tc(oc,t)}function pc(...t){return Promise.all(t.filter(t=>t).map(async t=>{if(!lc(t)&&sc(t)){const e=await sc(t)();Hn.component(t,e.default)}}))}function uc(t,e){"undefined"!=typeof window&&window.__VUEPRESS__&&(window.__VUEPRESS__[t]=e)}var gc=n(92),dc=n.n(gc),hc=n(93),fc=n.n(hc),mc={created(){if(this.siteMeta=this.$site.headTags.filter(([t])=>"meta"===t).map(([t,e])=>e),this.$ssrContext){const e=this.getMergedMetaTags();this.$ssrContext.title=this.$title,this.$ssrContext.lang=this.$lang,this.$ssrContext.pageMeta=(t=e)?t.map(t=>{let e="{e+=` ${n}="${fc()(t[n])}"`}),e+">"}).join("\n "):"",this.$ssrContext.canonicalLink=yc(this.$canonicalUrl)}var t},mounted(){this.currentMetaTags=[...document.querySelectorAll("meta")],this.updateMeta(),this.updateCanonicalLink()},methods:{updateMeta(){document.title=this.$title,document.documentElement.lang=this.$lang;const t=this.getMergedMetaTags();this.currentMetaTags=bc(t,this.currentMetaTags)},getMergedMetaTags(){const t=this.$page.frontmatter.meta||[];return dc()([{name:"description",content:this.$description}],t,this.siteMeta,wc)},updateCanonicalLink(){vc(),this.$canonicalUrl&&document.head.insertAdjacentHTML("beforeend",yc(this.$canonicalUrl))}},watch:{$page(){this.updateMeta(),this.updateCanonicalLink()}},beforeDestroy(){bc(null,this.currentMetaTags),vc()}};function vc(){const t=document.querySelector("link[rel='canonical']");t&&t.remove()}function yc(t=""){return t?``:""}function bc(t,e){if(e&&[...e].filter(t=>t.parentNode===document.head).forEach(t=>document.head.removeChild(t)),t)return t.map(t=>{const e=document.createElement("meta");return Object.keys(t).forEach(n=>{e.setAttribute(n,t[n])}),document.head.appendChild(e),e})}function wc(t){for(const e of["name","property","itemprop"])if(t.hasOwnProperty(e))return t[e]+e;return JSON.stringify(t)}var kc=n(94),_c={mounted(){window.addEventListener("scroll",this.onScroll)},methods:{onScroll:n.n(kc)()((function(){this.setActiveHash()}),300),setActiveHash(){const t=[].slice.call(document.querySelectorAll(".sidebar-link")),e=[].slice.call(document.querySelectorAll(".header-anchor")).filter(e=>t.some(t=>t.hash===e.hash)),n=Math.max(window.pageYOffset,document.documentElement.scrollTop,document.body.scrollTop),i=Math.max(document.documentElement.scrollHeight,document.body.scrollHeight),r=window.innerHeight+n;for(let t=0;t=o.parentElement.offsetTop+10&&(!a||n{this.$nextTick(()=>{this.$vuepress.$set("disableScrollBehavior",!1)})})}}}},beforeDestroy(){window.removeEventListener("scroll",this.onScroll)}},Lc=n(22),Dc=n.n(Lc),xc={mounted(){Dc.a.configure({showSpinner:!1}),this.$router.beforeEach((t,e,n)=>{t.path===e.path||Hn.component(t.name)||Dc.a.start(),n()}),this.$router.afterEach(()=>{Dc.a.done(),this.isSidebarOpen=!1})}},Pc={props:{parent:Object,code:String,options:{align:String,color:String,backgroundTransition:Boolean,backgroundColor:String,successText:String,staticIcon:Boolean}},data:()=>({success:!1,originalBackground:null,originalTransition:null}),computed:{alignStyle(){let t={};return t[this.options.align]="7.5px",t},iconClass(){return this.options.staticIcon?"":"hover"}},mounted(){this.originalTransition=this.parent.style.transition,this.originalBackground=this.parent.style.background},beforeDestroy(){this.parent.style.transition=this.originalTransition,this.parent.style.background=this.originalBackground},methods:{hexToRgb(t){let e=/^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(t);return e?{r:parseInt(e[1],16),g:parseInt(e[2],16),b:parseInt(e[3],16)}:null},copyToClipboard(t){if(navigator.clipboard)navigator.clipboard.writeText(this.code).then(()=>{this.setSuccessTransitions()},()=>{});else{let t=document.createElement("textarea");document.body.appendChild(t),t.value=this.code,t.select(),document.execCommand("Copy"),t.remove(),this.setSuccessTransitions()}},setSuccessTransitions(){if(clearTimeout(this.successTimeout),this.options.backgroundTransition){this.parent.style.transition="background 350ms";let t=this.hexToRgb(this.options.backgroundColor);this.parent.style.background=`rgba(${t.r}, ${t.g}, ${t.b}, 0.1)`}this.success=!0,this.successTimeout=setTimeout(()=>{this.options.backgroundTransition&&(this.parent.style.background=this.originalBackground,this.parent.style.transition=this.originalTransition),this.success=!1},500)}}},Cc=(n(240),n(7)),Sc=Object(Cc.a)(Pc,(function(){var t=this,e=t._self._c;return e("div",{staticClass:"code-copy"},[e("svg",{class:t.iconClass,style:t.alignStyle,attrs:{xmlns:"http://www.w3.org/2000/svg",width:"24",height:"24",viewBox:"0 0 24 24"},on:{click:t.copyToClipboard}},[e("path",{attrs:{fill:"none",d:"M0 0h24v24H0z"}}),t._v(" "),e("path",{attrs:{fill:t.options.color,d:"M16 1H4c-1.1 0-2 .9-2 2v14h2V3h12V1zm-1 4l6 6v10c0 1.1-.9 2-2 2H7.99C6.89 23 6 22.1 6 21l.01-14c0-1.1.89-2 1.99-2h7zm-1 7h5.5L14 6.5V12z"}})]),t._v(" "),e("span",{class:t.success?"success":"",style:t.alignStyle},[t._v("\n "+t._s(t.options.successText)+"\n ")])])}),[],!1,null,"49140617",null).exports,Kc=(n(241),[mc,_c,xc,{updated(){this.update()},methods:{update(){setTimeout(()=>{document.querySelectorAll('div[class*="language-"] pre').forEach(t=>{if(t.classList.contains("code-copy-added"))return;let e=new(Hn.extend(Sc));e.options={align:"bottom",color:"#8F979E",backgroundTransition:!1,backgroundColor:"#0075b8",successText:"Copied!",staticIcon:!0},e.code=t.innerText,e.parent=t,e.$mount(),t.classList.add("code-copy-added"),t.appendChild(e.$el)})},100)}}}]),Oc={name:"GlobalLayout",computed:{layout(){const t=this.getLayout();return uc("layout",t),Hn.component(t)}},methods:{getLayout(){if(this.$page.path){const t=this.$page.frontmatter.layout;return t&&(this.$vuepress.getLayoutAsyncComponent(t)||this.$vuepress.getVueComponent(t))?t:"Layout"}return"NotFound"}}},Tc=Object(Cc.a)(Oc,(function(){return(0,this._self._c)(this.layout,{tag:"component"})}),[],!1,null,null,null).exports;!function(t,e,n){switch(e){case"components":t[e]||(t[e]={}),Object.assign(t[e],n);break;case"mixins":t[e]||(t[e]=[]),t[e].push(...n);break;default:throw new Error("Unknown option name.")}}(Tc,"mixins",Kc);const $c=[{name:"v-109b7b6a",path:"/blog/anchor-outputs-channels-are-here/",component:Tc,beforeEnter:(t,e,n)=>{pc("Post","v-109b7b6a").then(n)}},{path:"/blog/anchor-outputs-channels-are-here/index.html",redirect:"/blog/anchor-outputs-channels-are-here/"},{path:"/_blog/anchor-outputs-channels-are-here.html",redirect:"/blog/anchor-outputs-channels-are-here/"},{name:"v-0f4e007e",path:"/blog/announcing-ldk-node/",component:Tc,beforeEnter:(t,e,n)=>{pc("Post","v-0f4e007e").then(n)}},{path:"/blog/announcing-ldk-node/index.html",redirect:"/blog/announcing-ldk-node/"},{path:"/_blog/announcing-ldk-node.html",redirect:"/blog/announcing-ldk-node/"},{name:"v-2578306f",path:"/blog/announcing-rapid-gossip-sync/",component:Tc,beforeEnter:(t,e,n)=>{pc("Post","v-2578306f").then(n)}},{path:"/blog/announcing-rapid-gossip-sync/index.html",redirect:"/blog/announcing-rapid-gossip-sync/"},{path:"/_blog/announcing-rapid-gossip-sync.html",redirect:"/blog/announcing-rapid-gossip-sync/"},{name:"v-6018492a",path:"/blog/bolt12-has-arrived/",component:Tc,beforeEnter:(t,e,n)=>{pc("Post","v-6018492a").then(n)}},{path:"/blog/bolt12-has-arrived/index.html",redirect:"/blog/bolt12-has-arrived/"},{path:"/_blog/bolt12-has-arrived.html",redirect:"/blog/bolt12-has-arrived/"},{name:"v-59a63080",path:"/blog/bitkit-uses-ldk-to-build-the-ultimate-alternative-to-custodial-wallets/",component:Tc,beforeEnter:(t,e,n)=>{pc("Post","v-59a63080").then(n)}},{path:"/blog/bitkit-uses-ldk-to-build-the-ultimate-alternative-to-custodial-wallets/index.html",redirect:"/blog/bitkit-uses-ldk-to-build-the-ultimate-alternative-to-custodial-wallets/"},{path:"/_blog/bitkit-uses-ldk-to-build-the-ultimate-alternative-to-custodial wallets.html",redirect:"/blog/bitkit-uses-ldk-to-build-the-ultimate-alternative-to-custodial-wallets/"},{name:"v-e02a8a76",path:"/blog/cashapp-enables-lightning-withdrawals-and-deposits-using-ldk/",component:Tc,beforeEnter:(t,e,n)=>{pc("Post","v-e02a8a76").then(n)}},{path:"/blog/cashapp-enables-lightning-withdrawals-and-deposits-using-ldk/index.html",redirect:"/blog/cashapp-enables-lightning-withdrawals-and-deposits-using-ldk/"},{path:"/_blog/cashapp-enables-lightning-withdrawals-and-deposits-using-ldk.html",redirect:"/blog/cashapp-enables-lightning-withdrawals-and-deposits-using-ldk/"},{name:"v-eebe6fe6",path:"/blog/ldk-an-sdk-for-the-lightning-network/",component:Tc,beforeEnter:(t,e,n)=>{pc("Post","v-eebe6fe6").then(n)}},{path:"/blog/ldk-an-sdk-for-the-lightning-network/index.html",redirect:"/blog/ldk-an-sdk-for-the-lightning-network/"},{path:"/_blog/ldk-an-sdk-for-the-lightning-network.html",redirect:"/blog/ldk-an-sdk-for-the-lightning-network/"},{name:"v-7b0f0961",path:"/blog/ldk-roadmap/",component:Tc,beforeEnter:(t,e,n)=>{pc("Post","v-7b0f0961").then(n)}},{path:"/blog/ldk-roadmap/index.html",redirect:"/blog/ldk-roadmap/"},{path:"/_blog/ldk-roadmap.html",redirect:"/blog/ldk-roadmap/"},{name:"v-61c088e6",path:"/blog/mutiny-uses-ldk-the-first-lightning-wallet-for-the-web/",component:Tc,beforeEnter:(t,e,n)=>{pc("Post","v-61c088e6").then(n)}},{path:"/blog/mutiny-uses-ldk-the-first-lightning-wallet-for-the-web/index.html",redirect:"/blog/mutiny-uses-ldk-the-first-lightning-wallet-for-the-web/"},{path:"/_blog/mutiny-uses-ldk-the-first-lightning-wallet-for-the-web.html",redirect:"/blog/mutiny-uses-ldk-the-first-lightning-wallet-for-the-web/"},{name:"v-177ef1fe",path:"/blog/introducing-phantom-node-payments/",component:Tc,beforeEnter:(t,e,n)=>{pc("Post","v-177ef1fe").then(n)}},{path:"/blog/introducing-phantom-node-payments/index.html",redirect:"/blog/introducing-phantom-node-payments/"},{path:"/_blog/introducing-phantom-node-payments.html",redirect:"/blog/introducing-phantom-node-payments/"},{name:"v-7b672071",path:"/blog/onion-messages-demystified/",component:Tc,beforeEnter:(t,e,n)=>{pc("Post","v-7b672071").then(n)}},{path:"/blog/onion-messages-demystified/index.html",redirect:"/blog/onion-messages-demystified/"},{path:"/_blog/onion-messages-demystified.html",redirect:"/blog/onion-messages-demystified/"},{name:"v-394e384e",path:"/blog/sensei-uses-ldk-to-build-a-multi-node-lightning-server-application/",component:Tc,beforeEnter:(t,e,n)=>{pc("Post","v-394e384e").then(n)}},{path:"/blog/sensei-uses-ldk-to-build-a-multi-node-lightning-server-application/index.html",redirect:"/blog/sensei-uses-ldk-to-build-a-multi-node-lightning-server-application/"},{path:"/_blog/sensei-uses-ldk-to-build-a-multi-node-lightning-server-application.html",redirect:"/blog/sensei-uses-ldk-to-build-a-multi-node-lightning-server-application/"},{name:"v-67ea603f",path:"/blog/the-challenges-of-developing-non-custodial-lightning-on-mobile/",component:Tc,beforeEnter:(t,e,n)=>{pc("Post","v-67ea603f").then(n)}},{path:"/blog/the-challenges-of-developing-non-custodial-lightning-on-mobile/index.html",redirect:"/blog/the-challenges-of-developing-non-custodial-lightning-on-mobile/"},{path:"/_blog/the-challenges-of-developing-non-custodial-lightning-on-mobile.html",redirect:"/blog/the-challenges-of-developing-non-custodial-lightning-on-mobile/"},{name:"v-4ffe1afe",path:"/blog/teos-uses-ldk-to-build-open-source-watchtower/",component:Tc,beforeEnter:(t,e,n)=>{pc("Post","v-4ffe1afe").then(n)}},{path:"/blog/teos-uses-ldk-to-build-open-source-watchtower/index.html",redirect:"/blog/teos-uses-ldk-to-build-open-source-watchtower/"},{path:"/_blog/teos-uses-ldk-to-build-open-source-watchtower.html",redirect:"/blog/teos-uses-ldk-to-build-open-source-watchtower/"},{name:"v-4c78f51d",path:"/blog/unleashing-liquidity-on-the-lightning-network-with-lightning-liquidity/",component:Tc,beforeEnter:(t,e,n)=>{pc("Post","v-4c78f51d").then(n)}},{path:"/blog/unleashing-liquidity-on-the-lightning-network-with-lightning-liquidity/index.html",redirect:"/blog/unleashing-liquidity-on-the-lightning-network-with-lightning-liquidity/"},{path:"/_blog/unleashing-liquidity-on-the-lightning-network-with-lightning-liquidity.html",redirect:"/blog/unleashing-liquidity-on-the-lightning-network-with-lightning-liquidity/"},{name:"v-3843152b",path:"/blog/zero-confirmation-channels/",component:Tc,beforeEnter:(t,e,n)=>{pc("Post","v-3843152b").then(n)}},{path:"/blog/zero-confirmation-channels/index.html",redirect:"/blog/zero-confirmation-channels/"},{path:"/_blog/zero-confirmation-channels.html",redirect:"/blog/zero-confirmation-channels/"},{name:"v-e5335502",path:"/blockchain_data/block_source/",component:Tc,beforeEnter:(t,e,n)=>{pc("Layout","v-e5335502").then(n)}},{path:"/blockchain_data/block_source/index.html",redirect:"/blockchain_data/block_source/"},{path:"/blockchain_data/block_source.html",redirect:"/blockchain_data/block_source/"},{name:"v-3dc27382",path:"/blockchain_data/chain_activity/",component:Tc,beforeEnter:(t,e,n)=>{pc("Layout","v-3dc27382").then(n)}},{path:"/blockchain_data/chain_activity/index.html",redirect:"/blockchain_data/chain_activity/"},{path:"/blockchain_data/chain_activity.html",redirect:"/blockchain_data/chain_activity/"},{name:"v-3efb3c3e",path:"/blockchain_data/full_blocks/",component:Tc,beforeEnter:(t,e,n)=>{pc("Layout","v-3efb3c3e").then(n)}},{path:"/blockchain_data/full_blocks/index.html",redirect:"/blockchain_data/full_blocks/"},{path:"/blockchain_data/full_blocks.html",redirect:"/blockchain_data/full_blocks/"},{name:"v-7da54c6f",path:"/blockchain_data/confirmed_transactions/",component:Tc,beforeEnter:(t,e,n)=>{pc("Layout","v-7da54c6f").then(n)}},{path:"/blockchain_data/confirmed_transactions/index.html",redirect:"/blockchain_data/confirmed_transactions/"},{path:"/blockchain_data/confirmed_transactions.html",redirect:"/blockchain_data/confirmed_transactions/"},{name:"v-2f9b6cb6",path:"/blockchain_data/introduction/",component:Tc,beforeEnter:(t,e,n)=>{pc("Layout","v-2f9b6cb6").then(n)}},{path:"/blockchain_data/introduction/index.html",redirect:"/blockchain_data/introduction/"},{path:"/blockchain_data/introduction.html",redirect:"/blockchain_data/introduction/"},{name:"v-66b18f61",path:"/blockchain_data/pre_filtered_blocks/",component:Tc,beforeEnter:(t,e,n)=>{pc("Layout","v-66b18f61").then(n)}},{path:"/blockchain_data/pre_filtered_blocks/index.html",redirect:"/blockchain_data/pre_filtered_blocks/"},{path:"/blockchain_data/pre_filtered_blocks.html",redirect:"/blockchain_data/pre_filtered_blocks/"},{name:"v-6b753255",path:"/blockchain_data/transaction_broadcasting/",component:Tc,beforeEnter:(t,e,n)=>{pc("Layout","v-6b753255").then(n)}},{path:"/blockchain_data/transaction_broadcasting/index.html",redirect:"/blockchain_data/transaction_broadcasting/"},{path:"/blockchain_data/transaction_broadcasting.html",redirect:"/blockchain_data/transaction_broadcasting/"},{name:"v-0c8784ee",path:"/building-a-node-with-ldk/closing-a-channel/",component:Tc,beforeEnter:(t,e,n)=>{pc("Layout","v-0c8784ee").then(n)}},{path:"/building-a-node-with-ldk/closing-a-channel/index.html",redirect:"/building-a-node-with-ldk/closing-a-channel/"},{path:"/building-a-node-with-ldk/closing-a-channel.html",redirect:"/building-a-node-with-ldk/closing-a-channel/"},{name:"v-2e33a981",path:"/building-a-node-with-ldk/connect-to-peers/",component:Tc,beforeEnter:(t,e,n)=>{pc("Layout","v-2e33a981").then(n)}},{path:"/building-a-node-with-ldk/connect-to-peers/index.html",redirect:"/building-a-node-with-ldk/connect-to-peers/"},{path:"/building-a-node-with-ldk/connect-to-peers.html",redirect:"/building-a-node-with-ldk/connect-to-peers/"},{name:"v-4215c085",path:"/building-a-node-with-ldk/handling-events/",component:Tc,beforeEnter:(t,e,n)=>{pc("Layout","v-4215c085").then(n)}},{path:"/building-a-node-with-ldk/handling-events/index.html",redirect:"/building-a-node-with-ldk/handling-events/"},{path:"/building-a-node-with-ldk/handling-events.html",redirect:"/building-a-node-with-ldk/handling-events/"},{name:"v-208c95fe",path:"/building-a-node-with-ldk/installation/",component:Tc,beforeEnter:(t,e,n)=>{pc("Layout","v-208c95fe").then(n)}},{path:"/building-a-node-with-ldk/installation/index.html",redirect:"/building-a-node-with-ldk/installation/"},{path:"/building-a-node-with-ldk/installation.html",redirect:"/building-a-node-with-ldk/installation/"},{name:"v-4e009901",path:"/building-a-node-with-ldk/introduction/",component:Tc,beforeEnter:(t,e,n)=>{pc("Layout","v-4e009901").then(n)}},{path:"/building-a-node-with-ldk/introduction/index.html",redirect:"/building-a-node-with-ldk/introduction/"},{path:"/building-a-node-with-ldk/introduction.html",redirect:"/building-a-node-with-ldk/introduction/"},{name:"v-f958b67a",path:"/building-a-node-with-ldk/opening-a-channel/",component:Tc,beforeEnter:(t,e,n)=>{pc("Layout","v-f958b67a").then(n)}},{path:"/building-a-node-with-ldk/opening-a-channel/index.html",redirect:"/building-a-node-with-ldk/opening-a-channel/"},{path:"/building-a-node-with-ldk/opening-a-channel.html",redirect:"/building-a-node-with-ldk/opening-a-channel/"},{name:"v-44e9497e",path:"/building-a-node-with-ldk/receiving-payments/",component:Tc,beforeEnter:(t,e,n)=>{pc("Layout","v-44e9497e").then(n)}},{path:"/building-a-node-with-ldk/receiving-payments/index.html",redirect:"/building-a-node-with-ldk/receiving-payments/"},{path:"/building-a-node-with-ldk/receiving-payments.html",redirect:"/building-a-node-with-ldk/receiving-payments/"},{name:"v-3cfeb3fe",path:"/building-a-node-with-ldk/setting-up-a-channel-manager/",component:Tc,beforeEnter:(t,e,n)=>{pc("Layout","v-3cfeb3fe").then(n)}},{path:"/building-a-node-with-ldk/setting-up-a-channel-manager/index.html",redirect:"/building-a-node-with-ldk/setting-up-a-channel-manager/"},{path:"/building-a-node-with-ldk/setting-up-a-channel-manager.html",redirect:"/building-a-node-with-ldk/setting-up-a-channel-manager/"},{name:"v-f0ae247e",path:"/building-a-node-with-ldk/setting-up-a-peer-manager/",component:Tc,beforeEnter:(t,e,n)=>{pc("Layout","v-f0ae247e").then(n)}},{path:"/building-a-node-with-ldk/setting-up-a-peer-manager/index.html",redirect:"/building-a-node-with-ldk/setting-up-a-peer-manager/"},{path:"/building-a-node-with-ldk/setting-up-a-peer-manager.html",redirect:"/building-a-node-with-ldk/setting-up-a-peer-manager/"},{name:"v-1f59967e",path:"/building-a-node-with-ldk/sending-payments/",component:Tc,beforeEnter:(t,e,n)=>{pc("Layout","v-1f59967e").then(n)}},{path:"/building-a-node-with-ldk/sending-payments/index.html",redirect:"/building-a-node-with-ldk/sending-payments/"},{path:"/building-a-node-with-ldk/sending-payments.html",redirect:"/building-a-node-with-ldk/sending-payments/"},{name:"v-1df9ba79",path:"/case-studies/",component:Tc,beforeEnter:(t,e,n)=>{pc("Layout","v-1df9ba79").then(n)}},{path:"/case-studies/index.html",redirect:"/case-studies/"},{path:"/case-studies.html",redirect:"/case-studies/"},{name:"v-acaf8bbe",path:"/code_of_conduct/",component:Tc,beforeEnter:(t,e,n)=>{pc("Layout","v-acaf8bbe").then(n)}},{path:"/code_of_conduct/index.html",redirect:"/code_of_conduct/"},{path:"/code_of_conduct.html",redirect:"/code_of_conduct/"},{name:"v-5e36ef8a",path:"/examples/",component:Tc,beforeEnter:(t,e,n)=>{pc("Layout","v-5e36ef8a").then(n)}},{path:"/examples/index.html",redirect:"/examples/"},{path:"/examples.html",redirect:"/examples/"},{name:"v-197bd04c",path:"/",component:Tc,beforeEnter:(t,e,n)=>{pc("Layout","v-197bd04c").then(n)}},{path:"/index.html",redirect:"/"},{name:"v-d599223e",path:"/introduction/architecture/",component:Tc,beforeEnter:(t,e,n)=>{pc("Layout","v-d599223e").then(n)}},{path:"/introduction/architecture/index.html",redirect:"/introduction/architecture/"},{path:"/introduction/architecture.html",redirect:"/introduction/architecture/"},{name:"v-7495ad8d",path:"/introduction/blockchain_data/",component:Tc,beforeEnter:(t,e,n)=>{pc("Layout","v-7495ad8d").then(n)}},{path:"/introduction/blockchain_data/index.html",redirect:"/introduction/blockchain_data/"},{path:"/introduction/blockchain_data.html",redirect:"/introduction/blockchain_data/"},{name:"v-2615480c",path:"/introduction/",component:Tc,beforeEnter:(t,e,n)=>{pc("Layout","v-2615480c").then(n)}},{path:"/introduction/index.html",redirect:"/introduction/"},{name:"v-2c8ce301",path:"/introduction/networking/",component:Tc,beforeEnter:(t,e,n)=>{pc("Layout","v-2c8ce301").then(n)}},{path:"/introduction/networking/index.html",redirect:"/introduction/networking/"},{path:"/introduction/networking.html",redirect:"/introduction/networking/"},{name:"v-6f688c61",path:"/introduction/persistent_storage/",component:Tc,beforeEnter:(t,e,n)=>{pc("Layout","v-6f688c61").then(n)}},{path:"/introduction/persistent_storage/index.html",redirect:"/introduction/persistent_storage/"},{path:"/introduction/persistent_storage.html",redirect:"/introduction/persistent_storage/"},{name:"v-9b98f9ca",path:"/introduction/peer-management/",component:Tc,beforeEnter:(t,e,n)=>{pc("Layout","v-9b98f9ca").then(n)}},{path:"/introduction/peer-management/index.html",redirect:"/introduction/peer-management/"},{path:"/introduction/peer-management.html",redirect:"/introduction/peer-management/"},{name:"v-73ba0ae1",path:"/introduction/private_key_management/",component:Tc,beforeEnter:(t,e,n)=>{pc("Layout","v-73ba0ae1").then(n)}},{path:"/introduction/private_key_management/index.html",redirect:"/introduction/private_key_management/"},{path:"/introduction/private_key_management.html",redirect:"/introduction/private_key_management/"},{name:"v-0a5ecb01",path:"/introduction/random_number_generation/",component:Tc,beforeEnter:(t,e,n)=>{pc("Layout","v-0a5ecb01").then(n)}},{path:"/introduction/random_number_generation/index.html",redirect:"/introduction/random_number_generation/"},{path:"/introduction/random_number_generation.html",redirect:"/introduction/random_number_generation/"},{name:"v-8b8ac0be",path:"/introduction/transactions/",component:Tc,beforeEnter:(t,e,n)=>{pc("Layout","v-8b8ac0be").then(n)}},{path:"/introduction/transactions/index.html",redirect:"/introduction/transactions/"},{path:"/introduction/transactions.html",redirect:"/introduction/transactions/"},{name:"v-2e6cd4fd",path:"/introduction/use-cases/",component:Tc,beforeEnter:(t,e,n)=>{pc("Layout","v-2e6cd4fd").then(n)}},{path:"/introduction/use-cases/index.html",redirect:"/introduction/use-cases/"},{path:"/introduction/use-cases.html",redirect:"/introduction/use-cases/"},{name:"v-c4171d36",path:"/introduction/wallet_management/",component:Tc,beforeEnter:(t,e,n)=>{pc("Layout","v-c4171d36").then(n)}},{path:"/introduction/wallet_management/index.html",redirect:"/introduction/wallet_management/"},{path:"/introduction/wallet_management.html",redirect:"/introduction/wallet_management/"},{name:"v-21d81ac1",path:"/language_bindings/",component:Tc,beforeEnter:(t,e,n)=>{pc("Layout","v-21d81ac1").then(n)}},{path:"/language_bindings/index.html",redirect:"/language_bindings/"},{path:"/language_bindings.html",redirect:"/language_bindings/"},{name:"v-50f91cc7",path:"/key_management/",component:Tc,beforeEnter:(t,e,n)=>{pc("Layout","v-50f91cc7").then(n)}},{path:"/key_management/index.html",redirect:"/key_management/"},{path:"/key_management.html",redirect:"/key_management/"},{name:"v-102e5c3e",path:"/persist/",component:Tc,beforeEnter:(t,e,n)=>{pc("Layout","v-102e5c3e").then(n)}},{path:"/persist/index.html",redirect:"/persist/"},{path:"/persist.html",redirect:"/persist/"},{name:"v-1d645dc1",path:"/running-a-sample-ldk-node/",component:Tc,beforeEnter:(t,e,n)=>{pc("Layout","v-1d645dc1").then(n)}},{path:"/running-a-sample-ldk-node/index.html",redirect:"/running-a-sample-ldk-node/"},{path:"/running-a-sample-ldk-node.html",redirect:"/running-a-sample-ldk-node/"},{name:"v-424df898",path:"/blog/",component:Tc,beforeEnter:(t,e,n)=>{pc("IndexPost","v-424df898").then(n)},meta:{pid:"blog",id:"blog"}},{path:"/blog/index.html",redirect:"/blog/"},{name:"v-619df59e",path:"/blog/tags/",component:Tc,beforeEnter:(t,e,n)=>{pc("FrontmatterKey","v-619df59e").then(n)},meta:{pid:"tags",id:"tags"}},{path:"/blog/tags/index.html",redirect:"/blog/tags/"},{name:"v-b0968728",path:"/blog/author/",component:Tc,beforeEnter:(t,e,n)=>{pc("FrontmatterKey","v-b0968728").then(n)},meta:{pid:"author",id:"author"}},{path:"/blog/author/index.html",redirect:"/blog/author/"},{name:"v-07a81b3e",path:"/blog/tags/Channels/",component:Tc,beforeEnter:(t,e,n)=>{pc("FrontmatterPagination","v-07a81b3e").then(n)},meta:{pid:"tags",id:"Channels"}},{path:"/blog/tags/Channels/index.html",redirect:"/blog/tags/Channels/"},{name:"v-2d66714d",path:"/blog/tags/Anchor Outputs/",component:Tc,beforeEnter:(t,e,n)=>{pc("FrontmatterPagination","v-2d66714d").then(n)},meta:{pid:"tags",id:"Anchor Outputs"}},{path:"/blog/tags/Anchor Outputs/index.html",redirect:"/blog/tags/Anchor Outputs/"},{name:"v-3d7abd24",path:"/blog/tags/Fees/",component:Tc,beforeEnter:(t,e,n)=>{pc("FrontmatterPagination","v-3d7abd24").then(n)},meta:{pid:"tags",id:"Fees"}},{path:"/blog/tags/Fees/index.html",redirect:"/blog/tags/Fees/"},{name:"v-45d354a1",path:"/blog/tags/Self-custody/",component:Tc,beforeEnter:(t,e,n)=>{pc("FrontmatterPagination","v-45d354a1").then(n)},meta:{pid:"tags",id:"Self-custody"}},{path:"/blog/tags/Self-custody/index.html",redirect:"/blog/tags/Self-custody/"},{name:"v-4cee384f",path:"/blog/tags/Mobile/",component:Tc,beforeEnter:(t,e,n)=>{pc("FrontmatterPagination","v-4cee384f").then(n)},meta:{pid:"tags",id:"Mobile"}},{path:"/blog/tags/Mobile/index.html",redirect:"/blog/tags/Mobile/"},{name:"v-107ce622",path:"/blog/tags/Gossip/",component:Tc,beforeEnter:(t,e,n)=>{pc("FrontmatterPagination","v-107ce622").then(n)},meta:{pid:"tags",id:"Gossip"}},{path:"/blog/tags/Gossip/index.html",redirect:"/blog/tags/Gossip/"},{name:"v-288bb6f4",path:"/blog/tags/Network Graph/",component:Tc,beforeEnter:(t,e,n)=>{pc("FrontmatterPagination","v-288bb6f4").then(n)},meta:{pid:"tags",id:"Network Graph"}},{path:"/blog/tags/Network Graph/index.html",redirect:"/blog/tags/Network Graph/"},{name:"v-b0d4940c",path:"/blog/tags/Offers/",component:Tc,beforeEnter:(t,e,n)=>{pc("FrontmatterPagination","v-b0d4940c").then(n)},meta:{pid:"tags",id:"Offers"}},{path:"/blog/tags/Offers/index.html",redirect:"/blog/tags/Offers/"},{name:"v-d885a66a",path:"/blog/tags/Onion Messages/",component:Tc,beforeEnter:(t,e,n)=>{pc("FrontmatterPagination","v-d885a66a").then(n)},meta:{pid:"tags",id:"Onion Messages"}},{path:"/blog/tags/Onion Messages/index.html",redirect:"/blog/tags/Onion Messages/"},{name:"v-33d32965",path:"/blog/tags/Privacy/",component:Tc,beforeEnter:(t,e,n)=>{pc("FrontmatterPagination","v-33d32965").then(n)},meta:{pid:"tags",id:"Privacy"}},{path:"/blog/tags/Privacy/index.html",redirect:"/blog/tags/Privacy/"},{name:"v-2571507d",path:"/blog/tags/Case Studies/",component:Tc,beforeEnter:(t,e,n)=>{pc("FrontmatterPagination","v-2571507d").then(n)},meta:{pid:"tags",id:"Case Studies"}},{path:"/blog/tags/Case Studies/index.html",redirect:"/blog/tags/Case Studies/"},{name:"v-89aabae2",path:"/blog/tags/Bitcoin/",component:Tc,beforeEnter:(t,e,n)=>{pc("FrontmatterPagination","v-89aabae2").then(n)},meta:{pid:"tags",id:"Bitcoin"}},{path:"/blog/tags/Bitcoin/index.html",redirect:"/blog/tags/Bitcoin/"},{name:"v-5f1ce94c",path:"/blog/tags/LDK/",component:Tc,beforeEnter:(t,e,n)=>{pc("FrontmatterPagination","v-5f1ce94c").then(n)},meta:{pid:"tags",id:"LDK"}},{path:"/blog/tags/LDK/index.html",redirect:"/blog/tags/LDK/"},{name:"v-5643d131",path:"/blog/tags/Roadmap/",component:Tc,beforeEnter:(t,e,n)=>{pc("FrontmatterPagination","v-5643d131").then(n)},meta:{pid:"tags",id:"Roadmap"}},{path:"/blog/tags/Roadmap/index.html",redirect:"/blog/tags/Roadmap/"},{name:"v-75584720",path:"/blog/tags/Enterprise/",component:Tc,beforeEnter:(t,e,n)=>{pc("FrontmatterPagination","v-75584720").then(n)},meta:{pid:"tags",id:"Enterprise"}},{path:"/blog/tags/Enterprise/index.html",redirect:"/blog/tags/Enterprise/"},{name:"v-14c62680",path:"/blog/tags/Phantom/",component:Tc,beforeEnter:(t,e,n)=>{pc("FrontmatterPagination","v-14c62680").then(n)},meta:{pid:"tags",id:"Phantom"}},{path:"/blog/tags/Phantom/index.html",redirect:"/blog/tags/Phantom/"},{name:"v-0bfa2c21",path:"/blog/tags/Non-Custodial/",component:Tc,beforeEnter:(t,e,n)=>{pc("FrontmatterPagination","v-0bfa2c21").then(n)},meta:{pid:"tags",id:"Non-Custodial"}},{path:"/blog/tags/Non-Custodial/index.html",redirect:"/blog/tags/Non-Custodial/"},{name:"v-2520b09b",path:"/blog/tags/liquidity/",component:Tc,beforeEnter:(t,e,n)=>{pc("FrontmatterPagination","v-2520b09b").then(n)},meta:{pid:"tags",id:"liquidity"}},{path:"/blog/tags/liquidity/index.html",redirect:"/blog/tags/liquidity/"},{name:"v-026b604a",path:"/blog/tags/0-Conf Channels/",component:Tc,beforeEnter:(t,e,n)=>{pc("FrontmatterPagination","v-026b604a").then(n)},meta:{pid:"tags",id:"0-Conf Channels"}},{path:"/blog/tags/0-Conf Channels/index.html",redirect:"/blog/tags/0-Conf Channels/"},{name:"v-27610544",path:"/blog/author/Wilmer Paulino/",component:Tc,beforeEnter:(t,e,n)=>{pc("FrontmatterPagination","v-27610544").then(n)},meta:{pid:"author",id:"Wilmer Paulino"}},{path:"/blog/author/Wilmer Paulino/index.html",redirect:"/blog/author/Wilmer Paulino/"},{name:"v-580ef260",path:"/blog/author/Elias Rohrer/",component:Tc,beforeEnter:(t,e,n)=>{pc("FrontmatterPagination","v-580ef260").then(n)},meta:{pid:"author",id:"Elias Rohrer"}},{path:"/blog/author/Elias Rohrer/index.html",redirect:"/blog/author/Elias Rohrer/"},{name:"v-79994b30",path:"/blog/author/Arik Sosman/",component:Tc,beforeEnter:(t,e,n)=>{pc("FrontmatterPagination","v-79994b30").then(n)},meta:{pid:"author",id:"Arik Sosman"}},{path:"/blog/author/Arik Sosman/index.html",redirect:"/blog/author/Arik Sosman/"},{name:"v-bf9b8e8a",path:"/blog/author/Jeff Czyz/",component:Tc,beforeEnter:(t,e,n)=>{pc("FrontmatterPagination","v-bf9b8e8a").then(n)},meta:{pid:"author",id:"Jeff Czyz"}},{path:"/blog/author/Jeff Czyz/index.html",redirect:"/blog/author/Jeff Czyz/"},{name:"v-5e0b95d8",path:"/blog/author/Matt Carvalho/",component:Tc,beforeEnter:(t,e,n)=>{pc("FrontmatterPagination","v-5e0b95d8").then(n)},meta:{pid:"author",id:"Matt Carvalho"}},{path:"/blog/author/Matt Carvalho/index.html",redirect:"/blog/author/Matt Carvalho/"},{name:"v-571fde2c",path:"/blog/author/Ryan Loomba/",component:Tc,beforeEnter:(t,e,n)=>{pc("FrontmatterPagination","v-571fde2c").then(n)},meta:{pid:"author",id:"Ryan Loomba"}},{path:"/blog/author/Ryan Loomba/index.html",redirect:"/blog/author/Ryan Loomba/"},{name:"v-044cdb6b",path:"/blog/author/Conor Okus/",component:Tc,beforeEnter:(t,e,n)=>{pc("FrontmatterPagination","v-044cdb6b").then(n)},meta:{pid:"author",id:"Conor Okus"}},{path:"/blog/author/Conor Okus/index.html",redirect:"/blog/author/Conor Okus/"},{name:"v-39b7f2bf",path:"/blog/author/Steve Lee/",component:Tc,beforeEnter:(t,e,n)=>{pc("FrontmatterPagination","v-39b7f2bf").then(n)},meta:{pid:"author",id:"Steve Lee"}},{path:"/blog/author/Steve Lee/index.html",redirect:"/blog/author/Steve Lee/"},{name:"v-6a051305",path:"/blog/author/Ben Carman/",component:Tc,beforeEnter:(t,e,n)=>{pc("FrontmatterPagination","v-6a051305").then(n)},meta:{pid:"author",id:"Ben Carman"}},{path:"/blog/author/Ben Carman/index.html",redirect:"/blog/author/Ben Carman/"},{name:"v-54403322",path:"/blog/author/Valentine Wallace/",component:Tc,beforeEnter:(t,e,n)=>{pc("FrontmatterPagination","v-54403322").then(n)},meta:{pid:"author",id:"Valentine Wallace"}},{path:"/blog/author/Valentine Wallace/index.html",redirect:"/blog/author/Valentine Wallace/"},{name:"v-c06ffaa8",path:"/blog/author/John Cantrell/",component:Tc,beforeEnter:(t,e,n)=>{pc("FrontmatterPagination","v-c06ffaa8").then(n)},meta:{pid:"author",id:"John Cantrell"}},{path:"/blog/author/John Cantrell/index.html",redirect:"/blog/author/John Cantrell/"},{name:"v-438a3c44",path:"/blog/author/Matt Corallo/",component:Tc,beforeEnter:(t,e,n)=>{pc("FrontmatterPagination","v-438a3c44").then(n)},meta:{pid:"author",id:"Matt Corallo"}},{path:"/blog/author/Matt Corallo/index.html",redirect:"/blog/author/Matt Corallo/"},{name:"v-0c9ef90c",path:"/blog/author/Sergi Delgado/",component:Tc,beforeEnter:(t,e,n)=>{pc("FrontmatterPagination","v-0c9ef90c").then(n)},meta:{pid:"author",id:"Sergi Delgado"}},{path:"/blog/author/Sergi Delgado/index.html",redirect:"/blog/author/Sergi Delgado/"},{name:"v-c3507bb6",path:"/blog/page/2/",component:Tc,beforeEnter:(t,e,n)=>{pc("DirectoryPagination","v-c3507bb6").then(n)},meta:{pid:"blog",id:"blog"}},{path:"/blog/page/2/index.html",redirect:"/blog/page/2/"},{path:"*",component:Tc}],Ec={title:"Lightning Dev Kit Documentation",description:"LDK is a flexible lightning implementation with supporting batteries (or modules).",base:"/",headTags:[["meta",{name:"viewport",content:"width=device-width,initial-scale=1.0"}],["link",{rel:"preload",href:"/fonts/ibm-plex-mono-400.woff2",as:"font",crossorigin:!0}],["link",{rel:"apple-touch-icon",sizes:"180x180",href:"/img/favicon/apple-touch-icon.png"}],["link",{rel:"manifest",href:"/site.webmanifest"}],["link",{rel:"stylesheet",href:"/css/variables.css"}],["link",{name:"msapplication-config",content:"/browserconfig.xml"}],["link",{name:"msapplication-TileColor",content:"#ffffff"}],["link",{name:"theme-color",content:"#ffffff"}]],pages:[{title:"Anchor Outputs Channels Are Here",frontmatter:{title:"Anchor Outputs Channels Are Here",description:"LDK v0.0.116 added support for opening channels with anchor outputs.",date:"2023-08-02",authors:["Wilmer Paulino"],tags:["Channels","Anchor Outputs","Fees"],meta:[{property:"article:published_time",content:"2023-08-02T00:00:00.000Z"},{property:"og:site_name",content:"Lightning Dev Kit Documentation"},{property:"og:title",content:"Anchor Outputs Channels Are Here"},{property:"og:description",content:"LDK v0.0.116 added support for opening channels with anchor outputs."},{property:"og:type",content:"article"},{property:"og:url",content:"https://lightningdevkit.org/_blog/anchor-outputs-channels-are-here/"},{property:"og:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:title",content:"Anchor Outputs Channels Are Here"},{name:"twitter:description",content:"LDK v0.0.116 added support for opening channels with anchor outputs."},{name:"twitter:url",content:"https://lightningdevkit.org/_blog/anchor-outputs-channels-are-here/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Channels, Anchor Outputs, Fees"},{property:"article:tag",content:"Channels"},{property:"article:tag",content:"Anchor Outputs"},{property:"article:tag",content:"Fees"}],layout:"Post",permalink:"/blog/:slug"},regularPath:"/_blog/anchor-outputs-channels-are-here.html",relativePath:"_blog/anchor-outputs-channels-are-here.md",key:"v-109b7b6a",path:"/blog/anchor-outputs-channels-are-here/",codeSwitcherOptions:{},id:"blog",pid:"blog",lastUpdated:"5/14/2024, 4:25:51 PM",lastUpdatedTimestamp:1715703951e3},{title:"Announcing LDK Node",frontmatter:{title:"Announcing LDK Node",description:"A ready-to-go Lightning node library built using LDK and BDK.",date:"2023-06-22",authors:["Elias Rohrer"],tags:["Self-custody","Mobile"],meta:[{property:"article:published_time",content:"2023-06-22T00:00:00.000Z"},{property:"og:site_name",content:"Lightning Dev Kit Documentation"},{property:"og:title",content:"Announcing LDK Node"},{property:"og:description",content:"A ready-to-go Lightning node library built using LDK and BDK."},{property:"og:type",content:"article"},{property:"og:url",content:"https://lightningdevkit.org/_blog/announcing-ldk-node/"},{property:"og:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:title",content:"Announcing LDK Node"},{name:"twitter:description",content:"A ready-to-go Lightning node library built using LDK and BDK."},{name:"twitter:url",content:"https://lightningdevkit.org/_blog/announcing-ldk-node/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Self-custody, Mobile"},{property:"article:tag",content:"Self-custody"},{property:"article:tag",content:"Mobile"}],layout:"Post",permalink:"/blog/:slug"},regularPath:"/_blog/announcing-ldk-node.html",relativePath:"_blog/announcing-ldk-node.md",key:"v-0f4e007e",path:"/blog/announcing-ldk-node/",headers:[{level:2,title:"A Lightweight Solution",slug:"a-lightweight-solution"},{level:2,title:"LDK Node: Simplifying Self-custodial Lightning Integration",slug:"ldk-node-simplifying-self-custodial-lightning-integration"},{level:2,title:"Mobile-first Self-Custody",slug:"mobile-first-self-custody"},{level:2,title:"Getting Started",slug:"getting-started"},{level:2,title:"Outlook",slug:"outlook"},{level:2,title:"Further Resources",slug:"further-resources"},{level:2,title:"Showcases",slug:"showcases"}],codeSwitcherOptions:{},id:"blog",pid:"blog",lastUpdated:"5/14/2024, 4:25:51 PM",lastUpdatedTimestamp:1715703951e3},{title:"Announcing Rapid Gossip Sync",frontmatter:{title:"Announcing Rapid Gossip Sync",description:"Rapid Gossip Sync is a protocol that allows nodes to catch up with channel gossip data by relying on semi-trusted servers.",date:"2022-08-30",authors:["Arik Sosman"],tags:["Gossip","Network Graph"],meta:[{property:"article:published_time",content:"2022-08-30T00:00:00.000Z"},{property:"og:site_name",content:"Lightning Dev Kit Documentation"},{property:"og:title",content:"Announcing Rapid Gossip Sync"},{property:"og:description",content:"Rapid Gossip Sync is a protocol that allows nodes to catch up with channel gossip data by relying on semi-trusted servers."},{property:"og:type",content:"article"},{property:"og:url",content:"https://lightningdevkit.org/_blog/announcing-rapid-gossip-sync/"},{property:"og:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:title",content:"Announcing Rapid Gossip Sync"},{name:"twitter:description",content:"Rapid Gossip Sync is a protocol that allows nodes to catch up with channel gossip data by relying on semi-trusted servers."},{name:"twitter:url",content:"https://lightningdevkit.org/_blog/announcing-rapid-gossip-sync/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Gossip, Network Graph"},{property:"article:tag",content:"Gossip"},{property:"article:tag",content:"Network Graph"}],layout:"Post",permalink:"/blog/:slug"},regularPath:"/_blog/announcing-rapid-gossip-sync.html",relativePath:"_blog/announcing-rapid-gossip-sync.md",key:"v-2578306f",path:"/blog/announcing-rapid-gossip-sync/",headers:[{level:2,title:"Exchanging Gossip Today",slug:"exchanging-gossip-today"},{level:2,title:"Rapid Gossip Sync",slug:"rapid-gossip-sync"},{level:2,title:"Rapid Gossip Sync Server",slug:"rapid-gossip-sync-server"},{level:2,title:"Trust Model",slug:"trust-model"},{level:2,title:"Conclusion",slug:"conclusion"}],codeSwitcherOptions:{},id:"blog",pid:"blog",lastUpdated:"5/14/2024, 4:25:51 PM",lastUpdatedTimestamp:1715703951e3},{title:"BOLT12 Has Arrived",frontmatter:{title:"BOLT12 Has Arrived",description:"BOLT12 offers enhanced privacy, reusable payment codes, refunds, and much more, all natively over the Lightning Network.",date:"2024-04-30",authors:["Jeff Czyz"],tags:["Offers","Onion Messages","Privacy"],meta:[{property:"article:published_time",content:"2024-04-30T00:00:00.000Z"},{property:"og:site_name",content:"Lightning Dev Kit Documentation"},{property:"og:title",content:"BOLT12 Has Arrived"},{property:"og:description",content:"BOLT12 offers enhanced privacy, reusable payment codes, refunds, and much more, all natively over the Lightning Network."},{property:"og:type",content:"article"},{property:"og:url",content:"https://lightningdevkit.org/_blog/bolt12-has-arrived/"},{property:"og:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:title",content:"BOLT12 Has Arrived"},{name:"twitter:description",content:"BOLT12 offers enhanced privacy, reusable payment codes, refunds, and much more, all natively over the Lightning Network."},{name:"twitter:url",content:"https://lightningdevkit.org/_blog/bolt12-has-arrived/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Offers, Onion Messages, Privacy"},{property:"article:tag",content:"Offers"},{property:"article:tag",content:"Onion Messages"},{property:"article:tag",content:"Privacy"}],layout:"Post",permalink:"/blog/:slug"},regularPath:"/_blog/bolt12-has-arrived.html",relativePath:"_blog/bolt12-has-arrived.md",key:"v-6018492a",path:"/blog/bolt12-has-arrived/",headers:[{level:2,title:"BOLT11 Invoices and Reusability",slug:"bolt11-invoices-and-reusability"},{level:2,title:"BOLT12 to the Rescue",slug:"bolt12-to-the-rescue"},{level:2,title:"OK, so what about privacy?",slug:"ok-so-what-about-privacy"},{level:2,title:"Offers in LDK",slug:"offers-in-ldk"},{level:2,title:"Wait, what about refunds?",slug:"wait-what-about-refunds"},{level:2,title:"Achieving statelessness",slug:"achieving-statelessness"},{level:2,title:"What’s next?",slug:"what-s-next"}],codeSwitcherOptions:{},id:"blog",pid:"blog",lastUpdated:"5/14/2024, 4:25:51 PM",lastUpdatedTimestamp:1715703951e3},{title:"Bitkit uses LDK to build the ultimate alternative to custodial wallets",frontmatter:{title:"Bitkit uses LDK to build the ultimate alternative to custodial wallets",description:"Learn how Bitkit uses LDK to build a cross platform mobile wallet",date:"2024-01-24",authors:["Matt Carvalho"],tags:["Case Studies"],meta:[{property:"article:published_time",content:"2024-01-24T00:00:00.000Z"},{property:"og:site_name",content:"Lightning Dev Kit Documentation"},{property:"og:title",content:"Bitkit uses LDK to build the ultimate alternative to custodial wallets"},{property:"og:description",content:"Learn how Bitkit uses LDK to build a cross platform mobile wallet"},{property:"og:type",content:"article"},{property:"og:url",content:"https://lightningdevkit.org/_blog/bitkit-uses-ldk-to-build-the-ultimate-alternative-to-custodial%20wallets/"},{property:"og:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:title",content:"Bitkit uses LDK to build the ultimate alternative to custodial wallets"},{name:"twitter:description",content:"Learn how Bitkit uses LDK to build a cross platform mobile wallet"},{name:"twitter:url",content:"https://lightningdevkit.org/_blog/bitkit-uses-ldk-to-build-the-ultimate-alternative-to-custodial%20wallets/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Case Studies"},{property:"article:tag",content:"Case Studies"}],layout:"Post",permalink:"/blog/:slug"},regularPath:"/_blog/bitkit-uses-ldk-to-build-the-ultimate-alternative-to-custodial%20wallets.html",relativePath:"_blog/bitkit-uses-ldk-to-build-the-ultimate-alternative-to-custodial wallets.md",key:"v-59a63080",path:"/blog/bitkit-uses-ldk-to-build-the-ultimate-alternative-to-custodial-wallets/",codeSwitcherOptions:{},id:"blog",pid:"blog",lastUpdated:"5/14/2024, 4:25:51 PM",lastUpdatedTimestamp:1715703951e3},{title:"Cash App Enables Lightning Withdrawals & Deposits Using LDK",frontmatter:{title:"Cash App Enables Lightning Withdrawals & Deposits Using LDK",description:"Learn how Cash App integrated with the lightning network, allowing its users to send and receive bitcoin instantly.",date:"2022-11-17",authors:["Ryan Loomba"],tags:["Case Studies"],meta:[{property:"article:published_time",content:"2022-11-17T00:00:00.000Z"},{property:"og:site_name",content:"Lightning Dev Kit Documentation"},{property:"og:title",content:"Cash App Enables Lightning Withdrawals & Deposits Using LDK"},{property:"og:description",content:"Learn how Cash App integrated with the lightning network, allowing its users to send and receive bitcoin instantly."},{property:"og:type",content:"article"},{property:"og:url",content:"https://lightningdevkit.org/_blog/cashapp-enables-lightning-withdrawals-and-deposits-using-ldk/"},{property:"og:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:title",content:"Cash App Enables Lightning Withdrawals & Deposits Using LDK"},{name:"twitter:description",content:"Learn how Cash App integrated with the lightning network, allowing its users to send and receive bitcoin instantly."},{name:"twitter:url",content:"https://lightningdevkit.org/_blog/cashapp-enables-lightning-withdrawals-and-deposits-using-ldk/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Case Studies"},{property:"article:tag",content:"Case Studies"}],layout:"Post",permalink:"/blog/:slug"},regularPath:"/_blog/cashapp-enables-lightning-withdrawals-and-deposits-using-ldk.html",relativePath:"_blog/cashapp-enables-lightning-withdrawals-and-deposits-using-ldk.md",key:"v-e02a8a76",path:"/blog/cashapp-enables-lightning-withdrawals-and-deposits-using-ldk/",codeSwitcherOptions:{},id:"blog",pid:"blog",lastUpdated:"5/14/2024, 4:25:51 PM",lastUpdatedTimestamp:1715703951e3},{title:"LDK: An SDK for the Lightning Network",frontmatter:{title:"LDK: An SDK for the Lightning Network",description:"Learn how LDK improves DX, makes it easier to work with Lightning functionality, and makes building faster for your entire team in our newly launched blog.",date:"2022-06-20",authors:["Conor Okus"],tags:["Bitcoin","LDK"],meta:[{property:"article:published_time",content:"2022-06-20T00:00:00.000Z"},{property:"og:site_name",content:"Lightning Dev Kit Documentation"},{property:"og:title",content:"LDK: An SDK for the Lightning Network"},{property:"og:description",content:"Learn how LDK improves DX, makes it easier to work with Lightning functionality, and makes building faster for your entire team in our newly launched blog."},{property:"og:type",content:"article"},{property:"og:url",content:"https://lightningdevkit.org/_blog/ldk-an-sdk-for-the-lightning-network/"},{property:"og:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:title",content:"LDK: An SDK for the Lightning Network"},{name:"twitter:description",content:"Learn how LDK improves DX, makes it easier to work with Lightning functionality, and makes building faster for your entire team in our newly launched blog."},{name:"twitter:url",content:"https://lightningdevkit.org/_blog/ldk-an-sdk-for-the-lightning-network/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, LDK"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"LDK"}],layout:"Post",permalink:"/blog/:slug"},regularPath:"/_blog/ldk-an-sdk-for-the-lightning-network.html",relativePath:"_blog/ldk-an-sdk-for-the-lightning-network.md",key:"v-eebe6fe6",path:"/blog/ldk-an-sdk-for-the-lightning-network/",headers:[{level:2,title:"LDWho?",slug:"ldwho"},{level:2,title:"What advantages does LDK offer developers?",slug:"what-advantages-does-ldk-offer-developers"},{level:2,title:"Who uses LDK?",slug:"who-uses-ldk"},{level:2,title:"What are LDK’s engineering priorities?",slug:"what-are-ldk-s-engineering-priorities"},{level:2,title:"Notable Updates",slug:"notable-updates"}],codeSwitcherOptions:{},id:"blog",pid:"blog",lastUpdated:"5/14/2024, 4:25:51 PM",lastUpdatedTimestamp:1715703951e3},{title:"LDK Roadmap",frontmatter:{title:"LDK Roadmap",description:"LDK is going to have a big year. Several key features are actively being developed or expected to be developed in the next few quarters.",date:"2023-03-13",authors:["Steve Lee"],tags:["Roadmap"],meta:[{property:"article:published_time",content:"2023-03-13T00:00:00.000Z"},{property:"og:site_name",content:"Lightning Dev Kit Documentation"},{property:"og:title",content:"LDK Roadmap"},{property:"og:description",content:"LDK is going to have a big year. Several key features are actively being developed or expected to be developed in the next few quarters."},{property:"og:type",content:"article"},{property:"og:url",content:"https://lightningdevkit.org/_blog/ldk-roadmap/"},{property:"og:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:title",content:"LDK Roadmap"},{name:"twitter:description",content:"LDK is going to have a big year. Several key features are actively being developed or expected to be developed in the next few quarters."},{name:"twitter:url",content:"https://lightningdevkit.org/_blog/ldk-roadmap/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Roadmap"},{property:"article:tag",content:"Roadmap"}],layout:"Post",permalink:"/blog/:slug"},regularPath:"/_blog/ldk-roadmap.html",relativePath:"_blog/ldk-roadmap.md",key:"v-7b0f0961",path:"/blog/ldk-roadmap/",headers:[{level:2,title:"LDK Node",slug:"ldk-node"},{level:2,title:"BOLT 12",slug:"bolt-12"},{level:2,title:"Anchor Outputs",slug:"anchor-outputs"},{level:2,title:"VSS",slug:"vss"},{level:2,title:"Improved Async-ness in LDK API",slug:"improved-async-ness-in-ldk-api"},{level:2,title:"Simple Taproot Channels",slug:"simple-taproot-channels"},{level:2,title:"Dual-Funded Channels",slug:"dual-funded-channels"},{level:2,title:"Splicing",slug:"splicing"},{level:2,title:"Async Payments",slug:"async-payments"},{level:2,title:"PTLCs",slug:"ptlcs"},{level:2,title:"Additional Language Bindings",slug:"additional-language-bindings"},{level:2,title:"Custom Scripts",slug:"custom-scripts"},{level:2,title:"Dynamic Commitments",slug:"dynamic-commitments"}],codeSwitcherOptions:{},id:"blog",pid:"blog",lastUpdated:"5/14/2024, 4:25:51 PM",lastUpdatedTimestamp:1715703951e3},{title:"Mutiny uses LDK to create the first lightning wallet for the web",frontmatter:{title:"Mutiny uses LDK to create the first lightning wallet for the web",description:"Learn how Mutiny built a lightning wallet for the web",date:"2023-08-07",authors:["Ben Carman"],tags:["Case Studies"],meta:[{property:"article:published_time",content:"2023-08-07T00:00:00.000Z"},{property:"og:site_name",content:"Lightning Dev Kit Documentation"},{property:"og:title",content:"Mutiny uses LDK to create the first lightning wallet for the web"},{property:"og:description",content:"Learn how Mutiny built a lightning wallet for the web"},{property:"og:type",content:"article"},{property:"og:url",content:"https://lightningdevkit.org/_blog/mutiny-uses-ldk-the-first-lightning-wallet-for-the-web/"},{property:"og:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:title",content:"Mutiny uses LDK to create the first lightning wallet for the web"},{name:"twitter:description",content:"Learn how Mutiny built a lightning wallet for the web"},{name:"twitter:url",content:"https://lightningdevkit.org/_blog/mutiny-uses-ldk-the-first-lightning-wallet-for-the-web/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Case Studies"},{property:"article:tag",content:"Case Studies"}],layout:"Post",permalink:"/blog/:slug"},regularPath:"/_blog/mutiny-uses-ldk-the-first-lightning-wallet-for-the-web.html",relativePath:"_blog/mutiny-uses-ldk-the-first-lightning-wallet-for-the-web.md",key:"v-61c088e6",path:"/blog/mutiny-uses-ldk-the-first-lightning-wallet-for-the-web/",codeSwitcherOptions:{},id:"blog",pid:"blog",lastUpdated:"5/14/2024, 4:25:51 PM",lastUpdatedTimestamp:1715703951e3},{title:"Introducing Phantom Node Payments",frontmatter:{title:"Introducing Phantom Node Payments",description:"Phantom node payments let enterprise users running high-volume lightning nodes generate invoices that can be paid to one of multiple production nodes.",date:"2022-07-11",authors:["Valentine Wallace"],tags:["Enterprise","Phantom"],meta:[{property:"article:published_time",content:"2022-07-11T00:00:00.000Z"},{property:"og:site_name",content:"Lightning Dev Kit Documentation"},{property:"og:title",content:"Introducing Phantom Node Payments"},{property:"og:description",content:"Phantom node payments let enterprise users running high-volume lightning nodes generate invoices that can be paid to one of multiple production nodes."},{property:"og:type",content:"article"},{property:"og:url",content:"https://lightningdevkit.org/_blog/introducing-phantom-node-payments/"},{property:"og:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:title",content:"Introducing Phantom Node Payments"},{name:"twitter:description",content:"Phantom node payments let enterprise users running high-volume lightning nodes generate invoices that can be paid to one of multiple production nodes."},{name:"twitter:url",content:"https://lightningdevkit.org/_blog/introducing-phantom-node-payments/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Enterprise, Phantom"},{property:"article:tag",content:"Enterprise"},{property:"article:tag",content:"Phantom"}],layout:"Post",permalink:"/blog/:slug"},regularPath:"/_blog/introducing-phantom-node-payments.html",relativePath:"_blog/introducing-phantom-node-payments.md",key:"v-177ef1fe",path:"/blog/introducing-phantom-node-payments/",headers:[{level:2,title:"Phantom Payment Flow",slug:"phantom-payment-flow"},{level:2,title:"Why It’s OK to Not Support MPP",slug:"why-it-s-ok-to-not-support-mpp"},{level:2,title:"Why MPP Shouldn’t Be Enabled",slug:"why-mpp-shouldn-t-be-enabled"}],codeSwitcherOptions:{},id:"blog",pid:"blog",lastUpdated:"5/14/2024, 4:25:51 PM",lastUpdatedTimestamp:1715703951e3},{title:"Onion Messages Demystified",frontmatter:{title:"Onion Messages Demystified",description:"We recently merged support for onion message forwarding, a precursor to deprecating today’s Lightning invoice format, in favor of offers.",date:"2022-10-04",authors:["Valentine Wallace"],tags:["Onion Messages","Offers"],meta:[{property:"article:published_time",content:"2022-10-04T00:00:00.000Z"},{property:"og:site_name",content:"Lightning Dev Kit Documentation"},{property:"og:title",content:"Onion Messages Demystified"},{property:"og:description",content:"We recently merged support for onion message forwarding, a precursor to deprecating today’s Lightning invoice format, in favor of offers."},{property:"og:type",content:"article"},{property:"og:url",content:"https://lightningdevkit.org/_blog/onion-messages-demystified/"},{property:"og:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:title",content:"Onion Messages Demystified"},{name:"twitter:description",content:"We recently merged support for onion message forwarding, a precursor to deprecating today’s Lightning invoice format, in favor of offers."},{name:"twitter:url",content:"https://lightningdevkit.org/_blog/onion-messages-demystified/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Onion Messages, Offers"},{property:"article:tag",content:"Onion Messages"},{property:"article:tag",content:"Offers"}],layout:"Post",permalink:"/blog/:slug"},regularPath:"/_blog/onion-messages-demystified.html",relativePath:"_blog/onion-messages-demystified.md",key:"v-7b672071",path:"/blog/onion-messages-demystified/",headers:[{level:2,title:"How Onion Messages Work",slug:"how-onion-messages-work"},{level:2,title:"Blinded Routes",slug:"blinded-routes"},{level:2,title:"Onion Message Structure",slug:"onion-message-structure"},{level:2,title:"Beyond Offers: Asynchronous Payments",slug:"beyond-offers-asynchronous-payments"},{level:2,title:"Future Security Directions",slug:"future-security-directions"},{level:2,title:"Seeya",slug:"seeya"}],codeSwitcherOptions:{},id:"blog",pid:"blog",lastUpdated:"5/14/2024, 4:25:51 PM",lastUpdatedTimestamp:1715703951e3},{title:"Sensei uses LDK to Build a Multi-Node Lightning Server App",frontmatter:{title:"Sensei uses LDK to Build a Multi-Node Lightning Server App",description:"Learn how Sensei built a lightning node app to serve many nodes",date:"2022-12-20",authors:["John Cantrell"],tags:["Case Studies"],meta:[{property:"article:published_time",content:"2022-12-20T00:00:00.000Z"},{property:"og:site_name",content:"Lightning Dev Kit Documentation"},{property:"og:title",content:"Sensei uses LDK to Build a Multi-Node Lightning Server App"},{property:"og:description",content:"Learn how Sensei built a lightning node app to serve many nodes"},{property:"og:type",content:"article"},{property:"og:url",content:"https://lightningdevkit.org/_blog/sensei-uses-ldk-to-build-a-multi-node-lightning-server-application/"},{property:"og:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:title",content:"Sensei uses LDK to Build a Multi-Node Lightning Server App"},{name:"twitter:description",content:"Learn how Sensei built a lightning node app to serve many nodes"},{name:"twitter:url",content:"https://lightningdevkit.org/_blog/sensei-uses-ldk-to-build-a-multi-node-lightning-server-application/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Case Studies"},{property:"article:tag",content:"Case Studies"}],layout:"Post",permalink:"/blog/:slug"},regularPath:"/_blog/sensei-uses-ldk-to-build-a-multi-node-lightning-server-application.html",relativePath:"_blog/sensei-uses-ldk-to-build-a-multi-node-lightning-server-application.md",key:"v-394e384e",path:"/blog/sensei-uses-ldk-to-build-a-multi-node-lightning-server-application/",codeSwitcherOptions:{},id:"blog",pid:"blog",lastUpdated:"5/14/2024, 4:25:51 PM",lastUpdatedTimestamp:1715703951e3},{title:"The Challenges of Developing Non-Custodial Lightning on Mobile",frontmatter:{title:"The Challenges of Developing Non-Custodial Lightning on Mobile",description:"Lightning development is tough. While going custodial simplifies the process, it means sacrificing user privacy, censorship resistance, and self-sovereignty, all of which contradict bitcoin’s ethos.",date:"2023-12-14",authors:["Matt Corallo"],tags:["Mobile","Non-Custodial"],meta:[{property:"article:published_time",content:"2023-12-14T00:00:00.000Z"},{property:"og:site_name",content:"Lightning Dev Kit Documentation"},{property:"og:title",content:"The Challenges of Developing Non-Custodial Lightning on Mobile"},{property:"og:description",content:"Lightning development is tough. While going custodial simplifies the process, it means sacrificing user privacy, censorship resistance, and self-sovereignty, all of which contradict bitcoin’s ethos."},{property:"og:type",content:"article"},{property:"og:url",content:"https://lightningdevkit.org/_blog/the-challenges-of-developing-non-custodial-lightning-on-mobile/"},{property:"og:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:title",content:"The Challenges of Developing Non-Custodial Lightning on Mobile"},{name:"twitter:description",content:"Lightning development is tough. While going custodial simplifies the process, it means sacrificing user privacy, censorship resistance, and self-sovereignty, all of which contradict bitcoin’s ethos."},{name:"twitter:url",content:"https://lightningdevkit.org/_blog/the-challenges-of-developing-non-custodial-lightning-on-mobile/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Mobile, Non-Custodial"},{property:"article:tag",content:"Mobile"},{property:"article:tag",content:"Non-Custodial"}],layout:"Post",permalink:"/blog/:slug"},regularPath:"/_blog/the-challenges-of-developing-non-custodial-lightning-on-mobile.html",relativePath:"_blog/the-challenges-of-developing-non-custodial-lightning-on-mobile.md",key:"v-67ea603f",path:"/blog/the-challenges-of-developing-non-custodial-lightning-on-mobile/",headers:[{level:2,title:"Obstacles",slug:"obstacles"},{level:2,title:"Liquidity",slug:"liquidity"}],codeSwitcherOptions:{},id:"blog",pid:"blog",lastUpdated:"5/14/2024, 4:25:51 PM",lastUpdatedTimestamp:1715703951e3},{title:"TEOS uses LDK to build open-source watchtower",frontmatter:{title:"TEOS uses LDK to build open-source watchtower",description:"Learn how TEOS built an open-source watchtower",date:"2023-01-18",authors:["Sergi Delgado"],tags:["Case Studies"],meta:[{property:"article:published_time",content:"2023-01-18T00:00:00.000Z"},{property:"og:site_name",content:"Lightning Dev Kit Documentation"},{property:"og:title",content:"TEOS uses LDK to build open-source watchtower"},{property:"og:description",content:"Learn how TEOS built an open-source watchtower"},{property:"og:type",content:"article"},{property:"og:url",content:"https://lightningdevkit.org/_blog/teos-uses-ldk-to-build-open-source-watchtower/"},{property:"og:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:title",content:"TEOS uses LDK to build open-source watchtower"},{name:"twitter:description",content:"Learn how TEOS built an open-source watchtower"},{name:"twitter:url",content:"https://lightningdevkit.org/_blog/teos-uses-ldk-to-build-open-source-watchtower/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Case Studies"},{property:"article:tag",content:"Case Studies"}],layout:"Post",permalink:"/blog/:slug"},regularPath:"/_blog/teos-uses-ldk-to-build-open-source-watchtower.html",relativePath:"_blog/teos-uses-ldk-to-build-open-source-watchtower.md",key:"v-4ffe1afe",path:"/blog/teos-uses-ldk-to-build-open-source-watchtower/",codeSwitcherOptions:{},id:"blog",pid:"blog",lastUpdated:"5/14/2024, 4:25:51 PM",lastUpdatedTimestamp:1715703951e3},{title:'Unleashing Liquidity on the Lightning Network with "lightning-liquidity"',frontmatter:{title:'Unleashing Liquidity on the Lightning Network with "lightning-liquidity"',description:"The lightning-liquidity crate is an easy-to-integrate rust library that wallet developers and LSP operators can use to implement the LSP specification",date:"2024-02-29",authors:["John Cantrell"],tags:["liquidity"],meta:[{property:"article:published_time",content:"2024-02-29T00:00:00.000Z"},{property:"og:site_name",content:"Lightning Dev Kit Documentation"},{property:"og:title",content:'Unleashing Liquidity on the Lightning Network with "lightning-liquidity"'},{property:"og:description",content:"The lightning-liquidity crate is an easy-to-integrate rust library that wallet developers and LSP operators can use to implement the LSP specification"},{property:"og:type",content:"article"},{property:"og:url",content:"https://lightningdevkit.org/_blog/unleashing-liquidity-on-the-lightning-network-with-lightning-liquidity/"},{property:"og:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:title",content:'Unleashing Liquidity on the Lightning Network with "lightning-liquidity"'},{name:"twitter:description",content:"The lightning-liquidity crate is an easy-to-integrate rust library that wallet developers and LSP operators can use to implement the LSP specification"},{name:"twitter:url",content:"https://lightningdevkit.org/_blog/unleashing-liquidity-on-the-lightning-network-with-lightning-liquidity/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"liquidity"},{property:"article:tag",content:"liquidity"}],layout:"Post",permalink:"/blog/:slug"},regularPath:"/_blog/unleashing-liquidity-on-the-lightning-network-with-lightning-liquidity.html",relativePath:"_blog/unleashing-liquidity-on-the-lightning-network-with-lightning-liquidity.md",key:"v-4c78f51d",path:"/blog/unleashing-liquidity-on-the-lightning-network-with-lightning-liquidity/",headers:[{level:2,title:"How It All Started: Lightning's Liquidity Problem",slug:"how-it-all-started-lightnings-liquidity-problem"},{level:2,title:"Current Approaches and Their Shortcomings",slug:"current-approaches-and-their-shortcomings"},{level:2,title:"A Unified Solution: The Standardization Effort",slug:"a-unified-solution-the-standardization-effort"},{level:2,title:"Just-In-Time Channels: A Cornerstone of the New Protocol",slug:"just-in-time-channels-a-cornerstone-of-the-new-protocol"},{level:2,title:"Introducing lightning-liquidity",slug:"introducing-lightning-liquidity"},{level:2,title:"How It Works: For Developers and Businesses",slug:"how-it-works-for-developers-and-businesses"},{level:2,title:"Join Us in Shaping the Future",slug:"join-us-in-shaping-the-future"}],codeSwitcherOptions:{},id:"blog",pid:"blog",lastUpdated:"5/14/2024, 4:25:51 PM",lastUpdatedTimestamp:1715703951e3},{title:"Zero-Confirmation Channels",frontmatter:{title:"Zero-Confirmation Channels",description:"A 0-conf channel allows peers to start using a channel as soon as the funding transaction is broadcast.",date:"2022-09-15",authors:["John Cantrell"],tags:["0-Conf Channels"],meta:[{property:"article:published_time",content:"2022-09-15T00:00:00.000Z"},{property:"og:site_name",content:"Lightning Dev Kit Documentation"},{property:"og:title",content:"Zero-Confirmation Channels"},{property:"og:description",content:"A 0-conf channel allows peers to start using a channel as soon as the funding transaction is broadcast."},{property:"og:type",content:"article"},{property:"og:url",content:"https://lightningdevkit.org/_blog/zero-confirmation-channels/"},{property:"og:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:title",content:"Zero-Confirmation Channels"},{name:"twitter:description",content:"A 0-conf channel allows peers to start using a channel as soon as the funding transaction is broadcast."},{name:"twitter:url",content:"https://lightningdevkit.org/_blog/zero-confirmation-channels/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"0-Conf Channels"},{property:"article:tag",content:"0-Conf Channels"}],layout:"Post",permalink:"/blog/:slug"},regularPath:"/_blog/zero-confirmation-channels.html",relativePath:"_blog/zero-confirmation-channels.md",key:"v-3843152b",path:"/blog/zero-confirmation-channels/",headers:[{level:2,title:"What is a confirmation?",slug:"what-is-a-confirmation"},{level:2,title:"Why does the number of confirmations matter?",slug:"why-does-the-number-of-confirmations-matter"},{level:2,title:"What does this have to do with the Lightning Network?",slug:"what-does-this-have-to-do-with-the-lightning-network"},{level:2,title:"Why or when might 0-conf channels be useful?",slug:"why-or-when-might-0-conf-channels-be-useful"},{level:2,title:"Conclusion",slug:"conclusion"}],codeSwitcherOptions:{},id:"blog",pid:"blog",lastUpdated:"5/14/2024, 4:25:51 PM",lastUpdatedTimestamp:1715703951e3},{title:"Block Source",frontmatter:{meta:[{property:"og:site_name",content:"Lightning Dev Kit Documentation"},{property:"og:title",content:"Block Source"},{property:"og:description",content:"Implementing the `BlockSource` interface requires defining methods for fetching\nheaders, blocks, and the best block hash."},{property:"og:type",content:"article"},{property:"og:url",content:"https://lightningdevkit.org/blockchain_data/block_source/"},{property:"og:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:title",content:"Block Source"},{name:"twitter:description",content:"Implementing the `BlockSource` interface requires defining methods for fetching\nheaders, blocks, and the best block hash."},{name:"twitter:url",content:"https://lightningdevkit.org/blockchain_data/block_source/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Lightning, LDK, Lightning Dev Kit, Documentation"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Lightning"},{property:"article:tag",content:"LDK"},{property:"article:tag",content:"Lightning Dev Kit"},{property:"article:tag",content:"Documentation"}]},regularPath:"/blockchain_data/block_source.html",relativePath:"blockchain_data/block_source.md",key:"v-e5335502",path:"/blockchain_data/block_source/",codeSwitcherOptions:{},lastUpdated:"5/14/2024, 4:25:51 PM",lastUpdatedTimestamp:1715703951e3},{title:"Chain Activity",frontmatter:{meta:[{property:"og:site_name",content:"Lightning Dev Kit Documentation"},{property:"og:title",content:"Chain Activity"},{property:"og:description",content:"Initially, our node doesn't have any channels and hence has no data to monitor\nfor on-chain. When a channel is opened with a peer, the `ChannelManager` creates\na `ChannelMonitor` and passes it to the `ChainMonitor` to watch."},{property:"og:type",content:"article"},{property:"og:url",content:"https://lightningdevkit.org/blockchain_data/chain_activity/"},{property:"og:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:title",content:"Chain Activity"},{name:"twitter:description",content:"Initially, our node doesn't have any channels and hence has no data to monitor\nfor on-chain. When a channel is opened with a peer, the `ChannelManager` creates\na `ChannelMonitor` and passes it to the `ChainMonitor` to watch."},{name:"twitter:url",content:"https://lightningdevkit.org/blockchain_data/chain_activity/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Lightning, LDK, Lightning Dev Kit, Documentation"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Lightning"},{property:"article:tag",content:"LDK"},{property:"article:tag",content:"Lightning Dev Kit"},{property:"article:tag",content:"Documentation"}]},regularPath:"/blockchain_data/chain_activity.html",relativePath:"blockchain_data/chain_activity.md",key:"v-3dc27382",path:"/blockchain_data/chain_activity/",codeSwitcherOptions:{},lastUpdated:"5/14/2024, 4:25:51 PM",lastUpdatedTimestamp:1715703951e3},{title:"Full Blocks",frontmatter:{meta:[{property:"og:site_name",content:"Lightning Dev Kit Documentation"},{property:"og:title",content:"Full Blocks"},{property:"og:description",content:"If your Lightning node is backed by a Bitcoin full node, the operation is\nstraight forward: call the appropriate methods on `ChannelManager` and"},{property:"og:type",content:"article"},{property:"og:url",content:"https://lightningdevkit.org/blockchain_data/full_blocks/"},{property:"og:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:title",content:"Full Blocks"},{name:"twitter:description",content:"If your Lightning node is backed by a Bitcoin full node, the operation is\nstraight forward: call the appropriate methods on `ChannelManager` and"},{name:"twitter:url",content:"https://lightningdevkit.org/blockchain_data/full_blocks/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Lightning, LDK, Lightning Dev Kit, Documentation"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Lightning"},{property:"article:tag",content:"LDK"},{property:"article:tag",content:"Lightning Dev Kit"},{property:"article:tag",content:"Documentation"}]},regularPath:"/blockchain_data/full_blocks.html",relativePath:"blockchain_data/full_blocks.md",key:"v-3efb3c3e",path:"/blockchain_data/full_blocks/",codeSwitcherOptions:{},lastUpdated:"5/14/2024, 4:25:51 PM",lastUpdatedTimestamp:1715703951e3},{title:"Confirmed Transactions",frontmatter:{meta:[{property:"og:site_name",content:"Lightning Dev Kit Documentation"},{property:"og:title",content:"Confirmed Transactions"},{property:"og:description",content:"Up until this point, we've explored how to notify LDK of chain activity using\nblocks. But what if you're sourcing chain activity from a place that doesn't\nprovide a block-centric interface, like Electrum?"},{property:"og:type",content:"article"},{property:"og:url",content:"https://lightningdevkit.org/blockchain_data/confirmed_transactions/"},{property:"og:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:title",content:"Confirmed Transactions"},{name:"twitter:description",content:"Up until this point, we've explored how to notify LDK of chain activity using\nblocks. But what if you're sourcing chain activity from a place that doesn't\nprovide a block-centric interface, like Electrum?"},{name:"twitter:url",content:"https://lightningdevkit.org/blockchain_data/confirmed_transactions/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Lightning, LDK, Lightning Dev Kit, Documentation"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Lightning"},{property:"article:tag",content:"LDK"},{property:"article:tag",content:"Lightning Dev Kit"},{property:"article:tag",content:"Documentation"}]},regularPath:"/blockchain_data/confirmed_transactions.html",relativePath:"blockchain_data/confirmed_transactions.md",key:"v-7da54c6f",path:"/blockchain_data/confirmed_transactions/",codeSwitcherOptions:{},lastUpdated:"5/14/2024, 4:25:51 PM",lastUpdatedTimestamp:1715703951e3},{title:"Introduction",frontmatter:{meta:[{property:"og:site_name",content:"Lightning Dev Kit Documentation"},{property:"og:title",content:"Introduction"},{property:"og:description",content:"In this guide, we'll explore how to provide chain data to LDK upon startup and\nas new blocks are mined. This allows LDK to maintain channel state and monitor\nfor on-chain channel activity."},{property:"og:type",content:"article"},{property:"og:url",content:"https://lightningdevkit.org/blockchain_data/introduction/"},{property:"og:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:title",content:"Introduction"},{name:"twitter:description",content:"In this guide, we'll explore how to provide chain data to LDK upon startup and\nas new blocks are mined. This allows LDK to maintain channel state and monitor\nfor on-chain channel activity."},{name:"twitter:url",content:"https://lightningdevkit.org/blockchain_data/introduction/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Lightning, LDK, Lightning Dev Kit, Documentation"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Lightning"},{property:"article:tag",content:"LDK"},{property:"article:tag",content:"Lightning Dev Kit"},{property:"article:tag",content:"Documentation"}]},regularPath:"/blockchain_data/introduction.html",relativePath:"blockchain_data/introduction.md",key:"v-2f9b6cb6",path:"/blockchain_data/introduction/",headers:[{level:2,title:"Introduction",slug:"introduction"}],codeSwitcherOptions:{},lastUpdated:"5/14/2024, 4:25:51 PM",lastUpdatedTimestamp:1715703951e3},{title:"Pre-filtered Blocks",frontmatter:{meta:[{property:"og:site_name",content:"Lightning Dev Kit Documentation"},{property:"og:title",content:"Pre-filtered Blocks"},{property:"og:description",content:"For environments that are resource constrained, receiving and processing all\ntransaction data may not be feasible. LDK handles this case by signaling back\nwhich transactions and outputs it is interested in. This information can then be\nused to filter blocks prior to sending them to your node."},{property:"og:type",content:"article"},{property:"og:url",content:"https://lightningdevkit.org/blockchain_data/pre_filtered_blocks/"},{property:"og:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:title",content:"Pre-filtered Blocks"},{name:"twitter:description",content:"For environments that are resource constrained, receiving and processing all\ntransaction data may not be feasible. LDK handles this case by signaling back\nwhich transactions and outputs it is interested in. This information can then be\nused to filter blocks prior to sending them to your node."},{name:"twitter:url",content:"https://lightningdevkit.org/blockchain_data/pre_filtered_blocks/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Lightning, LDK, Lightning Dev Kit, Documentation"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Lightning"},{property:"article:tag",content:"LDK"},{property:"article:tag",content:"Lightning Dev Kit"},{property:"article:tag",content:"Documentation"}]},regularPath:"/blockchain_data/pre_filtered_blocks.html",relativePath:"blockchain_data/pre_filtered_blocks.md",key:"v-66b18f61",path:"/blockchain_data/pre_filtered_blocks/",codeSwitcherOptions:{},lastUpdated:"5/14/2024, 4:25:51 PM",lastUpdatedTimestamp:1715703951e3},{title:"Transaction Broadcasting",frontmatter:{meta:[{property:"og:site_name",content:"Lightning Dev Kit Documentation"},{property:"og:title",content:"Transaction Broadcasting"},{property:"og:description",content:"Inevitably, LDK will need to broadcast transactions on your behalf. As you\nnotify it of blocks, it will determine if it should broadcast a transaction and\ndo so using an implementation of `BroadcasterInterface` that you have provided."},{property:"og:type",content:"article"},{property:"og:url",content:"https://lightningdevkit.org/blockchain_data/transaction_broadcasting/"},{property:"og:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:title",content:"Transaction Broadcasting"},{name:"twitter:description",content:"Inevitably, LDK will need to broadcast transactions on your behalf. As you\nnotify it of blocks, it will determine if it should broadcast a transaction and\ndo so using an implementation of `BroadcasterInterface` that you have provided."},{name:"twitter:url",content:"https://lightningdevkit.org/blockchain_data/transaction_broadcasting/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Lightning, LDK, Lightning Dev Kit, Documentation"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Lightning"},{property:"article:tag",content:"LDK"},{property:"article:tag",content:"Lightning Dev Kit"},{property:"article:tag",content:"Documentation"}]},regularPath:"/blockchain_data/transaction_broadcasting.html",relativePath:"blockchain_data/transaction_broadcasting.md",key:"v-6b753255",path:"/blockchain_data/transaction_broadcasting/",codeSwitcherOptions:{},lastUpdated:"5/14/2024, 4:25:51 PM",lastUpdatedTimestamp:1715703951e3},{title:"Closing a Channel",frontmatter:{meta:[{property:"og:site_name",content:"Lightning Dev Kit Documentation"},{property:"og:title",content:"Closing a Channel"},{property:"og:description",content:"Begins the process of closing a channel. After this call plus some timeout, no new HTLCs will be accepted on the given channel, and after additional timeout/the closing of all pending HTLCs, the channel will be closed on chain."},{property:"og:type",content:"article"},{property:"og:url",content:"https://lightningdevkit.org/building-a-node-with-ldk/closing-a-channel/"},{property:"og:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:title",content:"Closing a Channel"},{name:"twitter:description",content:"Begins the process of closing a channel. After this call plus some timeout, no new HTLCs will be accepted on the given channel, and after additional timeout/the closing of all pending HTLCs, the channel will be closed on chain."},{name:"twitter:url",content:"https://lightningdevkit.org/building-a-node-with-ldk/closing-a-channel/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Lightning, LDK, Lightning Dev Kit, Documentation"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Lightning"},{property:"article:tag",content:"LDK"},{property:"article:tag",content:"Lightning Dev Kit"},{property:"article:tag",content:"Documentation"}]},regularPath:"/building-a-node-with-ldk/closing-a-channel.html",relativePath:"building-a-node-with-ldk/closing-a-channel.md",key:"v-0c8784ee",path:"/building-a-node-with-ldk/closing-a-channel/",codeSwitcherOptions:{},lastUpdated:"5/14/2024, 4:25:51 PM",lastUpdatedTimestamp:1715703951e3},{title:"Connect to Peers",frontmatter:{meta:[{property:"og:site_name",content:"Lightning Dev Kit Documentation"},{property:"og:title",content:"Connect to Peers"},{property:"og:description",content:"In this section you'll learn how to join the lightning network."},{property:"og:type",content:"article"},{property:"og:url",content:"https://lightningdevkit.org/building-a-node-with-ldk/connect-to-peers/"},{property:"og:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:title",content:"Connect to Peers"},{name:"twitter:description",content:"In this section you'll learn how to join the lightning network."},{name:"twitter:url",content:"https://lightningdevkit.org/building-a-node-with-ldk/connect-to-peers/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Lightning, LDK, Lightning Dev Kit, Documentation"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Lightning"},{property:"article:tag",content:"LDK"},{property:"article:tag",content:"Lightning Dev Kit"},{property:"article:tag",content:"Documentation"}]},regularPath:"/building-a-node-with-ldk/connect-to-peers.html",relativePath:"building-a-node-with-ldk/connect-to-peers.md",key:"v-2e33a981",path:"/building-a-node-with-ldk/connect-to-peers/",codeSwitcherOptions:{},lastUpdated:"5/14/2024, 4:25:51 PM",lastUpdatedTimestamp:1715703951e3},{title:"Handling Events",frontmatter:{meta:[{property:"og:site_name",content:"Lightning Dev Kit Documentation"},{property:"og:title",content:"Handling Events"},{property:"og:description",content:"LDK requires that you handle many different events throughout your app's life cycle. You can learn more by reading about our event-driven architecture/introduction/architecture.md."},{property:"og:type",content:"article"},{property:"og:url",content:"https://lightningdevkit.org/building-a-node-with-ldk/handling-events/"},{property:"og:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:title",content:"Handling Events"},{name:"twitter:description",content:"LDK requires that you handle many different events throughout your app's life cycle. You can learn more by reading about our event-driven architecture/introduction/architecture.md."},{name:"twitter:url",content:"https://lightningdevkit.org/building-a-node-with-ldk/handling-events/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Lightning, LDK, Lightning Dev Kit, Documentation"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Lightning"},{property:"article:tag",content:"LDK"},{property:"article:tag",content:"Lightning Dev Kit"},{property:"article:tag",content:"Documentation"}]},regularPath:"/building-a-node-with-ldk/handling-events.html",relativePath:"building-a-node-with-ldk/handling-events.md",key:"v-4215c085",path:"/building-a-node-with-ldk/handling-events/",codeSwitcherOptions:{},lastUpdated:"5/14/2024, 4:25:51 PM",lastUpdatedTimestamp:1715703951e3},{title:"Getting started",frontmatter:{meta:[{property:"og:site_name",content:"Lightning Dev Kit Documentation"},{property:"og:title",content:"Getting started"},{property:"og:description",content:"Welcome to the Lightning Development Kit documentation!"},{property:"og:type",content:"article"},{property:"og:url",content:"https://lightningdevkit.org/building-a-node-with-ldk/installation/"},{property:"og:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:title",content:"Getting started"},{name:"twitter:description",content:"Welcome to the Lightning Development Kit documentation!"},{name:"twitter:url",content:"https://lightningdevkit.org/building-a-node-with-ldk/installation/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Lightning, LDK, Lightning Dev Kit, Documentation"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Lightning"},{property:"article:tag",content:"LDK"},{property:"article:tag",content:"Lightning Dev Kit"},{property:"article:tag",content:"Documentation"}]},regularPath:"/building-a-node-with-ldk/installation.html",relativePath:"building-a-node-with-ldk/installation.md",key:"v-208c95fe",path:"/building-a-node-with-ldk/installation/",headers:[{level:2,title:"Installation",slug:"installation"}],codeSwitcherOptions:{},lastUpdated:"5/14/2024, 4:25:51 PM",lastUpdatedTimestamp:1715703951e3},{title:"Building a Node with LDK",frontmatter:{meta:[{property:"og:site_name",content:"Lightning Dev Kit Documentation"},{property:"og:title",content:"Building a Node with LDK"},{property:"og:description",content:"For an integrated example of an LDK node in Rust, see the Sample Nodehttps://github.com/lightningdevkit/ldk-sample"},{property:"og:type",content:"article"},{property:"og:url",content:"https://lightningdevkit.org/building-a-node-with-ldk/introduction/"},{property:"og:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:title",content:"Building a Node with LDK"},{name:"twitter:description",content:"For an integrated example of an LDK node in Rust, see the Sample Nodehttps://github.com/lightningdevkit/ldk-sample"},{name:"twitter:url",content:"https://lightningdevkit.org/building-a-node-with-ldk/introduction/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Lightning, LDK, Lightning Dev Kit, Documentation"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Lightning"},{property:"article:tag",content:"LDK"},{property:"article:tag",content:"Lightning Dev Kit"},{property:"article:tag",content:"Documentation"}]},regularPath:"/building-a-node-with-ldk/introduction.html",relativePath:"building-a-node-with-ldk/introduction.md",key:"v-4e009901",path:"/building-a-node-with-ldk/introduction/",headers:[{level:2,title:"Learn how to build a basic LDK node from scratch",slug:"learn-how-to-build-a-basic-ldk-node-from-scratch"},{level:3,title:"Foundational Components",slug:"foundational-components"}],codeSwitcherOptions:{},lastUpdated:"5/14/2024, 4:25:51 PM",lastUpdatedTimestamp:1715703951e3},{title:"Opening a Channel",frontmatter:{meta:[{property:"og:site_name",content:"Lightning Dev Kit Documentation"},{property:"og:title",content:"Opening a Channel"},{property:"og:description",content:"Channels are the basic building blocks of the Lightning Network. With channels, you can transact not only with your immediate peers but with others on the network. Let's explore how to open a channel with LDK."},{property:"og:type",content:"article"},{property:"og:url",content:"https://lightningdevkit.org/building-a-node-with-ldk/opening-a-channel/"},{property:"og:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:title",content:"Opening a Channel"},{name:"twitter:description",content:"Channels are the basic building blocks of the Lightning Network. With channels, you can transact not only with your immediate peers but with others on the network. Let's explore how to open a channel with LDK."},{name:"twitter:url",content:"https://lightningdevkit.org/building-a-node-with-ldk/opening-a-channel/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Lightning, LDK, Lightning Dev Kit, Documentation"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Lightning"},{property:"article:tag",content:"LDK"},{property:"article:tag",content:"Lightning Dev Kit"},{property:"article:tag",content:"Documentation"}]},regularPath:"/building-a-node-with-ldk/opening-a-channel.html",relativePath:"building-a-node-with-ldk/opening-a-channel.md",key:"v-f958b67a",path:"/building-a-node-with-ldk/opening-a-channel/",codeSwitcherOptions:{},lastUpdated:"5/14/2024, 4:25:51 PM",lastUpdatedTimestamp:1715703951e3},{title:"Receiving Payments",frontmatter:{meta:[{property:"og:site_name",content:"Lightning Dev Kit Documentation"},{property:"og:title",content:"Receiving Payments"},{property:"og:description",content:"To receive a payment, you'll need to create an invoice of your own with an\namount and description. `ChannelManager` contains the remaining information\nneeded for the invoice. Use the provided utility to generate an invoice and\nregister a pending payment in `ChannelManager`."},{property:"og:type",content:"article"},{property:"og:url",content:"https://lightningdevkit.org/building-a-node-with-ldk/receiving-payments/"},{property:"og:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:title",content:"Receiving Payments"},{name:"twitter:description",content:"To receive a payment, you'll need to create an invoice of your own with an\namount and description. `ChannelManager` contains the remaining information\nneeded for the invoice. Use the provided utility to generate an invoice and\nregister a pending payment in `ChannelManager`."},{name:"twitter:url",content:"https://lightningdevkit.org/building-a-node-with-ldk/receiving-payments/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Lightning, LDK, Lightning Dev Kit, Documentation"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Lightning"},{property:"article:tag",content:"LDK"},{property:"article:tag",content:"Lightning Dev Kit"},{property:"article:tag",content:"Documentation"}]},regularPath:"/building-a-node-with-ldk/receiving-payments.html",relativePath:"building-a-node-with-ldk/receiving-payments.md",key:"v-44e9497e",path:"/building-a-node-with-ldk/receiving-payments/",codeSwitcherOptions:{},lastUpdated:"5/14/2024, 4:25:51 PM",lastUpdatedTimestamp:1715703951e3},{title:"Setting up a ChannelManager",frontmatter:{meta:[{property:"og:site_name",content:"Lightning Dev Kit Documentation"},{property:"og:title",content:"Setting up a ChannelManager"},{property:"og:description",content:"The `ChannelManager` is responsible for several tasks related to managing channel state. This includes keeping track of many channels, sending messages to appropriate channels, creating channels and more."},{property:"og:type",content:"article"},{property:"og:url",content:"https://lightningdevkit.org/building-a-node-with-ldk/setting-up-a-channel-manager/"},{property:"og:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:title",content:"Setting up a ChannelManager"},{name:"twitter:description",content:"The `ChannelManager` is responsible for several tasks related to managing channel state. This includes keeping track of many channels, sending messages to appropriate channels, creating channels and more."},{name:"twitter:url",content:"https://lightningdevkit.org/building-a-node-with-ldk/setting-up-a-channel-manager/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Lightning, LDK, Lightning Dev Kit, Documentation"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Lightning"},{property:"article:tag",content:"LDK"},{property:"article:tag",content:"Lightning Dev Kit"},{property:"article:tag",content:"Documentation"}]},regularPath:"/building-a-node-with-ldk/setting-up-a-channel-manager.html",relativePath:"building-a-node-with-ldk/setting-up-a-channel-manager.md",key:"v-3cfeb3fe",path:"/building-a-node-with-ldk/setting-up-a-channel-manager/",headers:[{level:2,title:"Adding a ChannelManager",slug:"adding-a-channelmanager"},{level:3,title:"Initialize the FeeEstimator",slug:"initialize-the-feeestimator"},{level:3,title:"Initialize the Router",slug:"initialize-the-router"},{level:3,title:"Initialize the Logger",slug:"initialize-the-logger"},{level:3,title:"Initialize the BroadcasterInterface",slug:"initialize-the-broadcasterinterface"},{level:3,title:"Initialize Persist",slug:"initialize-persist"},{level:3,title:"Start Background Processing",slug:"start-background-processing"},{level:3,title:"Regularly Broadcast Node Announcement",slug:"regularly-broadcast-node-announcement"},{level:3,title:"Optional: Initialize the Transaction Filter",slug:"optional-initialize-the-transaction-filter"},{level:3,title:"Initialize the ChainMonitor",slug:"initialize-the-chainmonitor"},{level:3,title:"Initialize the KeysManager",slug:"initialize-the-keysmanager"},{level:3,title:"Read ChannelMonitor state from disk",slug:"read-channelmonitor-state-from-disk"},{level:3,title:"Initialize the ChannelManager",slug:"initialize-the-channelmanager"},{level:3,title:"Sync ChannelMonitors and ChannelManager to chain tip",slug:"sync-channelmonitors-and-channelmanager-to-chain-tip"},{level:3,title:"Optional: Initialize P2PGossipSync or RapidGossipSync",slug:"optional-initialize-p2pgossipsync-or-rapidgossipsync"},{level:3,title:"Optional: Initialize Probabilistic Scorer",slug:"optional-initialize-probabilistic-scorer"}],codeSwitcherOptions:{},lastUpdated:"5/14/2024, 4:25:51 PM",lastUpdatedTimestamp:1715703951e3},{title:"Setting up a PeerManager",frontmatter:{meta:[{property:"og:site_name",content:"Lightning Dev Kit Documentation"},{property:"og:title",content:"Setting up a PeerManager"},{property:"og:description",content:"The `PeerManager` is responsible for managing a set of peer connections and data associated with those peers."},{property:"og:type",content:"article"},{property:"og:url",content:"https://lightningdevkit.org/building-a-node-with-ldk/setting-up-a-peer-manager/"},{property:"og:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:title",content:"Setting up a PeerManager"},{name:"twitter:description",content:"The `PeerManager` is responsible for managing a set of peer connections and data associated with those peers."},{name:"twitter:url",content:"https://lightningdevkit.org/building-a-node-with-ldk/setting-up-a-peer-manager/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Lightning, LDK, Lightning Dev Kit, Documentation"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Lightning"},{property:"article:tag",content:"LDK"},{property:"article:tag",content:"Lightning Dev Kit"},{property:"article:tag",content:"Documentation"}]},regularPath:"/building-a-node-with-ldk/setting-up-a-peer-manager.html",relativePath:"building-a-node-with-ldk/setting-up-a-peer-manager.md",key:"v-f0ae247e",path:"/building-a-node-with-ldk/setting-up-a-peer-manager/",headers:[{level:2,title:"Adding a PeerManager",slug:"adding-a-peermanager"}],codeSwitcherOptions:{},lastUpdated:"5/14/2024, 4:25:51 PM",lastUpdatedTimestamp:1715703951e3},{title:"Sending Payments",frontmatter:{meta:[{property:"og:site_name",content:"Lightning Dev Kit Documentation"},{property:"og:title",content:"Sending Payments"},{property:"og:description",content:"Lightning payments are used to pay invoices, which are typically encoded as a\nstring in accordance with BOLT 11. After parsing the invoice, you'll need to\nfind a route from your node to the recipient and then make the payment using"},{property:"og:type",content:"article"},{property:"og:url",content:"https://lightningdevkit.org/building-a-node-with-ldk/sending-payments/"},{property:"og:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:title",content:"Sending Payments"},{name:"twitter:description",content:"Lightning payments are used to pay invoices, which are typically encoded as a\nstring in accordance with BOLT 11. After parsing the invoice, you'll need to\nfind a route from your node to the recipient and then make the payment using"},{name:"twitter:url",content:"https://lightningdevkit.org/building-a-node-with-ldk/sending-payments/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Lightning, LDK, Lightning Dev Kit, Documentation"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Lightning"},{property:"article:tag",content:"LDK"},{property:"article:tag",content:"Lightning Dev Kit"},{property:"article:tag",content:"Documentation"}]},regularPath:"/building-a-node-with-ldk/sending-payments.html",relativePath:"building-a-node-with-ldk/sending-payments.md",key:"v-1f59967e",path:"/building-a-node-with-ldk/sending-payments/",codeSwitcherOptions:{},lastUpdated:"5/14/2024, 4:25:51 PM",lastUpdatedTimestamp:1715703951e3},{frontmatter:{cases:!0,sidebar:!1,tagline:"Bitcoin applications building with LDK",description:"A list of bitcoin applications and services building with LDK",actionText:"Add your project",actionLink:"https://github.com/orgs/lightningdevkit/discussions/1554",features:[{title:"Mutiny",details:"A self-custodial lightning wallet that runs in the browser",image:"/img/mutiny-featured.png",imageAlt:"mutiny logo",caseStudyLink:"/blog/mutiny-uses-ldk-the-first-lightning-wallet-for-the-web/"},{title:"Cash App",details:"Send and spend, bank, and buy stocks or bitcoin ",image:"/img/cash-app-logo.png",imageAlt:"cash app logo",caseStudyLink:"/blog/cashapp-enables-lightning-withdrawals-and-deposits-using-ldk/"},{title:"Bitkit",details:"Bitkit hands you the keys to your money, profile, contacts, and web accounts",image:"/img/bitkit.svg",imageAlt:"",caseStudyLink:"/blog/bitkit-uses-ldk-to-build-the-ultimate-alternative-to-custodial-wallets/"}],editLink:!1,lastUpdated:!1,meta:[{property:"og:site_name",content:"Lightning Dev Kit Documentation"},{property:"og:title",content:"Bitcoin applications building with LDK"},{property:"og:description",content:"A list of bitcoin applications and services building with LDK"},{property:"og:type",content:"article"},{property:"og:url",content:"https://lightningdevkit.org/case-studies/"},{property:"og:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:title",content:"Bitcoin applications building with LDK"},{name:"twitter:description",content:"A list of bitcoin applications and services building with LDK"},{name:"twitter:url",content:"https://lightningdevkit.org/case-studies/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Lightning, LDK, Lightning Dev Kit, Documentation"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Lightning"},{property:"article:tag",content:"LDK"},{property:"article:tag",content:"Lightning Dev Kit"},{property:"article:tag",content:"Documentation"}]},regularPath:"/case-studies.html",relativePath:"case-studies.md",key:"v-1df9ba79",path:"/case-studies/",codeSwitcherOptions:{},lastUpdated:"5/14/2024, 4:25:51 PM",lastUpdatedTimestamp:1715703951e3},{title:"LDK Code of Conduct",frontmatter:{meta:[{property:"og:site_name",content:"Lightning Dev Kit Documentation"},{property:"og:title",content:"LDK Code of Conduct"},{property:"og:description",content:"The LDK community is open to pretty much anyone. To ensure that project forums such as the Discord server and GitHub repository are open and friendly, we count on maintainers and project representatives to behave in a way that is not disruptive to LDK's culture or to any one participant's well-being."},{property:"og:type",content:"article"},{property:"og:url",content:"https://lightningdevkit.org/code_of_conduct/"},{property:"og:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:title",content:"LDK Code of Conduct"},{name:"twitter:description",content:"The LDK community is open to pretty much anyone. To ensure that project forums such as the Discord server and GitHub repository are open and friendly, we count on maintainers and project representatives to behave in a way that is not disruptive to LDK's culture or to any one participant's well-being."},{name:"twitter:url",content:"https://lightningdevkit.org/code_of_conduct/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Lightning, LDK, Lightning Dev Kit, Documentation"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Lightning"},{property:"article:tag",content:"LDK"},{property:"article:tag",content:"Lightning Dev Kit"},{property:"article:tag",content:"Documentation"}]},regularPath:"/code_of_conduct.html",relativePath:"code_of_conduct.md",key:"v-acaf8bbe",path:"/code_of_conduct/",headers:[{level:2,title:"The Code of Conduct Team",slug:"the-code-of-conduct-team"},{level:2,title:"The Code of Conduct Team’s Responsibilities",slug:"the-code-of-conduct-team-s-responsibilities"},{level:2,title:"Possible responses to an incident include:",slug:"possible-responses-to-an-incident-include"},{level:3,title:"Taking no further action:",slug:"taking-no-further-action"},{level:3,title:"Simple warning:",slug:"simple-warning"},{level:3,title:"Final warning:",slug:"final-warning"},{level:3,title:"2-3 months imposed break:",slug:"2-3-months-imposed-break"},{level:3,title:"Extended or permanent ban:",slug:"extended-or-permanent-ban"}],codeSwitcherOptions:{},lastUpdated:"5/14/2024, 4:25:51 PM",lastUpdatedTimestamp:1715703951e3},{title:"Examples",frontmatter:{meta:[{property:"og:site_name",content:"Lightning Dev Kit Documentation"},{property:"og:title",content:"Examples"},{property:"og:description",content:"Click the links below and learn from community-built example projects"},{property:"og:type",content:"article"},{property:"og:url",content:"https://lightningdevkit.org/examples/"},{property:"og:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:title",content:"Examples"},{name:"twitter:description",content:"Click the links below and learn from community-built example projects"},{name:"twitter:url",content:"https://lightningdevkit.org/examples/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Lightning, LDK, Lightning Dev Kit, Documentation"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Lightning"},{property:"article:tag",content:"LDK"},{property:"article:tag",content:"Lightning Dev Kit"},{property:"article:tag",content:"Documentation"}]},regularPath:"/examples.html",relativePath:"examples.md",key:"v-5e36ef8a",path:"/examples/",headers:[{level:3,title:"Rust Sample Node",slug:"rust-sample-node"},{level:3,title:"Kotlin/Android Sample App",slug:"kotlinandroid-sample-app"},{level:3,title:"Swift/iOS Sample App",slug:"swiftios-sample-app"},{level:3,title:"Rust node with sample Lightning Signer integration",slug:"rust-node-with-sample-lightning-signer-integration"},{level:3,title:"Rust node with sample Tor integration",slug:"rust-node-with-sample-tor-integration"},{level:3,title:"LDK Node",slug:"ldk-node"},{level:3,title:"LDK Node Rust Sample",slug:"ldk-node-rust-sample"},{level:3,title:"LDK Node Swift Sample App",slug:"ldk-node-swift-sample-app"},{level:3,title:"LDK Node Swift Sample app using Bitcoin Design Guide",slug:"ldk-node-swift-sample-app-using-bitcoin-design-guide"},{level:3,title:"LDK Node Flutter Sample App",slug:"ldk-node-flutter-sample-app"},{level:3,title:"LDK Node React Native Sample App",slug:"ldk-node-react-native-sample-app"},{level:3,title:"LDK Node Sample Desktop App",slug:"ldk-node-sample-desktop-app"}],codeSwitcherOptions:{},lastUpdated:"5/14/2024, 4:25:51 PM",lastUpdatedTimestamp:1715703951e3},{title:"Home",frontmatter:{home:!0,heroText:"Build Lightning applications your way with LDK",tagline:"A complete Lightning implementation packaged as an SDK",actionText:"Get started",actionLink:"/introduction/",features:[{title:"Flexible and customizable ",details:"Persistence. Networking. Chain sourcing. Routing. Key management. You name it. LDK easily configures to your application’s needs.",image:"customizable"},{title:"High performance",details:"As lightweight and compact as you need it to be, LDK performs on small-footprint devices and scales in the cloud.",image:"focus"},{title:"Any language, any platform",details:"LDK provides a multi-language native API. Run a Lightning node on mobile, web, HSMs, LSPs, or your existing infrastructure.",image:"mobile"}],promo:!0,promoImage:"ldk-node",promoTitle:"LDK Node",promoDescription:"Build a mobile Lightning wallet fast with our ready-to-go solution",promoActionText:"Get Started",promoActionLink:"https://docs.rs/ldk-node/*/ldk_node/",meta:[{property:"og:site_name",content:"Lightning Dev Kit Documentation"},{property:"og:title",content:"A complete Lightning implementation packaged as an SDK"},{property:"og:type",content:"article"},{property:"og:url",content:"https://lightningdevkit.org/"},{property:"og:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:title",content:"A complete Lightning implementation packaged as an SDK"},{name:"twitter:url",content:"https://lightningdevkit.org/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Lightning, LDK, Lightning Dev Kit, Documentation"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Lightning"},{property:"article:tag",content:"LDK"},{property:"article:tag",content:"Lightning Dev Kit"},{property:"article:tag",content:"Documentation"}]},regularPath:"/",relativePath:"index.md",key:"v-197bd04c",path:"/",codeSwitcherOptions:{},lastUpdated:"5/14/2024, 4:25:51 PM",lastUpdatedTimestamp:1715703951e3},{title:"Architecture",frontmatter:{meta:[{property:"og:site_name",content:"Lightning Dev Kit Documentation"},{property:"og:title",content:"Architecture"},{property:"og:description",content:"Firstly, LDK is not a daemon, but rather its own implementation of the Lightning protocol written as an SDK and designed to be compiled and executed in your application. "},{property:"og:type",content:"article"},{property:"og:url",content:"https://lightningdevkit.org/introduction/architecture/"},{property:"og:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:title",content:"Architecture"},{name:"twitter:description",content:"Firstly, LDK is not a daemon, but rather its own implementation of the Lightning protocol written as an SDK and designed to be compiled and executed in your application. "},{name:"twitter:url",content:"https://lightningdevkit.org/introduction/architecture/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Lightning, LDK, Lightning Dev Kit, Documentation"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Lightning"},{property:"article:tag",content:"LDK"},{property:"article:tag",content:"Lightning Dev Kit"},{property:"article:tag",content:"Documentation"}]},regularPath:"/introduction/architecture.html",relativePath:"introduction/architecture.md",key:"v-d599223e",path:"/introduction/architecture/",codeSwitcherOptions:{},lastUpdated:"5/14/2024, 4:25:51 PM",lastUpdatedTimestamp:1715703951e3},{title:"Blockchain Data",frontmatter:{meta:[{property:"og:site_name",content:"Lightning Dev Kit Documentation"},{property:"og:title",content:"Blockchain Data"},{property:"og:description",content:"LDK provides a simple `blockconnected`/`blockdisconnected` API which you pass block headers and transaction information to. LDK also provides an API for getting information about transactions it wishes to be informed of, which is compatible with Electrum server requests/neutrino filtering/etc."},{property:"og:type",content:"article"},{property:"og:url",content:"https://lightningdevkit.org/introduction/blockchain_data/"},{property:"og:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:title",content:"Blockchain Data"},{name:"twitter:description",content:"LDK provides a simple `blockconnected`/`blockdisconnected` API which you pass block headers and transaction information to. LDK also provides an API for getting information about transactions it wishes to be informed of, which is compatible with Electrum server requests/neutrino filtering/etc."},{name:"twitter:url",content:"https://lightningdevkit.org/introduction/blockchain_data/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Lightning, LDK, Lightning Dev Kit, Documentation"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Lightning"},{property:"article:tag",content:"LDK"},{property:"article:tag",content:"Lightning Dev Kit"},{property:"article:tag",content:"Documentation"}]},regularPath:"/introduction/blockchain_data.html",relativePath:"introduction/blockchain_data.md",key:"v-7495ad8d",path:"/introduction/blockchain_data/",codeSwitcherOptions:{},lastUpdated:"5/14/2024, 4:25:51 PM",lastUpdatedTimestamp:1715703951e3},{title:"Introduction",frontmatter:{meta:[{property:"og:site_name",content:"Lightning Dev Kit Documentation"},{property:"og:title",content:"Introduction"},{property:"og:description",content:"Lightning Development Kit LDK is a full and completely standalone Lightning implementation with supporting modules enabling greater flexibility."},{property:"og:type",content:"article"},{property:"og:url",content:"https://lightningdevkit.org/introduction/"},{property:"og:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:title",content:"Introduction"},{name:"twitter:description",content:"Lightning Development Kit LDK is a full and completely standalone Lightning implementation with supporting modules enabling greater flexibility."},{name:"twitter:url",content:"https://lightningdevkit.org/introduction/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Lightning, LDK, Lightning Dev Kit, Documentation"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Lightning"},{property:"article:tag",content:"LDK"},{property:"article:tag",content:"Lightning Dev Kit"},{property:"article:tag",content:"Documentation"}]},regularPath:"/introduction/",relativePath:"introduction/index.md",key:"v-2615480c",path:"/introduction/",headers:[{level:2,title:"References",slug:"references"},{level:3,title:"Rust Documentation",slug:"rust-documentation"},{level:3,title:"Swift LDK Documentation",slug:"swift-ldk-documentation"},{level:3,title:"Rust Sample Node",slug:"rust-sample-node"},{level:3,title:"Architecture",slug:"architecture"}],codeSwitcherOptions:{},lastUpdated:"5/14/2024, 4:25:51 PM",lastUpdatedTimestamp:1715703951e3},{title:"Networking",frontmatter:{meta:[{property:"og:site_name",content:"Lightning Dev Kit Documentation"},{property:"og:title",content:"Networking"},{property:"og:description",content:"To enable you to run a full Lightning node on an embedded machine, LDK doesn't specify exactly how to connect to another node at all! The default implementation uses TCP sockets, but, e.g., if you wanted to run your full Lightning node on a hardware wallet, you could, by piping the Lightning network messages over USB/serial and then sending them in a TCP socket from another machine."},{property:"og:type",content:"article"},{property:"og:url",content:"https://lightningdevkit.org/introduction/networking/"},{property:"og:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:title",content:"Networking"},{name:"twitter:description",content:"To enable you to run a full Lightning node on an embedded machine, LDK doesn't specify exactly how to connect to another node at all! The default implementation uses TCP sockets, but, e.g., if you wanted to run your full Lightning node on a hardware wallet, you could, by piping the Lightning network messages over USB/serial and then sending them in a TCP socket from another machine."},{name:"twitter:url",content:"https://lightningdevkit.org/introduction/networking/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Lightning, LDK, Lightning Dev Kit, Documentation"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Lightning"},{property:"article:tag",content:"LDK"},{property:"article:tag",content:"Lightning Dev Kit"},{property:"article:tag",content:"Documentation"}]},regularPath:"/introduction/networking.html",relativePath:"introduction/networking.md",key:"v-2c8ce301",path:"/introduction/networking/",codeSwitcherOptions:{},lastUpdated:"5/14/2024, 4:25:51 PM",lastUpdatedTimestamp:1715703951e3},{title:"Persistent Storage",frontmatter:{meta:[{property:"og:site_name",content:"Lightning Dev Kit Documentation"},{property:"og:title",content:"Persistent Storage"},{property:"og:description",content:"You can store the channel state any way you want - whether Google Drive/iCloud, a local disk, any key-value store/database/a remote server, or any combination of them - LDK provides a clean API, where objects can be serialized into simple binary blobs, and stored in any way you wish."},{property:"og:type",content:"article"},{property:"og:url",content:"https://lightningdevkit.org/introduction/persistent_storage/"},{property:"og:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:title",content:"Persistent Storage"},{name:"twitter:description",content:"You can store the channel state any way you want - whether Google Drive/iCloud, a local disk, any key-value store/database/a remote server, or any combination of them - LDK provides a clean API, where objects can be serialized into simple binary blobs, and stored in any way you wish."},{name:"twitter:url",content:"https://lightningdevkit.org/introduction/persistent_storage/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Lightning, LDK, Lightning Dev Kit, Documentation"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Lightning"},{property:"article:tag",content:"LDK"},{property:"article:tag",content:"Lightning Dev Kit"},{property:"article:tag",content:"Documentation"}]},regularPath:"/introduction/persistent_storage.html",relativePath:"introduction/persistent_storage.md",key:"v-6f688c61",path:"/introduction/persistent_storage/",codeSwitcherOptions:{},lastUpdated:"5/14/2024, 4:25:51 PM",lastUpdatedTimestamp:1715703951e3},{title:"Peer Management",frontmatter:{meta:[{property:"og:site_name",content:"Lightning Dev Kit Documentation"},{property:"og:title",content:"Peer Management"},{property:"og:description",content:"One of the first things you'll need to do when building your own Lightning node is connect to a peer. In LDK this is handled by the `PeerManager`https://docs.rs/lightning//lightning/ln/peerhandler/struct.PeerManager.html."},{property:"og:type",content:"article"},{property:"og:url",content:"https://lightningdevkit.org/introduction/peer-management/"},{property:"og:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:title",content:"Peer Management"},{name:"twitter:description",content:"One of the first things you'll need to do when building your own Lightning node is connect to a peer. In LDK this is handled by the `PeerManager`https://docs.rs/lightning//lightning/ln/peerhandler/struct.PeerManager.html."},{name:"twitter:url",content:"https://lightningdevkit.org/introduction/peer-management/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Lightning, LDK, Lightning Dev Kit, Documentation"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Lightning"},{property:"article:tag",content:"LDK"},{property:"article:tag",content:"Lightning Dev Kit"},{property:"article:tag",content:"Documentation"}]},regularPath:"/introduction/peer-management.html",relativePath:"introduction/peer-management.md",key:"v-9b98f9ca",path:"/introduction/peer-management/",codeSwitcherOptions:{},lastUpdated:"5/14/2024, 4:25:51 PM",lastUpdatedTimestamp:1715703951e3},{title:"Private Key Management",frontmatter:{meta:[{property:"og:site_name",content:"Lightning Dev Kit Documentation"},{property:"og:title",content:"Private Key Management"},{property:"og:description",content:"LDK provides a default implementation for key management, but you can choose to provide private keys to LDK in any way you wish following a simple API. LDK even supports a generic API for signing transactions, allowing you to run LDK without any private keys in memory and/or putting private keys only on hardware wallets."},{property:"og:type",content:"article"},{property:"og:url",content:"https://lightningdevkit.org/introduction/private_key_management/"},{property:"og:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:title",content:"Private Key Management"},{name:"twitter:description",content:"LDK provides a default implementation for key management, but you can choose to provide private keys to LDK in any way you wish following a simple API. LDK even supports a generic API for signing transactions, allowing you to run LDK without any private keys in memory and/or putting private keys only on hardware wallets."},{name:"twitter:url",content:"https://lightningdevkit.org/introduction/private_key_management/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Lightning, LDK, Lightning Dev Kit, Documentation"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Lightning"},{property:"article:tag",content:"LDK"},{property:"article:tag",content:"Lightning Dev Kit"},{property:"article:tag",content:"Documentation"}]},regularPath:"/introduction/private_key_management.html",relativePath:"introduction/private_key_management.md",key:"v-73ba0ae1",path:"/introduction/private_key_management/",codeSwitcherOptions:{},lastUpdated:"5/14/2024, 4:25:51 PM",lastUpdatedTimestamp:1715703951e3},{title:"Random Number Generation",frontmatter:{meta:[{property:"og:site_name",content:"Lightning Dev Kit Documentation"},{property:"og:title",content:"Random Number Generation"},{property:"og:description",content:"LDK aims to make no system calls, it is therefore restricted from generating its own randomness."},{property:"og:type",content:"article"},{property:"og:url",content:"https://lightningdevkit.org/introduction/random_number_generation/"},{property:"og:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:title",content:"Random Number Generation"},{name:"twitter:description",content:"LDK aims to make no system calls, it is therefore restricted from generating its own randomness."},{name:"twitter:url",content:"https://lightningdevkit.org/introduction/random_number_generation/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Lightning, LDK, Lightning Dev Kit, Documentation"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Lightning"},{property:"article:tag",content:"LDK"},{property:"article:tag",content:"Lightning Dev Kit"},{property:"article:tag",content:"Documentation"}]},regularPath:"/introduction/random_number_generation.html",relativePath:"introduction/random_number_generation.md",key:"v-0a5ecb01",path:"/introduction/random_number_generation/",codeSwitcherOptions:{},lastUpdated:"5/14/2024, 4:25:51 PM",lastUpdatedTimestamp:1715703951e3},{title:"Transactions",frontmatter:{meta:[{property:"og:site_name",content:"Lightning Dev Kit Documentation"},{property:"og:title",content:"Transactions"},{property:"og:description",content:"Clients running a light client may wish to filter for transactions on a separate server, in which case LDK will tell them about transactions to filter for. "},{property:"og:type",content:"article"},{property:"og:url",content:"https://lightningdevkit.org/introduction/transactions/"},{property:"og:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:title",content:"Transactions"},{name:"twitter:description",content:"Clients running a light client may wish to filter for transactions on a separate server, in which case LDK will tell them about transactions to filter for. "},{name:"twitter:url",content:"https://lightningdevkit.org/introduction/transactions/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Lightning, LDK, Lightning Dev Kit, Documentation"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Lightning"},{property:"article:tag",content:"LDK"},{property:"article:tag",content:"Lightning Dev Kit"},{property:"article:tag",content:"Documentation"}]},regularPath:"/introduction/transactions.html",relativePath:"introduction/transactions.md",key:"v-8b8ac0be",path:"/introduction/transactions/",headers:[{level:2,title:"Transaction Filtering",slug:"transaction-filtering"},{level:2,title:"Fee Estimation",slug:"fee-estimation"},{level:2,title:"Transaction Broadcasting",slug:"transaction-broadcasting"}],codeSwitcherOptions:{},lastUpdated:"5/14/2024, 4:25:51 PM",lastUpdatedTimestamp:1715703951e3},{title:"Use Cases for LDK",frontmatter:{meta:[{property:"og:site_name",content:"Lightning Dev Kit Documentation"},{property:"og:title",content:"Use Cases for LDK"},{property:"og:description",content:"The standard Lightning use case is running a standalone node on one's laptop.\nHere's some other use cases that LDK supports."},{property:"og:type",content:"article"},{property:"og:url",content:"https://lightningdevkit.org/introduction/use-cases/"},{property:"og:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:title",content:"Use Cases for LDK"},{name:"twitter:description",content:"The standard Lightning use case is running a standalone node on one's laptop.\nHere's some other use cases that LDK supports."},{name:"twitter:url",content:"https://lightningdevkit.org/introduction/use-cases/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Lightning, LDK, Lightning Dev Kit, Documentation"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Lightning"},{property:"article:tag",content:"LDK"},{property:"article:tag",content:"Lightning Dev Kit"},{property:"article:tag",content:"Documentation"}]},regularPath:"/introduction/use-cases.html",relativePath:"introduction/use-cases.md",key:"v-2e6cd4fd",path:"/introduction/use-cases/",headers:[{level:2,title:"Mobile Devices",slug:"mobile-devices"},{level:2,title:"HSMs (Hardware Security Modules)",slug:"hsms-hardware-security-modules"},{level:2,title:"Production Lightning Nodes",slug:"production-lightning-nodes"}],codeSwitcherOptions:{},lastUpdated:"5/14/2024, 4:25:51 PM",lastUpdatedTimestamp:1715703951e3},{title:"Wallet Management",frontmatter:{meta:[{property:"og:site_name",content:"Lightning Dev Kit Documentation"},{property:"og:title",content:"Wallet Management"},{property:"og:description",content:'LDK owns on-chain funds as long as they are claimable as a part of a Lightning output which can be contested - once a channel is closed and all on-chain outputs are spendable only by you, LDK provides you notifications that a UTXO is "yours" again and it is up to you to spend it as you wish. '},{property:"og:type",content:"article"},{property:"og:url",content:"https://lightningdevkit.org/introduction/wallet_management/"},{property:"og:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:title",content:"Wallet Management"},{name:"twitter:description",content:'LDK owns on-chain funds as long as they are claimable as a part of a Lightning output which can be contested - once a channel is closed and all on-chain outputs are spendable only by you, LDK provides you notifications that a UTXO is "yours" again and it is up to you to spend it as you wish. '},{name:"twitter:url",content:"https://lightningdevkit.org/introduction/wallet_management/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Lightning, LDK, Lightning Dev Kit, Documentation"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Lightning"},{property:"article:tag",content:"LDK"},{property:"article:tag",content:"Lightning Dev Kit"},{property:"article:tag",content:"Documentation"}]},regularPath:"/introduction/wallet_management.html",relativePath:"introduction/wallet_management.md",key:"v-c4171d36",path:"/introduction/wallet_management/",codeSwitcherOptions:{},lastUpdated:"5/14/2024, 4:25:51 PM",lastUpdatedTimestamp:1715703951e3},{title:"Language Bindings",frontmatter:{meta:[{property:"og:site_name",content:"Lightning Dev Kit Documentation"},{property:"og:title",content:"Language Bindings"},{property:"og:description",content:"TODO"},{property:"og:type",content:"article"},{property:"og:url",content:"https://lightningdevkit.org/language_bindings/"},{property:"og:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:title",content:"Language Bindings"},{name:"twitter:description",content:"TODO"},{name:"twitter:url",content:"https://lightningdevkit.org/language_bindings/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Lightning, LDK, Lightning Dev Kit, Documentation"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Lightning"},{property:"article:tag",content:"LDK"},{property:"article:tag",content:"Lightning Dev Kit"},{property:"article:tag",content:"Documentation"}]},regularPath:"/language_bindings.html",relativePath:"language_bindings.md",key:"v-21d81ac1",path:"/language_bindings/",codeSwitcherOptions:{},lastUpdated:"5/14/2024, 4:25:51 PM",lastUpdatedTimestamp:1715703951e3},{title:"Key Management",frontmatter:{meta:[{property:"og:site_name",content:"Lightning Dev Kit Documentation"},{property:"og:title",content:"Key Management"},{property:"og:description",content:"LDK provides a simple default `KeysManager` implementation that takes a 32-byte seed for use as a BIP 32 extended key and derives keys from that. Check out the Rust docshttps://docs.rs/lightning//lightning/sign/struct.KeysManager.html."},{property:"og:type",content:"article"},{property:"og:url",content:"https://lightningdevkit.org/key_management/"},{property:"og:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:title",content:"Key Management"},{name:"twitter:description",content:"LDK provides a simple default `KeysManager` implementation that takes a 32-byte seed for use as a BIP 32 extended key and derives keys from that. Check out the Rust docshttps://docs.rs/lightning//lightning/sign/struct.KeysManager.html."},{name:"twitter:url",content:"https://lightningdevkit.org/key_management/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Lightning, LDK, Lightning Dev Kit, Documentation"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Lightning"},{property:"article:tag",content:"LDK"},{property:"article:tag",content:"Lightning Dev Kit"},{property:"article:tag",content:"Documentation"}]},regularPath:"/key_management.html",relativePath:"key_management.md",key:"v-50f91cc7",path:"/key_management/",codeSwitcherOptions:{},lastUpdated:"5/14/2024, 4:25:51 PM",lastUpdatedTimestamp:1715703951e3},{title:"Data Persistence",frontmatter:{meta:[{property:"og:site_name",content:"Lightning Dev Kit Documentation"},{property:"og:title",content:"Data Persistence"},{property:"og:description",content:"TODO"},{property:"og:type",content:"article"},{property:"og:url",content:"https://lightningdevkit.org/persist/"},{property:"og:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:title",content:"Data Persistence"},{name:"twitter:description",content:"TODO"},{name:"twitter:url",content:"https://lightningdevkit.org/persist/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Lightning, LDK, Lightning Dev Kit, Documentation"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Lightning"},{property:"article:tag",content:"LDK"},{property:"article:tag",content:"Lightning Dev Kit"},{property:"article:tag",content:"Documentation"}]},regularPath:"/persist.html",relativePath:"persist.md",key:"v-102e5c3e",path:"/persist/",codeSwitcherOptions:{},lastUpdated:"5/14/2024, 4:25:51 PM",lastUpdatedTimestamp:1715703951e3},{title:"Running a sample LDK node",frontmatter:{meta:[{property:"og:site_name",content:"Lightning Dev Kit Documentation"},{property:"og:title",content:"Running a sample LDK node"},{property:"og:description",content:"Let's run our first LDK node. We'll ensure we have a compatible Rust toolchain installed, setup Polar to create a local Lightning network and then start running the node."},{property:"og:type",content:"article"},{property:"og:url",content:"https://lightningdevkit.org/running-a-sample-ldk-node/"},{property:"og:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:title",content:"Running a sample LDK node"},{name:"twitter:description",content:"Let's run our first LDK node. We'll ensure we have a compatible Rust toolchain installed, setup Polar to create a local Lightning network and then start running the node."},{name:"twitter:url",content:"https://lightningdevkit.org/running-a-sample-ldk-node/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Lightning, LDK, Lightning Dev Kit, Documentation"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Lightning"},{property:"article:tag",content:"LDK"},{property:"article:tag",content:"Lightning Dev Kit"},{property:"article:tag",content:"Documentation"}]},regularPath:"/running-a-sample-ldk-node.html",relativePath:"running-a-sample-ldk-node.md",key:"v-1d645dc1",path:"/running-a-sample-ldk-node/",headers:[{level:2,title:"Installing Rust",slug:"installing-rust"},{level:2,title:"Setup Polar",slug:"setup-polar"},{level:2,title:"Running the LDK Sample Node",slug:"running-the-ldk-sample-node"}],codeSwitcherOptions:{},lastUpdated:"5/14/2024, 4:25:51 PM",lastUpdatedTimestamp:1715703951e3},{frontmatter:{layout:"IndexPost",title:"Blog",meta:[{property:"og:site_name",content:"Lightning Dev Kit Documentation"},{property:"og:type",content:"article"},{property:"og:url",content:"https://lightningdevkit.org/blog/"},{property:"og:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:url",content:"https://lightningdevkit.org/blog/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Lightning, LDK, Lightning Dev Kit, Documentation"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Lightning"},{property:"article:tag",content:"LDK"},{property:"article:tag",content:"Lightning Dev Kit"},{property:"article:tag",content:"Documentation"}]},regularPath:"/blog/",key:"v-424df898",path:"/blog/",codeSwitcherOptions:{}},{frontmatter:{layout:"FrontmatterKey",title:"Tags",meta:[{property:"og:site_name",content:"Lightning Dev Kit Documentation"},{property:"og:type",content:"article"},{property:"og:url",content:"https://lightningdevkit.org/blog/tags/"},{property:"og:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:url",content:"https://lightningdevkit.org/blog/tags/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Lightning, LDK, Lightning Dev Kit, Documentation"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Lightning"},{property:"article:tag",content:"LDK"},{property:"article:tag",content:"Lightning Dev Kit"},{property:"article:tag",content:"Documentation"}]},regularPath:"/blog/tags/",key:"v-619df59e",path:"/blog/tags/",codeSwitcherOptions:{}},{frontmatter:{layout:"FrontmatterKey",title:"Authors",meta:[{property:"og:site_name",content:"Lightning Dev Kit Documentation"},{property:"og:type",content:"article"},{property:"og:url",content:"https://lightningdevkit.org/blog/author/"},{property:"og:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:url",content:"https://lightningdevkit.org/blog/author/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Lightning, LDK, Lightning Dev Kit, Documentation"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Lightning"},{property:"article:tag",content:"LDK"},{property:"article:tag",content:"Lightning Dev Kit"},{property:"article:tag",content:"Documentation"}]},regularPath:"/blog/author/",key:"v-b0968728",path:"/blog/author/",codeSwitcherOptions:{}},{frontmatter:{layout:"FrontmatterPagination",title:"Channels ",meta:[{property:"og:site_name",content:"Lightning Dev Kit Documentation"},{property:"og:type",content:"article"},{property:"og:url",content:"https://lightningdevkit.org/blog/tags/Channels/"},{property:"og:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:url",content:"https://lightningdevkit.org/blog/tags/Channels/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Lightning, LDK, Lightning Dev Kit, Documentation"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Lightning"},{property:"article:tag",content:"LDK"},{property:"article:tag",content:"Lightning Dev Kit"},{property:"article:tag",content:"Documentation"}]},regularPath:"/blog/tags/Channels/",key:"v-07a81b3e",path:"/blog/tags/Channels/",codeSwitcherOptions:{}},{frontmatter:{layout:"FrontmatterPagination",title:"Anchor Outputs ",meta:[{property:"og:site_name",content:"Lightning Dev Kit Documentation"},{property:"og:type",content:"article"},{property:"og:url",content:"https://lightningdevkit.org/blog/tags/Anchor Outputs/"},{property:"og:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:url",content:"https://lightningdevkit.org/blog/tags/Anchor Outputs/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Lightning, LDK, Lightning Dev Kit, Documentation"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Lightning"},{property:"article:tag",content:"LDK"},{property:"article:tag",content:"Lightning Dev Kit"},{property:"article:tag",content:"Documentation"}]},regularPath:"/blog/tags/Anchor%20Outputs/",key:"v-2d66714d",path:"/blog/tags/Anchor Outputs/",codeSwitcherOptions:{}},{frontmatter:{layout:"FrontmatterPagination",title:"Fees ",meta:[{property:"og:site_name",content:"Lightning Dev Kit Documentation"},{property:"og:type",content:"article"},{property:"og:url",content:"https://lightningdevkit.org/blog/tags/Fees/"},{property:"og:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:url",content:"https://lightningdevkit.org/blog/tags/Fees/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Lightning, LDK, Lightning Dev Kit, Documentation"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Lightning"},{property:"article:tag",content:"LDK"},{property:"article:tag",content:"Lightning Dev Kit"},{property:"article:tag",content:"Documentation"}]},regularPath:"/blog/tags/Fees/",key:"v-3d7abd24",path:"/blog/tags/Fees/",codeSwitcherOptions:{}},{frontmatter:{layout:"FrontmatterPagination",title:"Self-custody ",meta:[{property:"og:site_name",content:"Lightning Dev Kit Documentation"},{property:"og:type",content:"article"},{property:"og:url",content:"https://lightningdevkit.org/blog/tags/Self-custody/"},{property:"og:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:url",content:"https://lightningdevkit.org/blog/tags/Self-custody/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Lightning, LDK, Lightning Dev Kit, Documentation"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Lightning"},{property:"article:tag",content:"LDK"},{property:"article:tag",content:"Lightning Dev Kit"},{property:"article:tag",content:"Documentation"}]},regularPath:"/blog/tags/Self-custody/",key:"v-45d354a1",path:"/blog/tags/Self-custody/",codeSwitcherOptions:{}},{frontmatter:{layout:"FrontmatterPagination",title:"Mobile ",meta:[{property:"og:site_name",content:"Lightning Dev Kit Documentation"},{property:"og:type",content:"article"},{property:"og:url",content:"https://lightningdevkit.org/blog/tags/Mobile/"},{property:"og:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:url",content:"https://lightningdevkit.org/blog/tags/Mobile/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Lightning, LDK, Lightning Dev Kit, Documentation"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Lightning"},{property:"article:tag",content:"LDK"},{property:"article:tag",content:"Lightning Dev Kit"},{property:"article:tag",content:"Documentation"}]},regularPath:"/blog/tags/Mobile/",key:"v-4cee384f",path:"/blog/tags/Mobile/",codeSwitcherOptions:{}},{frontmatter:{layout:"FrontmatterPagination",title:"Gossip ",meta:[{property:"og:site_name",content:"Lightning Dev Kit Documentation"},{property:"og:type",content:"article"},{property:"og:url",content:"https://lightningdevkit.org/blog/tags/Gossip/"},{property:"og:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:url",content:"https://lightningdevkit.org/blog/tags/Gossip/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Lightning, LDK, Lightning Dev Kit, Documentation"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Lightning"},{property:"article:tag",content:"LDK"},{property:"article:tag",content:"Lightning Dev Kit"},{property:"article:tag",content:"Documentation"}]},regularPath:"/blog/tags/Gossip/",key:"v-107ce622",path:"/blog/tags/Gossip/",codeSwitcherOptions:{}},{frontmatter:{layout:"FrontmatterPagination",title:"Network Graph ",meta:[{property:"og:site_name",content:"Lightning Dev Kit Documentation"},{property:"og:type",content:"article"},{property:"og:url",content:"https://lightningdevkit.org/blog/tags/Network Graph/"},{property:"og:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:url",content:"https://lightningdevkit.org/blog/tags/Network Graph/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Lightning, LDK, Lightning Dev Kit, Documentation"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Lightning"},{property:"article:tag",content:"LDK"},{property:"article:tag",content:"Lightning Dev Kit"},{property:"article:tag",content:"Documentation"}]},regularPath:"/blog/tags/Network%20Graph/",key:"v-288bb6f4",path:"/blog/tags/Network Graph/",codeSwitcherOptions:{}},{frontmatter:{layout:"FrontmatterPagination",title:"Offers ",meta:[{property:"og:site_name",content:"Lightning Dev Kit Documentation"},{property:"og:type",content:"article"},{property:"og:url",content:"https://lightningdevkit.org/blog/tags/Offers/"},{property:"og:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:url",content:"https://lightningdevkit.org/blog/tags/Offers/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Lightning, LDK, Lightning Dev Kit, Documentation"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Lightning"},{property:"article:tag",content:"LDK"},{property:"article:tag",content:"Lightning Dev Kit"},{property:"article:tag",content:"Documentation"}]},regularPath:"/blog/tags/Offers/",key:"v-b0d4940c",path:"/blog/tags/Offers/",codeSwitcherOptions:{}},{frontmatter:{layout:"FrontmatterPagination",title:"Onion Messages ",meta:[{property:"og:site_name",content:"Lightning Dev Kit Documentation"},{property:"og:type",content:"article"},{property:"og:url",content:"https://lightningdevkit.org/blog/tags/Onion Messages/"},{property:"og:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:url",content:"https://lightningdevkit.org/blog/tags/Onion Messages/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Lightning, LDK, Lightning Dev Kit, Documentation"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Lightning"},{property:"article:tag",content:"LDK"},{property:"article:tag",content:"Lightning Dev Kit"},{property:"article:tag",content:"Documentation"}]},regularPath:"/blog/tags/Onion%20Messages/",key:"v-d885a66a",path:"/blog/tags/Onion Messages/",codeSwitcherOptions:{}},{frontmatter:{layout:"FrontmatterPagination",title:"Privacy ",meta:[{property:"og:site_name",content:"Lightning Dev Kit Documentation"},{property:"og:type",content:"article"},{property:"og:url",content:"https://lightningdevkit.org/blog/tags/Privacy/"},{property:"og:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:url",content:"https://lightningdevkit.org/blog/tags/Privacy/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Lightning, LDK, Lightning Dev Kit, Documentation"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Lightning"},{property:"article:tag",content:"LDK"},{property:"article:tag",content:"Lightning Dev Kit"},{property:"article:tag",content:"Documentation"}]},regularPath:"/blog/tags/Privacy/",key:"v-33d32965",path:"/blog/tags/Privacy/",codeSwitcherOptions:{}},{frontmatter:{layout:"FrontmatterPagination",title:"Case Studies ",meta:[{property:"og:site_name",content:"Lightning Dev Kit Documentation"},{property:"og:type",content:"article"},{property:"og:url",content:"https://lightningdevkit.org/blog/tags/Case Studies/"},{property:"og:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:url",content:"https://lightningdevkit.org/blog/tags/Case Studies/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Lightning, LDK, Lightning Dev Kit, Documentation"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Lightning"},{property:"article:tag",content:"LDK"},{property:"article:tag",content:"Lightning Dev Kit"},{property:"article:tag",content:"Documentation"}]},regularPath:"/blog/tags/Case%20Studies/",key:"v-2571507d",path:"/blog/tags/Case Studies/",codeSwitcherOptions:{}},{frontmatter:{layout:"FrontmatterPagination",title:"Bitcoin ",meta:[{property:"og:site_name",content:"Lightning Dev Kit Documentation"},{property:"og:type",content:"article"},{property:"og:url",content:"https://lightningdevkit.org/blog/tags/Bitcoin/"},{property:"og:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:url",content:"https://lightningdevkit.org/blog/tags/Bitcoin/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Lightning, LDK, Lightning Dev Kit, Documentation"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Lightning"},{property:"article:tag",content:"LDK"},{property:"article:tag",content:"Lightning Dev Kit"},{property:"article:tag",content:"Documentation"}]},regularPath:"/blog/tags/Bitcoin/",key:"v-89aabae2",path:"/blog/tags/Bitcoin/",codeSwitcherOptions:{}},{frontmatter:{layout:"FrontmatterPagination",title:"LDK ",meta:[{property:"og:site_name",content:"Lightning Dev Kit Documentation"},{property:"og:type",content:"article"},{property:"og:url",content:"https://lightningdevkit.org/blog/tags/LDK/"},{property:"og:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:url",content:"https://lightningdevkit.org/blog/tags/LDK/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Lightning, LDK, Lightning Dev Kit, Documentation"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Lightning"},{property:"article:tag",content:"LDK"},{property:"article:tag",content:"Lightning Dev Kit"},{property:"article:tag",content:"Documentation"}]},regularPath:"/blog/tags/LDK/",key:"v-5f1ce94c",path:"/blog/tags/LDK/",codeSwitcherOptions:{}},{frontmatter:{layout:"FrontmatterPagination",title:"Roadmap ",meta:[{property:"og:site_name",content:"Lightning Dev Kit Documentation"},{property:"og:type",content:"article"},{property:"og:url",content:"https://lightningdevkit.org/blog/tags/Roadmap/"},{property:"og:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:url",content:"https://lightningdevkit.org/blog/tags/Roadmap/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Lightning, LDK, Lightning Dev Kit, Documentation"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Lightning"},{property:"article:tag",content:"LDK"},{property:"article:tag",content:"Lightning Dev Kit"},{property:"article:tag",content:"Documentation"}]},regularPath:"/blog/tags/Roadmap/",key:"v-5643d131",path:"/blog/tags/Roadmap/",codeSwitcherOptions:{}},{frontmatter:{layout:"FrontmatterPagination",title:"Enterprise ",meta:[{property:"og:site_name",content:"Lightning Dev Kit Documentation"},{property:"og:type",content:"article"},{property:"og:url",content:"https://lightningdevkit.org/blog/tags/Enterprise/"},{property:"og:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:url",content:"https://lightningdevkit.org/blog/tags/Enterprise/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Lightning, LDK, Lightning Dev Kit, Documentation"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Lightning"},{property:"article:tag",content:"LDK"},{property:"article:tag",content:"Lightning Dev Kit"},{property:"article:tag",content:"Documentation"}]},regularPath:"/blog/tags/Enterprise/",key:"v-75584720",path:"/blog/tags/Enterprise/",codeSwitcherOptions:{}},{frontmatter:{layout:"FrontmatterPagination",title:"Phantom ",meta:[{property:"og:site_name",content:"Lightning Dev Kit Documentation"},{property:"og:type",content:"article"},{property:"og:url",content:"https://lightningdevkit.org/blog/tags/Phantom/"},{property:"og:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:url",content:"https://lightningdevkit.org/blog/tags/Phantom/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Lightning, LDK, Lightning Dev Kit, Documentation"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Lightning"},{property:"article:tag",content:"LDK"},{property:"article:tag",content:"Lightning Dev Kit"},{property:"article:tag",content:"Documentation"}]},regularPath:"/blog/tags/Phantom/",key:"v-14c62680",path:"/blog/tags/Phantom/",codeSwitcherOptions:{}},{frontmatter:{layout:"FrontmatterPagination",title:"Non-Custodial ",meta:[{property:"og:site_name",content:"Lightning Dev Kit Documentation"},{property:"og:type",content:"article"},{property:"og:url",content:"https://lightningdevkit.org/blog/tags/Non-Custodial/"},{property:"og:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:url",content:"https://lightningdevkit.org/blog/tags/Non-Custodial/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Lightning, LDK, Lightning Dev Kit, Documentation"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Lightning"},{property:"article:tag",content:"LDK"},{property:"article:tag",content:"Lightning Dev Kit"},{property:"article:tag",content:"Documentation"}]},regularPath:"/blog/tags/Non-Custodial/",key:"v-0bfa2c21",path:"/blog/tags/Non-Custodial/",codeSwitcherOptions:{}},{frontmatter:{layout:"FrontmatterPagination",title:"liquidity ",meta:[{property:"og:site_name",content:"Lightning Dev Kit Documentation"},{property:"og:type",content:"article"},{property:"og:url",content:"https://lightningdevkit.org/blog/tags/liquidity/"},{property:"og:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:url",content:"https://lightningdevkit.org/blog/tags/liquidity/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Lightning, LDK, Lightning Dev Kit, Documentation"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Lightning"},{property:"article:tag",content:"LDK"},{property:"article:tag",content:"Lightning Dev Kit"},{property:"article:tag",content:"Documentation"}]},regularPath:"/blog/tags/liquidity/",key:"v-2520b09b",path:"/blog/tags/liquidity/",codeSwitcherOptions:{}},{frontmatter:{layout:"FrontmatterPagination",title:"0-Conf Channels ",meta:[{property:"og:site_name",content:"Lightning Dev Kit Documentation"},{property:"og:type",content:"article"},{property:"og:url",content:"https://lightningdevkit.org/blog/tags/0-Conf Channels/"},{property:"og:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:url",content:"https://lightningdevkit.org/blog/tags/0-Conf Channels/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Lightning, LDK, Lightning Dev Kit, Documentation"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Lightning"},{property:"article:tag",content:"LDK"},{property:"article:tag",content:"Lightning Dev Kit"},{property:"article:tag",content:"Documentation"}]},regularPath:"/blog/tags/0-Conf%20Channels/",key:"v-026b604a",path:"/blog/tags/0-Conf Channels/",codeSwitcherOptions:{}},{frontmatter:{layout:"FrontmatterPagination",title:"Wilmer Paulino ",meta:[{property:"og:site_name",content:"Lightning Dev Kit Documentation"},{property:"og:type",content:"article"},{property:"og:url",content:"https://lightningdevkit.org/blog/author/Wilmer Paulino/"},{property:"og:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:url",content:"https://lightningdevkit.org/blog/author/Wilmer Paulino/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Lightning, LDK, Lightning Dev Kit, Documentation"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Lightning"},{property:"article:tag",content:"LDK"},{property:"article:tag",content:"Lightning Dev Kit"},{property:"article:tag",content:"Documentation"}]},regularPath:"/blog/author/Wilmer%20Paulino/",key:"v-27610544",path:"/blog/author/Wilmer Paulino/",codeSwitcherOptions:{}},{frontmatter:{layout:"FrontmatterPagination",title:"Elias Rohrer ",meta:[{property:"og:site_name",content:"Lightning Dev Kit Documentation"},{property:"og:type",content:"article"},{property:"og:url",content:"https://lightningdevkit.org/blog/author/Elias Rohrer/"},{property:"og:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:url",content:"https://lightningdevkit.org/blog/author/Elias Rohrer/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Lightning, LDK, Lightning Dev Kit, Documentation"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Lightning"},{property:"article:tag",content:"LDK"},{property:"article:tag",content:"Lightning Dev Kit"},{property:"article:tag",content:"Documentation"}]},regularPath:"/blog/author/Elias%20Rohrer/",key:"v-580ef260",path:"/blog/author/Elias Rohrer/",codeSwitcherOptions:{}},{frontmatter:{layout:"FrontmatterPagination",title:"Arik Sosman ",meta:[{property:"og:site_name",content:"Lightning Dev Kit Documentation"},{property:"og:type",content:"article"},{property:"og:url",content:"https://lightningdevkit.org/blog/author/Arik Sosman/"},{property:"og:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:url",content:"https://lightningdevkit.org/blog/author/Arik Sosman/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Lightning, LDK, Lightning Dev Kit, Documentation"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Lightning"},{property:"article:tag",content:"LDK"},{property:"article:tag",content:"Lightning Dev Kit"},{property:"article:tag",content:"Documentation"}]},regularPath:"/blog/author/Arik%20Sosman/",key:"v-79994b30",path:"/blog/author/Arik Sosman/",codeSwitcherOptions:{}},{frontmatter:{layout:"FrontmatterPagination",title:"Jeff Czyz ",meta:[{property:"og:site_name",content:"Lightning Dev Kit Documentation"},{property:"og:type",content:"article"},{property:"og:url",content:"https://lightningdevkit.org/blog/author/Jeff Czyz/"},{property:"og:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:url",content:"https://lightningdevkit.org/blog/author/Jeff Czyz/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Lightning, LDK, Lightning Dev Kit, Documentation"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Lightning"},{property:"article:tag",content:"LDK"},{property:"article:tag",content:"Lightning Dev Kit"},{property:"article:tag",content:"Documentation"}]},regularPath:"/blog/author/Jeff%20Czyz/",key:"v-bf9b8e8a",path:"/blog/author/Jeff Czyz/",codeSwitcherOptions:{}},{frontmatter:{layout:"FrontmatterPagination",title:"Matt Carvalho ",meta:[{property:"og:site_name",content:"Lightning Dev Kit Documentation"},{property:"og:type",content:"article"},{property:"og:url",content:"https://lightningdevkit.org/blog/author/Matt Carvalho/"},{property:"og:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:url",content:"https://lightningdevkit.org/blog/author/Matt Carvalho/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Lightning, LDK, Lightning Dev Kit, Documentation"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Lightning"},{property:"article:tag",content:"LDK"},{property:"article:tag",content:"Lightning Dev Kit"},{property:"article:tag",content:"Documentation"}]},regularPath:"/blog/author/Matt%20Carvalho/",key:"v-5e0b95d8",path:"/blog/author/Matt Carvalho/",codeSwitcherOptions:{}},{frontmatter:{layout:"FrontmatterPagination",title:"Ryan Loomba ",meta:[{property:"og:site_name",content:"Lightning Dev Kit Documentation"},{property:"og:type",content:"article"},{property:"og:url",content:"https://lightningdevkit.org/blog/author/Ryan Loomba/"},{property:"og:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:url",content:"https://lightningdevkit.org/blog/author/Ryan Loomba/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Lightning, LDK, Lightning Dev Kit, Documentation"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Lightning"},{property:"article:tag",content:"LDK"},{property:"article:tag",content:"Lightning Dev Kit"},{property:"article:tag",content:"Documentation"}]},regularPath:"/blog/author/Ryan%20Loomba/",key:"v-571fde2c",path:"/blog/author/Ryan Loomba/",codeSwitcherOptions:{}},{frontmatter:{layout:"FrontmatterPagination",title:"Conor Okus ",meta:[{property:"og:site_name",content:"Lightning Dev Kit Documentation"},{property:"og:type",content:"article"},{property:"og:url",content:"https://lightningdevkit.org/blog/author/Conor Okus/"},{property:"og:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:url",content:"https://lightningdevkit.org/blog/author/Conor Okus/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Lightning, LDK, Lightning Dev Kit, Documentation"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Lightning"},{property:"article:tag",content:"LDK"},{property:"article:tag",content:"Lightning Dev Kit"},{property:"article:tag",content:"Documentation"}]},regularPath:"/blog/author/Conor%20Okus/",key:"v-044cdb6b",path:"/blog/author/Conor Okus/",codeSwitcherOptions:{}},{frontmatter:{layout:"FrontmatterPagination",title:"Steve Lee ",meta:[{property:"og:site_name",content:"Lightning Dev Kit Documentation"},{property:"og:type",content:"article"},{property:"og:url",content:"https://lightningdevkit.org/blog/author/Steve Lee/"},{property:"og:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:url",content:"https://lightningdevkit.org/blog/author/Steve Lee/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Lightning, LDK, Lightning Dev Kit, Documentation"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Lightning"},{property:"article:tag",content:"LDK"},{property:"article:tag",content:"Lightning Dev Kit"},{property:"article:tag",content:"Documentation"}]},regularPath:"/blog/author/Steve%20Lee/",key:"v-39b7f2bf",path:"/blog/author/Steve Lee/",codeSwitcherOptions:{}},{frontmatter:{layout:"FrontmatterPagination",title:"Ben Carman ",meta:[{property:"og:site_name",content:"Lightning Dev Kit Documentation"},{property:"og:type",content:"article"},{property:"og:url",content:"https://lightningdevkit.org/blog/author/Ben Carman/"},{property:"og:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:url",content:"https://lightningdevkit.org/blog/author/Ben Carman/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Lightning, LDK, Lightning Dev Kit, Documentation"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Lightning"},{property:"article:tag",content:"LDK"},{property:"article:tag",content:"Lightning Dev Kit"},{property:"article:tag",content:"Documentation"}]},regularPath:"/blog/author/Ben%20Carman/",key:"v-6a051305",path:"/blog/author/Ben Carman/",codeSwitcherOptions:{}},{frontmatter:{layout:"FrontmatterPagination",title:"Valentine Wallace ",meta:[{property:"og:site_name",content:"Lightning Dev Kit Documentation"},{property:"og:type",content:"article"},{property:"og:url",content:"https://lightningdevkit.org/blog/author/Valentine Wallace/"},{property:"og:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:url",content:"https://lightningdevkit.org/blog/author/Valentine Wallace/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Lightning, LDK, Lightning Dev Kit, Documentation"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Lightning"},{property:"article:tag",content:"LDK"},{property:"article:tag",content:"Lightning Dev Kit"},{property:"article:tag",content:"Documentation"}]},regularPath:"/blog/author/Valentine%20Wallace/",key:"v-54403322",path:"/blog/author/Valentine Wallace/",codeSwitcherOptions:{}},{frontmatter:{layout:"FrontmatterPagination",title:"John Cantrell ",meta:[{property:"og:site_name",content:"Lightning Dev Kit Documentation"},{property:"og:type",content:"article"},{property:"og:url",content:"https://lightningdevkit.org/blog/author/John Cantrell/"},{property:"og:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:url",content:"https://lightningdevkit.org/blog/author/John Cantrell/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Lightning, LDK, Lightning Dev Kit, Documentation"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Lightning"},{property:"article:tag",content:"LDK"},{property:"article:tag",content:"Lightning Dev Kit"},{property:"article:tag",content:"Documentation"}]},regularPath:"/blog/author/John%20Cantrell/",key:"v-c06ffaa8",path:"/blog/author/John Cantrell/",codeSwitcherOptions:{}},{frontmatter:{layout:"FrontmatterPagination",title:"Matt Corallo ",meta:[{property:"og:site_name",content:"Lightning Dev Kit Documentation"},{property:"og:type",content:"article"},{property:"og:url",content:"https://lightningdevkit.org/blog/author/Matt Corallo/"},{property:"og:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:url",content:"https://lightningdevkit.org/blog/author/Matt Corallo/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Lightning, LDK, Lightning Dev Kit, Documentation"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Lightning"},{property:"article:tag",content:"LDK"},{property:"article:tag",content:"Lightning Dev Kit"},{property:"article:tag",content:"Documentation"}]},regularPath:"/blog/author/Matt%20Corallo/",key:"v-438a3c44",path:"/blog/author/Matt Corallo/",codeSwitcherOptions:{}},{frontmatter:{layout:"FrontmatterPagination",title:"Sergi Delgado ",meta:[{property:"og:site_name",content:"Lightning Dev Kit Documentation"},{property:"og:type",content:"article"},{property:"og:url",content:"https://lightningdevkit.org/blog/author/Sergi Delgado/"},{property:"og:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:url",content:"https://lightningdevkit.org/blog/author/Sergi Delgado/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Lightning, LDK, Lightning Dev Kit, Documentation"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Lightning"},{property:"article:tag",content:"LDK"},{property:"article:tag",content:"Lightning Dev Kit"},{property:"article:tag",content:"Documentation"}]},regularPath:"/blog/author/Sergi%20Delgado/",key:"v-0c9ef90c",path:"/blog/author/Sergi Delgado/",codeSwitcherOptions:{}},{frontmatter:{layout:"DirectoryPagination",title:"Page 2",meta:[{property:"og:site_name",content:"Lightning Dev Kit Documentation"},{property:"og:type",content:"article"},{property:"og:url",content:"https://lightningdevkit.org/blog/page/2/"},{property:"og:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:url",content:"https://lightningdevkit.org/blog/page/2/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://lightningdevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Lightning, LDK, Lightning Dev Kit, Documentation"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Lightning"},{property:"article:tag",content:"LDK"},{property:"article:tag",content:"Lightning Dev Kit"},{property:"article:tag",content:"Documentation"}]},regularPath:"/blog/page/2/",key:"v-c3507bb6",path:"/blog/page/2/",codeSwitcherOptions:{}}],themeConfig:{domain:"https://lightningdevkit.org",logo:"/img/logo.svg",displayAllHeaders:!1,repo:"lightningdevkit/lightningdevkit.org",docsDir:"docs",docsBranch:"main",editLinks:!0,sidebarDepth:0,algolia:{indexName:"lightningdevkit",appId:"BH4D9OD16A",apiKey:"17ed8a4e16a1cb7d94da4e96f2ff817f",algoliaOptions:{typoTolerance:"min"},autocompleteOptions:{openOnFocus:!0}},nav:[{text:"Docs",link:"/introduction/"},{text:"Case Studies",link:"/case-studies/"},{text:"Blog",link:"/blog/"},{text:"Discord",link:"https://discord.gg/5AcknnMfBw",rel:"noopener noreferrer"},{text:"GitHub",link:"https://github.com/lightningdevkit",rel:"noopener noreferrer"}],sidebar:{"/_blog/":[{title:"Blog",collapsable:!1,children:[["/blog/","Articles"],["/blog/tags/","Tags"],["/blog/author/","Authors"]]}],"/blog/":[{title:"Blog",collapsable:!1,children:[["/blog/","Articles"],["/blog/tags/","Tags"],["/blog/author/","Authors"]]}],"/":[{title:"Documentation",collapsable:!1,children:[{title:"Introduction",path:"/introduction/",collapsable:!0,children:[["/introduction/use-cases","Use Cases"],["/introduction/architecture","Architecture"],["/introduction/peer-management","Peer Management"],["/introduction/persistent_storage","Persistent Storage"],["/introduction/blockchain_data","Blockchain Data"],["/introduction/wallet_management","Wallet Management"],["/introduction/networking","Networking"],["/introduction/private_key_management","Private Key Management"],["/introduction/transactions","Transactions"],["/introduction/random_number_generation","Random Number Generation"]]},{title:"Building a node with LDK",collapsable:!0,children:[["/building-a-node-with-ldk/introduction","Introduction"],["/building-a-node-with-ldk/installation","Installation"],["/building-a-node-with-ldk/setting-up-a-channel-manager","Setting up a Channel Manager"],["/building-a-node-with-ldk/handling-events","Handling Events"],["/building-a-node-with-ldk/setting-up-a-peer-manager","Setting up a Peer Manager"],["/building-a-node-with-ldk/connect-to-peers","Connect to Peers"],["/building-a-node-with-ldk/opening-a-channel","Opening a Channel"],["/building-a-node-with-ldk/sending-payments","Sending Payments"],["/building-a-node-with-ldk/receiving-payments","Receiving Payments"],["/building-a-node-with-ldk/closing-a-channel","Closing a Channel"]]},"/running-a-sample-ldk-node",{title:"Blockchain Data",collapsable:!0,children:[["/blockchain_data/introduction","Introduction"],["/blockchain_data/chain_activity","Chain Activity"],["/blockchain_data/block_source","Block Source"],["/blockchain_data/full_blocks","Full Blocks"],["/blockchain_data/pre_filtered_blocks","Pre-filtered Blocks"],["/blockchain_data/confirmed_transactions","Confirmed Transactions"],["/blockchain_data/transaction_broadcasting","Transaction Broadcasting"]]},"/key_management","/examples"]},{title:"API Reference",collapsable:!1,children:[{title:"Rust",collapsable:!0,children:[["https://docs.rs/lightning/*/lightning/","lightning"],["https://docs.rs/lightning-background-processor/*/lightning_background_processor/","lightning-background-processor"],["https://docs.rs/lightning-block-sync/*/lightning_block_sync/","lightning-block-sync"],["https://docs.rs/lightning-invoice/*/lightning_invoice/","lightning-invoice"],["https://docs.rs/lightning-net-tokio/*/lightning_net_tokio/","lightning-net-tokio"],["https://docs.rs/lightning-persister/*/lightning_persister/","lightning-persister"],["https://docs.rs/lightning-rapid-gossip-sync/*/lightning_rapid_gossip_sync/","lightning-rapid-gossip-sync"],["https://docs.rs/lightning-transaction-sync/*/lightning_transaction_sync/","lightning-transaction-sync"],["https://docs.rs/lightning-custom-message/*/lightning_custom_message/","lightning-custom-message"]]},["https://github.com/arik-so/SwiftLightning/tree/master/Documentation","Swift"]]}]},footer:{links:[{title:"Docs",children:[{text:"Introduction",link:"/introduction/"},{text:"Building a node with LDK",link:"/building-a-node-with-ldk/introduction"},{text:"Running a sample LDK node",link:"/running-a-sample-ldk-node/"},{text:"Architecture",link:"/introduction/architecture/"},{text:"Blockchain Data",link:"/blockchain_data/introduction/"},{text:"Key Management",link:"/key_management/"},{text:"Examples",link:"/examples/"}]},{title:"Community",children:[{text:"GitHub",link:"https://github.com/lightningdevkit",rel:"noopener noreferrer"},{text:"Twitter",link:"https://twitter.com/lightningdevkit",rel:"noopener noreferrer"},{text:"Chat on Discord",link:"https://discord.gg/5AcknnMfBw",rel:"noopener noreferrer"},{text:"LDK Calendar",link:"https://calendar.google.com/calendar/embed?src=c_e6fv6vlshbpoob2mmbvblkkoj4%40group.calendar.google.com",rel:"noopener noreferrer"},{text:"LDK Review Club",link:"http://ldk.reviews/",rel:"noopener noreferrer"},{text:"Code of Conduct",link:"/code_of_conduct",rel:"noopener noreferrer"}]},{title:"Resources",children:[{text:"Case Studies",link:"/case-studies/"},{text:"Blog",link:"/blog/"}]},{title:"Other",children:[{text:"Bitcoin Dev Kit",link:"https://bitcoindevkit.org/",rel:"noopener noreferrer"},{text:"Reporting a Vulnerability",link:"https://github.com/lightningdevkit/rust-lightning/blob/main/SECURITY.md",rel:"noopener noreferrer"}]}],copyright:"Copyright © 2024 LDK Developers"}}},{COLOR_MODES:Mc,STORE_ATTR:Ac,setColorMode:jc}=n(112),Bc=t=>"Enter"===t.code||13===(t.keyCode||t.which),Fc=t=>{const e=t.target.matches("#algolia-search-input")&&Bc(t);(t.target.matches(".ds-dropdown-menu *")||e)&&document.getElementById("algolia-search-input").blur(),t.target.matches(".ytEmbed")&&(t.preventDefault(),(t=>{const e=t.querySelector("iframe[data-src]");if(e){const t=e.getAttribute("data-src");e.setAttribute("src",t)}})(t.target))};if("undefined"==typeof process||"server"!==process.env.VUE_ENV){const t=window.matchMedia("(prefers-color-scheme: dark)").matches?Mc[1]:Mc[0],e=window.localStorage.getItem(Ac);jc(Mc.includes(e)?e:t)}n(242);Hn.component("Badge",()=>Promise.all([n.e(0),n.e(14)]).then(n.bind(null,437))),Hn.component("CodeBlock",()=>Promise.all([n.e(0),n.e(15)]).then(n.bind(null,382))),Hn.component("CodeGroup",()=>Promise.all([n.e(0),n.e(16)]).then(n.bind(null,383)));n(243);var Rc={props:{color:{required:!1,default:"rgb(66, 185, 131)"}}},Nc=(n(244),Object(Cc.a)(Rc,(function(){return(0,this._self._c)("div",{staticClass:"spinner",style:{background:this.color}})}),[],!1,null,"1bbcb91a",null).exports);const Ic={name:"Mermaid",props:{id:{type:String,required:!0},graph:{type:String,required:!0}},data:()=>({svg:void 0}),render(t){return void 0===this.svg?t("Loading"):t("div",{domProps:{innerHTML:this.svg,style:"width: 100%"}})},mounted(){n.e(68).then(n.t.bind(null,372,7)).then(t=>{t.initialize({startOnLoad:!0});let e=document.createElement("div");document.body.appendChild(e),t.render(this.id,this.graph,t=>{this.svg=t,document.body.removeChild(e)},e)})},components:{Loading:Nc}};var Uc=n(95),zc=n.n(Uc);n(245);Hn.component("CodeSwitcher",()=>n.e(28).then(n.bind(null,384)));var qc={tags:{Channels:{key:"Channels",scope:"tags",path:"/blog/tags/Channels/",pageKeys:["v-109b7b6a"]},"Anchor Outputs":{key:"Anchor Outputs",scope:"tags",path:"/blog/tags/Anchor Outputs/",pageKeys:["v-109b7b6a"]},Fees:{key:"Fees",scope:"tags",path:"/blog/tags/Fees/",pageKeys:["v-109b7b6a"]},"Self-custody":{key:"Self-custody",scope:"tags",path:"/blog/tags/Self-custody/",pageKeys:["v-0f4e007e"]},Mobile:{key:"Mobile",scope:"tags",path:"/blog/tags/Mobile/",pageKeys:["v-0f4e007e","v-67ea603f"]},Gossip:{key:"Gossip",scope:"tags",path:"/blog/tags/Gossip/",pageKeys:["v-2578306f"]},"Network Graph":{key:"Network Graph",scope:"tags",path:"/blog/tags/Network Graph/",pageKeys:["v-2578306f"]},Offers:{key:"Offers",scope:"tags",path:"/blog/tags/Offers/",pageKeys:["v-6018492a","v-7b672071"]},"Onion Messages":{key:"Onion Messages",scope:"tags",path:"/blog/tags/Onion Messages/",pageKeys:["v-6018492a","v-7b672071"]},Privacy:{key:"Privacy",scope:"tags",path:"/blog/tags/Privacy/",pageKeys:["v-6018492a"]},"Case Studies":{key:"Case Studies",scope:"tags",path:"/blog/tags/Case Studies/",pageKeys:["v-59a63080","v-e02a8a76","v-61c088e6","v-394e384e","v-4ffe1afe"]},Bitcoin:{key:"Bitcoin",scope:"tags",path:"/blog/tags/Bitcoin/",pageKeys:["v-eebe6fe6"]},LDK:{key:"LDK",scope:"tags",path:"/blog/tags/LDK/",pageKeys:["v-eebe6fe6"]},Roadmap:{key:"Roadmap",scope:"tags",path:"/blog/tags/Roadmap/",pageKeys:["v-7b0f0961"]},Enterprise:{key:"Enterprise",scope:"tags",path:"/blog/tags/Enterprise/",pageKeys:["v-177ef1fe"]},Phantom:{key:"Phantom",scope:"tags",path:"/blog/tags/Phantom/",pageKeys:["v-177ef1fe"]},"Non-Custodial":{key:"Non-Custodial",scope:"tags",path:"/blog/tags/Non-Custodial/",pageKeys:["v-67ea603f"]},liquidity:{key:"liquidity",scope:"tags",path:"/blog/tags/liquidity/",pageKeys:["v-4c78f51d"]},"0-Conf Channels":{key:"0-Conf Channels",scope:"tags",path:"/blog/tags/0-Conf Channels/",pageKeys:["v-3843152b"]}},author:{"Wilmer Paulino":{key:"Wilmer Paulino",scope:"author",path:"/blog/author/Wilmer Paulino/",pageKeys:["v-109b7b6a"]},"Elias Rohrer":{key:"Elias Rohrer",scope:"author",path:"/blog/author/Elias Rohrer/",pageKeys:["v-0f4e007e"]},"Arik Sosman":{key:"Arik Sosman",scope:"author",path:"/blog/author/Arik Sosman/",pageKeys:["v-2578306f"]},"Jeff Czyz":{key:"Jeff Czyz",scope:"author",path:"/blog/author/Jeff Czyz/",pageKeys:["v-6018492a"]},"Matt Carvalho":{key:"Matt Carvalho",scope:"author",path:"/blog/author/Matt Carvalho/",pageKeys:["v-59a63080"]},"Ryan Loomba":{key:"Ryan Loomba",scope:"author",path:"/blog/author/Ryan Loomba/",pageKeys:["v-e02a8a76"]},"Conor Okus":{key:"Conor Okus",scope:"author",path:"/blog/author/Conor Okus/",pageKeys:["v-eebe6fe6"]},"Steve Lee":{key:"Steve Lee",scope:"author",path:"/blog/author/Steve Lee/",pageKeys:["v-7b0f0961"]},"Ben Carman":{key:"Ben Carman",scope:"author",path:"/blog/author/Ben Carman/",pageKeys:["v-61c088e6"]},"Valentine Wallace":{key:"Valentine Wallace",scope:"author",path:"/blog/author/Valentine Wallace/",pageKeys:["v-177ef1fe","v-7b672071"]},"John Cantrell":{key:"John Cantrell",scope:"author",path:"/blog/author/John Cantrell/",pageKeys:["v-394e384e","v-4c78f51d","v-3843152b"]},"Matt Corallo":{key:"Matt Corallo",scope:"author",path:"/blog/author/Matt Corallo/",pageKeys:["v-67ea603f"]},"Sergi Delgado":{key:"Sergi Delgado",scope:"author",path:"/blog/author/Sergi Delgado/",pageKeys:["v-4ffe1afe"]}}};class Wc{constructor(t,e){this._metaMap=Object.assign({},t),Object.keys(this._metaMap).forEach(t=>{const{pageKeys:n}=this._metaMap[t];this._metaMap[t].pages=n.map(t=>function(t,e){for(let n=0;n{const{pages:n,path:i}=this._metaMap[e];t.push({name:e,pages:n,path:i})}),t}getItemByName(t){return this._metaMap[t]}}var Hc={blog:(t,e)=>{const i=n(45);return i(t.frontmatter.date)-i(e.frontmatter.date)>0?-1:1},tags:(t,e)=>{const i=n(45);return i(t.frontmatter.date)-i(e.frontmatter.date)>0?-1:1},author:(t,e)=>{const i=n(45);return i(t.frontmatter.date)-i(e.frontmatter.date)>0?-1:1}},Vc={blog:function(t,e,n){return t.pid===n&&t.id===e},tags:function(t,e,n){const i=e;return["tags"].some(e=>{const n=t.frontmatter[e];return Array.isArray(n)?n.some(t=>t==i):n==i})},author:function(t,e,n){const i=e;return["author","authors"].some(e=>{const n=t.frontmatter[e];return Array.isArray(n)?n.some(t=>t==i):n==i})}},Gc=[{pid:"blog",id:"blog",filter:Vc.blog,sorter:Hc.blog,pages:[{path:"/blog/",interval:[0,9]},{path:"/blog/page/2/",interval:[10,16]}],prevText:"Prev",nextText:"Next"},{pid:"tags",id:"Channels",filter:Vc.tags,sorter:Hc.tags,pages:[{path:"/blog/tags/Channels/",interval:[0,1]}],prevText:"Prev",nextText:"Next"},{pid:"tags",id:"Anchor Outputs",filter:Vc.tags,sorter:Hc.tags,pages:[{path:"/blog/tags/Anchor Outputs/",interval:[0,1]}],prevText:"Prev",nextText:"Next"},{pid:"tags",id:"Fees",filter:Vc.tags,sorter:Hc.tags,pages:[{path:"/blog/tags/Fees/",interval:[0,1]}],prevText:"Prev",nextText:"Next"},{pid:"tags",id:"Self-custody",filter:Vc.tags,sorter:Hc.tags,pages:[{path:"/blog/tags/Self-custody/",interval:[0,1]}],prevText:"Prev",nextText:"Next"},{pid:"tags",id:"Mobile",filter:Vc.tags,sorter:Hc.tags,pages:[{path:"/blog/tags/Mobile/",interval:[0,2]}],prevText:"Prev",nextText:"Next"},{pid:"tags",id:"Gossip",filter:Vc.tags,sorter:Hc.tags,pages:[{path:"/blog/tags/Gossip/",interval:[0,1]}],prevText:"Prev",nextText:"Next"},{pid:"tags",id:"Network Graph",filter:Vc.tags,sorter:Hc.tags,pages:[{path:"/blog/tags/Network Graph/",interval:[0,1]}],prevText:"Prev",nextText:"Next"},{pid:"tags",id:"Offers",filter:Vc.tags,sorter:Hc.tags,pages:[{path:"/blog/tags/Offers/",interval:[0,2]}],prevText:"Prev",nextText:"Next"},{pid:"tags",id:"Onion Messages",filter:Vc.tags,sorter:Hc.tags,pages:[{path:"/blog/tags/Onion Messages/",interval:[0,2]}],prevText:"Prev",nextText:"Next"},{pid:"tags",id:"Privacy",filter:Vc.tags,sorter:Hc.tags,pages:[{path:"/blog/tags/Privacy/",interval:[0,1]}],prevText:"Prev",nextText:"Next"},{pid:"tags",id:"Case Studies",filter:Vc.tags,sorter:Hc.tags,pages:[{path:"/blog/tags/Case Studies/",interval:[0,5]}],prevText:"Prev",nextText:"Next"},{pid:"tags",id:"Bitcoin",filter:Vc.tags,sorter:Hc.tags,pages:[{path:"/blog/tags/Bitcoin/",interval:[0,1]}],prevText:"Prev",nextText:"Next"},{pid:"tags",id:"LDK",filter:Vc.tags,sorter:Hc.tags,pages:[{path:"/blog/tags/LDK/",interval:[0,1]}],prevText:"Prev",nextText:"Next"},{pid:"tags",id:"Roadmap",filter:Vc.tags,sorter:Hc.tags,pages:[{path:"/blog/tags/Roadmap/",interval:[0,1]}],prevText:"Prev",nextText:"Next"},{pid:"tags",id:"Enterprise",filter:Vc.tags,sorter:Hc.tags,pages:[{path:"/blog/tags/Enterprise/",interval:[0,1]}],prevText:"Prev",nextText:"Next"},{pid:"tags",id:"Phantom",filter:Vc.tags,sorter:Hc.tags,pages:[{path:"/blog/tags/Phantom/",interval:[0,1]}],prevText:"Prev",nextText:"Next"},{pid:"tags",id:"Non-Custodial",filter:Vc.tags,sorter:Hc.tags,pages:[{path:"/blog/tags/Non-Custodial/",interval:[0,1]}],prevText:"Prev",nextText:"Next"},{pid:"tags",id:"liquidity",filter:Vc.tags,sorter:Hc.tags,pages:[{path:"/blog/tags/liquidity/",interval:[0,1]}],prevText:"Prev",nextText:"Next"},{pid:"tags",id:"0-Conf Channels",filter:Vc.tags,sorter:Hc.tags,pages:[{path:"/blog/tags/0-Conf Channels/",interval:[0,1]}],prevText:"Prev",nextText:"Next"},{pid:"author",id:"Wilmer Paulino",filter:Vc.author,sorter:Hc.author,pages:[{path:"/blog/author/Wilmer Paulino/",interval:[0,1]}],prevText:"Prev",nextText:"Next"},{pid:"author",id:"Elias Rohrer",filter:Vc.author,sorter:Hc.author,pages:[{path:"/blog/author/Elias Rohrer/",interval:[0,1]}],prevText:"Prev",nextText:"Next"},{pid:"author",id:"Arik Sosman",filter:Vc.author,sorter:Hc.author,pages:[{path:"/blog/author/Arik Sosman/",interval:[0,1]}],prevText:"Prev",nextText:"Next"},{pid:"author",id:"Jeff Czyz",filter:Vc.author,sorter:Hc.author,pages:[{path:"/blog/author/Jeff Czyz/",interval:[0,1]}],prevText:"Prev",nextText:"Next"},{pid:"author",id:"Matt Carvalho",filter:Vc.author,sorter:Hc.author,pages:[{path:"/blog/author/Matt Carvalho/",interval:[0,1]}],prevText:"Prev",nextText:"Next"},{pid:"author",id:"Ryan Loomba",filter:Vc.author,sorter:Hc.author,pages:[{path:"/blog/author/Ryan Loomba/",interval:[0,1]}],prevText:"Prev",nextText:"Next"},{pid:"author",id:"Conor Okus",filter:Vc.author,sorter:Hc.author,pages:[{path:"/blog/author/Conor Okus/",interval:[0,1]}],prevText:"Prev",nextText:"Next"},{pid:"author",id:"Steve Lee",filter:Vc.author,sorter:Hc.author,pages:[{path:"/blog/author/Steve Lee/",interval:[0,1]}],prevText:"Prev",nextText:"Next"},{pid:"author",id:"Ben Carman",filter:Vc.author,sorter:Hc.author,pages:[{path:"/blog/author/Ben Carman/",interval:[0,1]}],prevText:"Prev",nextText:"Next"},{pid:"author",id:"Valentine Wallace",filter:Vc.author,sorter:Hc.author,pages:[{path:"/blog/author/Valentine Wallace/",interval:[0,2]}],prevText:"Prev",nextText:"Next"},{pid:"author",id:"John Cantrell",filter:Vc.author,sorter:Hc.author,pages:[{path:"/blog/author/John Cantrell/",interval:[0,3]}],prevText:"Prev",nextText:"Next"},{pid:"author",id:"Matt Corallo",filter:Vc.author,sorter:Hc.author,pages:[{path:"/blog/author/Matt Corallo/",interval:[0,1]}],prevText:"Prev",nextText:"Next"},{pid:"author",id:"Sergi Delgado",filter:Vc.author,sorter:Hc.author,pages:[{path:"/blog/author/Sergi Delgado/",interval:[0,1]}],prevText:"Prev",nextText:"Next"}],Jc=n(96);const Zc=n.n(Jc)()("plugin-blog:pagination");class Yc{constructor(t,e,n){Zc("pagination",t);const{pages:i,prevText:r,nextText:o}=t,{path:a}=n;this._prevText=r,this._nextText=o;for(let t=0,e=i.length;tt.filter(e,t.id,t.pid)).sort(t.sorter)}setIndexPage(t){this._indexPage=t}get length(){return this._paginationPages.length}get pages(){const[t,e]=this._currentPage.interval;return this._matchedPages.slice(t,e+1)}get hasPrev(){return 0!==this.paginationIndex}get prevLink(){return this.hasPrev?this.paginationIndex-1==0&&this._indexPage?this._indexPage:this._paginationPages[this.paginationIndex-1].path:null}get hasNext(){return this.paginationIndex!==this.length-1}get nextLink(){return this.hasNext?this._paginationPages[this.paginationIndex+1].path:null}get prevText(){return this._prevText}get nextText(){return this._nextText}getSpecificPageLink(t){return this._paginationPages[t].path}}const Xc=new class{constructor(t){this.paginations=t}get pages(){return Hn.$vuepress.$get("siteData").pages}getPagination(t,e,n){Zc("id",e),Zc("pid",t);const i=this.paginations.filter(n=>n.id===e&&n.pid===t)[0];return new Yc(i,this.pages,n)}}(Gc);var Qc={comment:{enabled:!1,service:""},email:{enabled:!1},feed:{rss:!1,atom:!1,json:!1}},ts=[({router:t})=>{"undefined"!=typeof process&&"server"===process.env.VUE_ENV||t.onReady(()=>{const{app:e}=t;e.$once("hook:mounted",()=>{setTimeout(()=>{const{hash:t}=document.location;if(t.length>1){const e=t.substring(1),n=document.getElementById(e);n&&n.scrollIntoView()}},500)}),document.addEventListener("click",Fc),document.addEventListener("keyup",t=>{Bc(t)&&Fc(t)})})},{},({Vue:t})=>{t.mixin({computed:{$dataBlock(){return this.$options.__data__block__}}})},{},{},({Vue:t})=>{t.component("CodeCopy",Sc)},({Vue:t})=>{t.component("Mermaid",Ic)},({Vue:t})=>t.use(zc.a),{},{},({Vue:t})=>{const e=Object.keys(qc).map(t=>{const e=qc[t],n="$"+t;return{[n](){const{pages:t}=this.$site;return new Wc(e,t)},["$current"+(t.charAt(0).toUpperCase()+t.slice(1))](){const t=this.$route.meta.id;return this[n].getItemByName(t)}}}).reduce((t,e)=>(Object.assign(t,e),t),{});e.$frontmatterKey=function(){const t=this["$"+this.$route.meta.id];return t||null},t.mixin({computed:e})},({Vue:t})=>{t.mixin({computed:{$pagination(){return this.$route.meta.pid&&this.$route.meta.id?this.$getPagination(this.$route.meta.pid,this.$route.meta.id):null}},methods:{$getPagination(t,e){return e=e||t,Xc.getPagination(t,e,this.$route)}}})},({Vue:t})=>{const e={$service:()=>Qc};t.mixin({computed:e})}],es=[];class ns extends class{constructor(){this.store=new Hn({data:{state:{}}})}$get(t){return this.store.state[t]}$set(t,e){Hn.set(this.store.state,t,e)}$emit(...t){this.store.$emit(...t)}$on(...t){this.store.$on(...t)}}{}Object.assign(ns.prototype,{getPageAsyncComponent:ac,getLayoutAsyncComponent:cc,getAsyncComponent:sc,getVueComponent:lc});var is={install(t){const e=new ns;t.$vuepress=e,t.prototype.$vuepress=e}};function rs(t,e){const n=e.toLowerCase();return t.options.routes.some(t=>t.path.toLowerCase()===n)}var os={props:{pageKey:String,slotKey:{type:String,default:"default"}},render(t){const e=this.pageKey||this.$parent.$page.key;return uc("pageKey",e),Hn.component(e)||Hn.component(e,ac(e)),Hn.component(e)?t(e):t("")}},as={functional:!0,props:{slotKey:String,required:!0},render:(t,{props:e,slots:n})=>t("div",{class:["content__"+e.slotKey]},n()[e.slotKey])},cs={computed:{openInNewWindowTitle(){return this.$themeLocaleConfig.openNewWindowText||"(opens new window)"}}},ss=(n(248),n(249),Object(Cc.a)(cs,(function(){var t=this._self._c;return t("span",[t("svg",{staticClass:"icon outbound",attrs:{xmlns:"http://www.w3.org/2000/svg","aria-hidden":"true",focusable:"false",x:"0px",y:"0px",viewBox:"0 0 100 100",width:"15",height:"15"}},[t("path",{attrs:{fill:"currentColor",d:"M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"}}),this._v(" "),t("polygon",{attrs:{fill:"currentColor",points:"45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"}})]),this._v(" "),t("span",{staticClass:"sr-only"},[this._v(this._s(this.openInNewWindowTitle))])])}),[],!1,null,null,null).exports),ls={functional:!0,render(t,{parent:e,children:n}){if(e._isMounted)return n;e.$once("hook:mounted",()=>{e.$forceUpdate()})}};Hn.config.productionTip=!1,Hn.use(qa),Hn.use(is),Hn.mixin(function(t,e,n=Hn){!function(t){t.locales&&Object.keys(t.locales).forEach(e=>{t.locales[e].path=e});Object.freeze(t)}(e),n.$vuepress.$set("siteData",e);const i=new(t(n.$vuepress.$get("siteData"))),r=Object.getOwnPropertyDescriptors(Object.getPrototypeOf(i)),o={};return Object.keys(r).reduce((t,e)=>(e.startsWith("$")&&(t[e]=r[e].get),t),o),{computed:o}}(t=>class{setPage(t){this.__page=t}get $site(){return t}get $themeConfig(){return this.$site.themeConfig}get $frontmatter(){return this.$page.frontmatter}get $localeConfig(){const{locales:t={}}=this.$site;let e,n;for(const i in t)"/"===i?n=t[i]:0===this.$page.path.indexOf(i)&&(e=t[i]);return e||n||{}}get $siteTitle(){return this.$localeConfig.title||this.$site.title||""}get $canonicalUrl(){const{canonicalUrl:t}=this.$page.frontmatter;return"string"==typeof t&&t}get $title(){const t=this.$page,{metaTitle:e}=this.$page.frontmatter;if("string"==typeof e)return e;const n=this.$siteTitle,i=t.frontmatter.home?null:t.frontmatter.title||t.title;return n?i?i+" | "+n:n:i||"VuePress"}get $description(){const t=function(t){if(t){const e=t.filter(t=>"description"===t.name)[0];if(e)return e.content}}(this.$page.frontmatter.meta);return t||(this.$page.frontmatter.description||this.$localeConfig.description||this.$site.description||"")}get $lang(){return this.$page.frontmatter.lang||this.$localeConfig.lang||"en-US"}get $localePath(){return this.$localeConfig.path||"/"}get $themeLocaleConfig(){return(this.$site.themeConfig.locales||{})[this.$localePath]||{}}get $page(){return this.__page?this.__page:function(t,e){for(let n=0;nn||(t.hash?!Hn.$vuepress.$get("disableScrollBehavior")&&{selector:decodeURIComponent(t.hash)}:{x:0,y:0})});!function(t){t.beforeEach((e,n,i)=>{if(rs(t,e.path))i();else if(/(\/|\.html)$/.test(e.path))if(/\/$/.test(e.path)){const n=e.path.replace(/\/$/,"")+".html";rs(t,n)?i(n):i()}else i();else{const n=e.path+"/",r=e.path+".html";rs(t,r)?i(r):rs(t,n)?i(n):i()}})}(n);const i={};try{await Promise.all(ts.filter(t=>"function"==typeof t).map(e=>e({Vue:Hn,options:i,router:n,siteData:Ec,isServer:t})))}catch(t){console.error(t)}return{app:new Hn(Object.assign(i,{router:n,render:t=>t("div",{attrs:{id:"app"}},[t("RouterView",{ref:"layout"}),t("div",{class:"global-ui"},es.map(e=>t(e)))])})),router:n}}(!1).then(({app:t,router:e})=>{e.onReady(()=>{t.$mount("#app")})})}]); \ No newline at end of file diff --git a/blockchain_data/block_source/index.html b/blockchain_data/block_source/index.html index 57a7aacbc..424e59b8f 100644 --- a/blockchain_data/block_source/index.html +++ b/blockchain_data/block_source/index.html @@ -31,7 +31,7 @@ - + @@ -76,7 +76,7 @@ }

For instance, you may implement this interface by querying Bitcoin Core's JSON RPC interface, which happens to be a sample implementation provided by -lightning-block-sync.

Let's walk through the use case where LDK receives full blocks.

- + diff --git a/blockchain_data/chain_activity/index.html b/blockchain_data/chain_activity/index.html index 0215a6f12..65cd8efa7 100644 --- a/blockchain_data/chain_activity/index.html +++ b/blockchain_data/chain_activity/index.html @@ -33,7 +33,7 @@ - + @@ -72,7 +72,7 @@ source for the best chain tip, detecting chain forks, and notifying listeners when blocks are connected and disconnected. It can be configured to:

  • Poll a custom BlockSource
  • Notify ChannelManager and ChainMonitor of block events

It is your choice as to whether you use this utility or your own to feed the required chain data to LDK. If you choose to use it, you will need to implement -the BlockSource interface or use one of the samples that it provides.

Note

Currently, lightning-block-sync is only available in Rust.

- + diff --git a/blockchain_data/confirmed_transactions/index.html b/blockchain_data/confirmed_transactions/index.html index 69497a16a..403979195 100644 --- a/blockchain_data/confirmed_transactions/index.html +++ b/blockchain_data/confirmed_transactions/index.html @@ -33,7 +33,7 @@ - + @@ -81,7 +81,7 @@ described in the Confirm documentation (opens new window)

Note

Note that the described methods of Confirm must be called both on the ChannelManager and the ChainMonitor.

Note

Be advised that chain::Confirm is a less mature interface than chain::Listen. As such, there is not yet a utility like -lightning-block-sync to use for interacting with clients like Electrum.

- + diff --git a/blockchain_data/full_blocks/index.html b/blockchain_data/full_blocks/index.html index 3fa4e7ab3..f253e2cd9 100644 --- a/blockchain_data/full_blocks/index.html +++ b/blockchain_data/full_blocks/index.html @@ -31,7 +31,7 @@ - + @@ -66,7 +66,7 @@ updates the internal channel state as needed. The ChainMonitor will detect any spends of the channel funding transaction or any pertinent transaction outputs, tracking them as necessary.

If necessary, LDK will broadcast a transaction on your behalf. More on that -later. For now, let's look at the more interesting case of pre-filtered blocks.

- + diff --git a/blockchain_data/introduction/index.html b/blockchain_data/introduction/index.html index 240d04f52..12fbe3b6b 100644 --- a/blockchain_data/introduction/index.html +++ b/blockchain_data/introduction/index.html @@ -33,7 +33,7 @@ - + @@ -70,7 +70,7 @@ channel.

When a new block is mined, it is connected to the chain while other blocks may be disconnected if reorganized out. Transactions are confirmed or unconfirmed during this process. You are required to feed this activity to LDK which will -process it by:

  • Updating channel state
  • Signaling back transactions to filter
  • Broadcasting transactions if necessary

We will walk through this process as depicted here:

LDK block processing
- + diff --git a/blockchain_data/pre_filtered_blocks/index.html b/blockchain_data/pre_filtered_blocks/index.html index 6713b22ba..6a01fad6b 100644 --- a/blockchain_data/pre_filtered_blocks/index.html +++ b/blockchain_data/pre_filtered_blocks/index.html @@ -35,7 +35,7 @@ - + @@ -95,7 +95,7 @@ });

When this is provided, ChainMonitor will call back to the filter as channels are opened and blocks connected. This gives the opportunity for the source to -pre-filter blocks as desired.

Regardless, when a block is connected, its header must be processed by LDK.

- + diff --git a/blockchain_data/transaction_broadcasting/index.html b/blockchain_data/transaction_broadcasting/index.html index 461b46da5..5668786f8 100644 --- a/blockchain_data/transaction_broadcasting/index.html +++ b/blockchain_data/transaction_broadcasting/index.html @@ -33,7 +33,7 @@ - + @@ -65,7 +65,7 @@ notify it of blocks, it will determine if it should broadcast a transaction and do so using an implementation of BroadcasterInterface that you have provided.

And as those transactions or those from your peers are confirmed on-chain, they will be likewise processed when notified of a connected block. Thus, continuing -the cycle.

- + diff --git a/blog/anchor-outputs-channels-are-here/index.html b/blog/anchor-outputs-channels-are-here/index.html index 0f17405d9..2790ceec8 100644 --- a/blog/anchor-outputs-channels-are-here/index.html +++ b/blog/anchor-outputs-channels-are-here/index.html @@ -30,7 +30,7 @@ - + @@ -102,7 +102,7 @@ meantime, application developers must determine whether their use case warrants such enforcement, then implement it themselves. For example, a mobile user connected to a LSP could always defer to the LSP to broadcast the latest state so that the user wouldn’t need to maintain a reserve.

While the feature is now available, we still consider it experimental. We're always seeking feedback -on how to improve our API and provide a better developer experience.

- + diff --git a/blog/author/Elias Rohrer/index.html b/blog/author/Elias Rohrer/index.html index 3d1c75546..84ea24598 100644 --- a/blog/author/Elias Rohrer/index.html +++ b/blog/author/Elias Rohrer/index.html @@ -25,7 +25,7 @@ - + @@ -99,6 +99,6 @@ (opens new window)
Reporting a Vulnerability (opens new window)
- + diff --git a/blog/author/Jeff Czyz/index.html b/blog/author/Jeff Czyz/index.html index 4166a9ce8..eab3fdf5d 100644 --- a/blog/author/Jeff Czyz/index.html +++ b/blog/author/Jeff Czyz/index.html @@ -25,7 +25,7 @@ - + @@ -99,6 +99,6 @@ (opens new window)
Reporting a Vulnerability (opens new window)
- + diff --git a/blog/author/John Cantrell/index.html b/blog/author/John Cantrell/index.html index c62a749cc..f12a08fcd 100644 --- a/blog/author/John Cantrell/index.html +++ b/blog/author/John Cantrell/index.html @@ -25,7 +25,7 @@ - + @@ -121,6 +121,6 @@ (opens new window)
Reporting a Vulnerability (opens new window)
- + diff --git a/blog/author/Matt Carvalho/index.html b/blog/author/Matt Carvalho/index.html index e2721e2ea..110411c33 100644 --- a/blog/author/Matt Carvalho/index.html +++ b/blog/author/Matt Carvalho/index.html @@ -25,7 +25,7 @@ - + @@ -99,6 +99,6 @@ (opens new window)
Reporting a Vulnerability (opens new window)
- + diff --git a/blog/author/Matt Corallo/index.html b/blog/author/Matt Corallo/index.html index 6d0529070..3a4e39687 100644 --- a/blog/author/Matt Corallo/index.html +++ b/blog/author/Matt Corallo/index.html @@ -25,7 +25,7 @@ - + @@ -99,6 +99,6 @@ (opens new window)
Reporting a Vulnerability (opens new window)
- + diff --git a/blog/author/Ryan Loomba/index.html b/blog/author/Ryan Loomba/index.html index 0a9680687..52173aafe 100644 --- a/blog/author/Ryan Loomba/index.html +++ b/blog/author/Ryan Loomba/index.html @@ -25,7 +25,7 @@ - + @@ -99,6 +99,6 @@ (opens new window)
Reporting a Vulnerability (opens new window)
- + diff --git a/blog/author/Sergi Delgado/index.html b/blog/author/Sergi Delgado/index.html index d0fef0a09..6b29cd409 100644 --- a/blog/author/Sergi Delgado/index.html +++ b/blog/author/Sergi Delgado/index.html @@ -25,7 +25,7 @@ - + @@ -99,6 +99,6 @@ (opens new window)
Reporting a Vulnerability (opens new window)
- + diff --git a/blog/author/Steve Lee/index.html b/blog/author/Steve Lee/index.html index ec8c6c891..6358c3f43 100644 --- a/blog/author/Steve Lee/index.html +++ b/blog/author/Steve Lee/index.html @@ -25,7 +25,7 @@ - + @@ -99,6 +99,6 @@ (opens new window)
Reporting a Vulnerability (opens new window)
- + diff --git a/blog/author/Valentine Wallace/index.html b/blog/author/Valentine Wallace/index.html index 26539038b..ff90800bc 100644 --- a/blog/author/Valentine Wallace/index.html +++ b/blog/author/Valentine Wallace/index.html @@ -25,7 +25,7 @@ - + @@ -110,6 +110,6 @@ (opens new window)
Reporting a Vulnerability (opens new window)
- + diff --git a/blog/author/Wilmer Paulino/index.html b/blog/author/Wilmer Paulino/index.html index 57c3980f8..d86dd265e 100644 --- a/blog/author/Wilmer Paulino/index.html +++ b/blog/author/Wilmer Paulino/index.html @@ -25,7 +25,7 @@ - + @@ -99,6 +99,6 @@ (opens new window)
Reporting a Vulnerability (opens new window)
- + diff --git a/blog/author/index.html b/blog/author/index.html index 67a1f7640..f873f6581 100644 --- a/blog/author/index.html +++ b/blog/author/index.html @@ -25,7 +25,7 @@ - + @@ -53,7 +53,7 @@ GitHub (opens new window) GitHub - (opens new window)

Authors

- + diff --git a/blog/tags/LDK/index.html b/blog/tags/LDK/index.html index 16f500ff8..a5aaf9a8c 100644 --- a/blog/tags/LDK/index.html +++ b/blog/tags/LDK/index.html @@ -25,7 +25,7 @@ - + @@ -99,6 +99,6 @@ (opens new window)
Reporting a Vulnerability (opens new window)
- + diff --git a/blog/tags/Mobile/index.html b/blog/tags/Mobile/index.html index 4b7664cda..2243f00b4 100644 --- a/blog/tags/Mobile/index.html +++ b/blog/tags/Mobile/index.html @@ -25,7 +25,7 @@ - + @@ -110,6 +110,6 @@ (opens new window)
Reporting a Vulnerability (opens new window)
- + diff --git a/blog/tags/Network Graph/index.html b/blog/tags/Network Graph/index.html index 8f48f60be..52adb5543 100644 --- a/blog/tags/Network Graph/index.html +++ b/blog/tags/Network Graph/index.html @@ -25,7 +25,7 @@ - + @@ -99,6 +99,6 @@ (opens new window)
Reporting a Vulnerability (opens new window)
- + diff --git a/blog/tags/Non-Custodial/index.html b/blog/tags/Non-Custodial/index.html index 36116748c..73d2ca648 100644 --- a/blog/tags/Non-Custodial/index.html +++ b/blog/tags/Non-Custodial/index.html @@ -25,7 +25,7 @@ - + @@ -99,6 +99,6 @@ (opens new window)
Reporting a Vulnerability (opens new window)
- + diff --git a/blog/tags/Offers/index.html b/blog/tags/Offers/index.html index f42ecd3a2..671652f7e 100644 --- a/blog/tags/Offers/index.html +++ b/blog/tags/Offers/index.html @@ -25,7 +25,7 @@ - + @@ -110,6 +110,6 @@ (opens new window)
Reporting a Vulnerability (opens new window)
- + diff --git a/blog/tags/Onion Messages/index.html b/blog/tags/Onion Messages/index.html index 3b85bff77..48bbbd7f5 100644 --- a/blog/tags/Onion Messages/index.html +++ b/blog/tags/Onion Messages/index.html @@ -25,7 +25,7 @@ - + @@ -110,6 +110,6 @@ (opens new window)
Reporting a Vulnerability (opens new window)
- + diff --git a/blog/tags/Phantom/index.html b/blog/tags/Phantom/index.html index 02359fe8c..8d04199de 100644 --- a/blog/tags/Phantom/index.html +++ b/blog/tags/Phantom/index.html @@ -25,7 +25,7 @@ - + @@ -99,6 +99,6 @@ (opens new window)
Reporting a Vulnerability (opens new window)
- + diff --git a/blog/tags/Privacy/index.html b/blog/tags/Privacy/index.html index 0b989ba2f..8476cabca 100644 --- a/blog/tags/Privacy/index.html +++ b/blog/tags/Privacy/index.html @@ -25,7 +25,7 @@ - + @@ -99,6 +99,6 @@ (opens new window)
Reporting a Vulnerability (opens new window)
- + diff --git a/blog/tags/Roadmap/index.html b/blog/tags/Roadmap/index.html index 5bf488b44..554d81c8d 100644 --- a/blog/tags/Roadmap/index.html +++ b/blog/tags/Roadmap/index.html @@ -25,7 +25,7 @@ - + @@ -99,6 +99,6 @@ (opens new window)
Reporting a Vulnerability (opens new window)
- + diff --git a/blog/tags/Self-custody/index.html b/blog/tags/Self-custody/index.html index af428d548..ce5908fa9 100644 --- a/blog/tags/Self-custody/index.html +++ b/blog/tags/Self-custody/index.html @@ -25,7 +25,7 @@ - + @@ -99,6 +99,6 @@ (opens new window)
Reporting a Vulnerability (opens new window)
- + diff --git a/blog/tags/index.html b/blog/tags/index.html index 456b90de6..60da90fbf 100644 --- a/blog/tags/index.html +++ b/blog/tags/index.html @@ -25,7 +25,7 @@ - + @@ -53,7 +53,7 @@ GitHub (opens new window) GitHub - (opens new window)

Tags

- + diff --git a/blog/teos-uses-ldk-to-build-open-source-watchtower/index.html b/blog/teos-uses-ldk-to-build-open-source-watchtower/index.html index e306a6ed6..95b6d05f7 100644 --- a/blog/teos-uses-ldk-to-build-open-source-watchtower/index.html +++ b/blog/teos-uses-ldk-to-build-open-source-watchtower/index.html @@ -30,7 +30,7 @@ - + @@ -69,7 +69,7 @@ - Tags: - Case Studies


The Eye of Satoshi (TEOS) (opens new window) is a bitcoin watchtower with a specific focus on lightning. Watchtowers are third-party viewing services that help prevent people from cheating on the lightning network by constantly monitoring the bitcoin blockchain for channel breaches. If found, a watchtower will react by penalizing the misbehaving party and sending all funds to its counterpart.

In order for TEOS to work, information is needed from several different building blocks. This includes block data processing (such as reacting to forks/chain splits), interaction with a bitcoin node (for transaction broadcasting), and general tooling around bitcoin/lightning (transaction parsing, data encoding/decoding, lightning P2P messaging, etc).

TEOS does not have strong performance requirements, as data is checked in newly processed blocks approximately every 10 mins. However, if it services a substantial amount of nodes at once or channels with high traffic, it may need to compare processed info against huge amounts of data.

# What we did?

We initially had a Python implementation, but as the project evolved we realized it could be beneficial to switch to a language that was more robust and had better tooling. Rust was an obvious choice given how well it works for other bitcoin-related projects. Moving away from Python allowed us to drop a substantial amount of dependencies that were unmaintained or maintained by us, and instead use properly maintained counterparts.

TEOS architecture

While it did take time to perform the Rust re-implementation, it was worth it for several reasons. LDK does a substantial amount of the low-level heavy lifting (e.g. reorg management), allowing us to remove several components of the original design and abstract interaction with bitcoind. Additionally, Python lacks proper support for most of lightning’s functionality, so we would have had to implement and maintain all of the related toolings to support lightning P2P communication features.

Furthermore, LDK supports various lightning features that we may need in the future, such as anchors. At the end of the day, LDK makes it possible to focus on the product/protocol you are building and care less about the low-level lightning/bitcoin parts that are needed.

# Results

The TEOS codebase is now more robust and stable, making it easier to contribute to and integrate with other projects.

In terms of functionality, we recently reached the same state as the old Python codebase. We are currently focusing on new features and integrations. Additionally, using Rust and LDK has allowed us to build a healthier community. It’s easier to make improvements to a project when you use the same tools and literally speak the same language.

It's been a pleasure working with the LDK team. They’ve helped us solve several Rust and LDK issues, and have been open to accepting PRs and implementing new functionality that we require.

Learn how you can deploy your own TEOS watchtower on the Bitcoin Developers Youtube channel (opens new window).

- + diff --git a/building-a-node-with-ldk/introduction/index.html b/building-a-node-with-ldk/introduction/index.html index 1c84b0424..0118f058c 100644 --- a/building-a-node-with-ldk/introduction/index.html +++ b/building-a-node-with-ldk/introduction/index.html @@ -29,7 +29,7 @@ - + @@ -57,7 +57,7 @@ GitHub (opens new window) GitHub - (opens new window)

# Building a Node with LDK

# Learn how to build a basic LDK node from scratch

Note

For an integrated example of an LDK node in Rust, see the Sample Node (opens new window)

The following tutorials will show you how to build the simplest lightning node using LDK, that fufills the following tasks:

  1. Connecting to Peers
  2. Opening Channels
  3. Sending Payments
  4. Receiving Payments
  5. Closing Channels

# Foundational Components

Let's start by looking at the core components we'll need to make this node work for the tasks we outlined above.

  1. A ChannelManager (opens new window), to open and close channels.
  2. A networking stack (https://docs.rs/lightning-net-tokio/*/lightning_net_tokio/index.html), for establishing TCP/IP connections to other nodes on the lightning network.
  3. Payments & routing, ability to create and pay invoices.

To make the above work we also need to setup a series of supporting modules, including:

  1. A FeeEstimator (opens new window)
  2. A Logger (opens new window)
  3. A Transaction Broadcaster (opens new window)
  4. A NetworkGraph (opens new window)
  5. A Persister (opens new window)
  6. An EventHandler (opens new window)
  7. A Transaction Filter (opens new window)
  8. A ChainMonitor (opens new window)
  9. A KeysManager (opens new window)
  10. A Scorer (opens new window)
- + diff --git a/building-a-node-with-ldk/opening-a-channel/index.html b/building-a-node-with-ldk/opening-a-channel/index.html index ecbfd1f2b..06c63c4a5 100644 --- a/building-a-node-with-ldk/opening-a-channel/index.html +++ b/building-a-node-with-ldk/opening-a-channel/index.html @@ -29,7 +29,7 @@ - + @@ -260,7 +260,7 @@ } } } -

References: Rust BroadcasterInterface docs (opens new window), Java/Kotlin BroadcasterInterface bindings (opens new window)

Keep LDK in sync

Remember if you are restarting and have open channels then you should let LDK know about the latest channel state.

References: Rust BroadcasterInterface docs (opens new window), Java/Kotlin BroadcasterInterface bindings (opens new window)

Keep LDK in sync

Remember if you are restarting and have open channels then you should let LDK know about the latest channel state.

Reporting a Vulnerability (opens new window)
- + diff --git a/building-a-node-with-ldk/receiving-payments/index.html b/building-a-node-with-ldk/receiving-payments/index.html index ba507729b..9091ba914 100644 --- a/building-a-node-with-ldk/receiving-payments/index.html +++ b/building-a-node-with-ldk/receiving-payments/index.html @@ -35,7 +35,7 @@ - + @@ -172,7 +172,7 @@ let paymentPreimage = paymentClaimedEvent.getPurpose().getValueAsInvoicePayment()?.getPaymentPreimage() let _ = channelManager.claimFunds(paymentPreimage: paymentPreimage!) } -

References: Rust PaymentClaimable docs (opens new window), Java/Kotlin PaymentClaimable bindings (opens new window)

References: Rust PaymentClaimable docs (opens new window), Java/Kotlin PaymentClaimable bindings (opens new window)

Reporting a Vulnerability (opens new window)
- + diff --git a/building-a-node-with-ldk/sending-payments/index.html b/building-a-node-with-ldk/sending-payments/index.html index ab163089c..5c5043487 100644 --- a/building-a-node-with-ldk/sending-payments/index.html +++ b/building-a-node-with-ldk/sending-payments/index.html @@ -33,7 +33,7 @@ - + @@ -162,7 +162,7 @@ } else if let paymentFailedEvent = event.getValueAsPaymentFailed() { // Handle failed payment } -

References: Rust PaymentSent docs (opens new window),Rust PaymentFailed docs (opens new window), Java/Kotlin PaymentSent bindings (opens new window), Java/Kotlin PaymentFailed bindings (opens new window)

References: Rust PaymentSent docs (opens new window),Rust PaymentFailed docs (opens new window), Java/Kotlin PaymentSent bindings (opens new window), Java/Kotlin PaymentFailed bindings (opens new window)

Reporting a Vulnerability (opens new window)
- + diff --git a/building-a-node-with-ldk/setting-up-a-channel-manager/index.html b/building-a-node-with-ldk/setting-up-a-channel-manager/index.html index 4f90b03ad..bf12b0b7c 100644 --- a/building-a-node-with-ldk/setting-up-a-channel-manager/index.html +++ b/building-a-node-with-ldk/setting-up-a-channel-manager/index.html @@ -29,7 +29,7 @@ - + @@ -879,7 +879,7 @@ // Scorer loaded let scorer = MultiThreadedLockableScore(score: score) -

Dependencies: NetworkGraph

References: Rust ProbabilisticScorer docs (opens new window), Java/Kotlin ProbabilisticScorer docs (opens new window)

Dependencies: NetworkGraph

References: Rust ProbabilisticScorer docs (opens new window), Java/Kotlin ProbabilisticScorer docs (opens new window)

Reporting a Vulnerability (opens new window)
- + diff --git a/building-a-node-with-ldk/setting-up-a-peer-manager/index.html b/building-a-node-with-ldk/setting-up-a-peer-manager/index.html index 118ba775c..4bcd465c2 100644 --- a/building-a-node-with-ldk/setting-up-a-peer-manager/index.html +++ b/building-a-node-with-ldk/setting-up-a-peer-manager/index.html @@ -29,7 +29,7 @@ - + @@ -88,7 +88,7 @@

Implementation notes: if you did not initialize P2PGossipSync in the previous step, you can initialize your own struct (which can be a dummy struct) that implements RoutingMessageHandler

Dependencies: ChannelManager, RoutingMessageHandler, KeysManager, random bytes, Logger

References: Rust PeerManager docs (opens new window), Rust RoutingMessageHandler docs (opens new window), Java/Kotlin PeerManager bindings (opens new window), Java/Kotlin RoutingMessageHandler bindings (opens new window)

Implementation notes: if you did not initialize P2PGossipSync in the previous step, you can initialize your own struct (which can be a dummy struct) that implements RoutingMessageHandler

Dependencies: ChannelManager, RoutingMessageHandler, KeysManager, random bytes, Logger

References: Rust PeerManager docs (opens new window), Rust RoutingMessageHandler docs (opens new window), Java/Kotlin PeerManager bindings (opens new window), Java/Kotlin RoutingMessageHandler bindings (opens new window)

Reporting a Vulnerability (opens new window)
- + diff --git a/case-studies/index.html b/case-studies/index.html index b515f0544..7dcdb358d 100644 --- a/case-studies/index.html +++ b/case-studies/index.html @@ -29,7 +29,7 @@ - + @@ -111,6 +111,6 @@ (opens new window)
Reporting a Vulnerability (opens new window)
- + diff --git a/code_of_conduct/index.html b/code_of_conduct/index.html index 69e138f53..065b4232a 100644 --- a/code_of_conduct/index.html +++ b/code_of_conduct/index.html @@ -29,7 +29,7 @@ - + @@ -58,7 +58,7 @@ (opens new window) GitHub (opens new window)

# LDK Code of Conduct

The LDK community is open to pretty much anyone. To ensure that project forums such as the Discord server and GitHub repository are open and friendly, we count on maintainers and project representatives to behave in a way that is not disruptive to LDK's culture or to any one participant's well-being.

Therefore, we came up with some easy to follow guidelines.

  • Be friendly. Interact in a way that fosters openness, inclusivity, and collaboration.
  • Be respectful. We may disagree, but disagreement is no excuse for rude behavior or personal attacks.
  • Be considerate. Provide and accept constructive criticism.

Private or public harassment of any kind will not be tolerated. Since harassment can take many forms, here's a non-exhaustive list of what we consider unacceptable behavior:

  • Offensive language directed at individuals or groups of people
  • Bullying (verbal, physical, social, or cyber)
  • Interfering with someone's ability to contribute, like with excessive nitpicking
  • Continued one-on-one communication after a party has requested it cease
  • Stalking online or offline
  • Doxing or unauthorized publication of private information or communication
  • Unwelcomed sexual attention
  • Inappropriate visual displays such as sexually-oriented or offensive photography, cartoons, drawings, or gestures
  • Retaliation for reporting or threatening to report harassment

Additionally, spam and other content which disrupts or prevents LDK contributors from working on LDK is not acceptable.

# The Code of Conduct Team

A small team of LDK contributors has volunteered to enforce the LDK Code of Conduct. If you feel like a community member has engaged in inappropriate behavior, please don't hesitate to contact one of the following LDK contributors via email or on Discord:

  • Matt Corallo - ldkcocpoc on mattcorallo.com
  • Val Wallace - vwallace on protonmail.com
  • Devrandom - devrandom99 on proton.me

# The Code of Conduct Team’s Responsibilities

Team members are tasked with responding to reports within 24 hours. They will review each incident and determine, to the best of their ability:

  • Does the event constitute a Code of Conduct violation?
  • Is the behavior on our list of inappropriate behavior? Is it borderline inappropriate?
  • Did the event occur in a space within our Code of Conduct's scope? -
    • If the incident occurred outside community forums and the individual is seen as a project representative or identifies as an LDK contributor, the incident may be in scope.
    • Additionally, an incident may be in scope if a community member's ability to contribute to LDK is impacted.
  • Did this incident occur in a private conversation or in a public space?
  • Is the situation isolated or ongoing?
  • How is the reported person's behavior negatively impacting others?
  • Does the incident impact the ability of individuals to freely contribute to LDK?
  • Does this incident include sexual harassment?
  • Does this pose a safety risk or severely negatively impact someone's mental health?
  • Is there a risk of this behavior being repeated?
  • Does the reported person understand why their behavior was inappropriate?

If a report is insufficiently detailed or involves multiple parties, the Code of Conduct Team may seek additional information from witnesses or the accused. Neither party should contact the other to discuss the incident. Likewise, the team will do its best not to disclose who reported a given incident, either to the accused or generally, though we recognize that circumstantial disclosures to the accused might be unavoidable.

The Code of Conduct Team aims to resolve all reports within one week. If a resolution is not possible within that time frame, the team will respond to the reporter(s) with an adjusted one.

# Possible responses to an incident include:

# Taking no further action:

If the Code of Conduct Team determines that no action is needed, they will inform the reporter.

# Simple warning:

This applies to disruptive behavior, but not insulting behavior. The Code of Conduct Team will contact the individual(s) and request that they stop.

# Final warning:

If an incident or series of incidents creates sustained toxicity within the LDK Community, the Code of Conduct Team will sternly warn the reported party and raise the possibility of further disciplinary action. In addition, they may request that the reported party:

  • Not use specific language
  • Not participate in specific types of discussions
  • Not send private messages to a community member
  • Not review a particular person's PRs on GitHub (but still allow them to privately share review comments with a maintainer)
  • Not lead sub-projects like code review sessions
  • Take a step away for a short period to cool off
  • Lose maintainer/merge access

# 2-3 months imposed break:

If the Code of Conduct Team’s warning goes unheeded, the individual(s) may be asked to avoid participating with the LDK Community on its preferred platforms for several months. After time has passed, the individual(s) will have the option of meeting with the team to discuss returning to the community.

# Extended or permanent ban:

If a temporary break does not remedy a serious offense, the offender may be removed from the Discord server and Github repository. The Code of Conduct Team may also choose to un-ban a user for a first offense, depending on its severity and pending that the user has offered the offended party a genuine apology.

- + diff --git a/examples/index.html b/examples/index.html index c1bf8a7b0..123fc8231 100644 --- a/examples/index.html +++ b/examples/index.html @@ -29,7 +29,7 @@ - + @@ -58,7 +58,7 @@ (opens new window) GitHub (opens new window)

# Examples

Click the links below and learn from community-built example projects

# Rust Sample Node (opens new window)

This sample serves as a complete reference for constructing a lightning node with -LDK. This is a good starting point if you want a self-guided tour.

# Kotlin/Android Sample App (opens new window)

This sample uses the Kotlin bindings provided by ldk-garbagecollected (opens new window) to create a self-custodial mobile lightning wallet on Android.

# Swift/iOS Sample App (opens new window)

This sample uses the Swift bindings provided by ldk-swift (opens new window) to create a self-custodial mobile lightning wallet on iOS.

# Rust node with sample Lightning Signer integration (opens new window)

A Rust lightning node implementation based on LDK and the Lightning Signer projects. Aims to be production ready at some point.

# Rust node with sample Tor integration (opens new window)

A Rust lightning node sample implementation based on LDK with an embedded Tor daemon.

# LDK Node (opens new window)

A ready-to-go Lightning node library built using LDK and BDK (opens new window).

# LDK Node Rust Sample (opens new window)

A sample lightning node command-line app built on top of LDK Node (similar to ldk-sample).

# LDK Node Swift Sample App (opens new window)

This sample uses ldk-node-swift (opens new window) bindings to quickly build a self custodial lightning mobile wallet on iOS. Watch the video tutorial here (opens new window).

# LDK Node Swift Sample app using Bitcoin Design Guide (opens new window)

This sample is a good starting point for building a sample iOS wallet with a strong focus on user experience.

# LDK Node Flutter Sample App (opens new window)

This sample is a starting point for an LDK Node Flutter app.

# LDK Node React Native Sample App (opens new window)

This sample is a starting point for an LDK Node React Native app.

# LDK Node Sample Desktop App (opens new window)

This sample is a desktop node manager for LDK Node.

Reporting a Vulnerability (opens new window)
- + diff --git a/index.html b/index.html index d5d5c472d..fa3969315 100644 --- a/index.html +++ b/index.html @@ -27,7 +27,7 @@ - + @@ -102,6 +102,6 @@ (opens new window)
Reporting a Vulnerability (opens new window)
- + diff --git a/introduction/architecture/index.html b/introduction/architecture/index.html index 66b31ec53..da539b766 100644 --- a/introduction/architecture/index.html +++ b/introduction/architecture/index.html @@ -29,7 +29,7 @@ - + @@ -57,7 +57,7 @@ GitHub (opens new window) GitHub - (opens new window)

# Architecture

Architecture

Firstly, LDK is not a daemon, but rather its own implementation of the Lightning protocol written as an SDK and designed to be compiled and executed in your application.

This makes it environment agnostic, allowing you to choose your own data storage, wallet, networking stack and blockchain monitoring. In the diagram above the boxes with dotted borders are LDK's modules — these must be configured with either default or custom implementations that you provide.

LDK also uses an event-driven architecture which allows for asynchronous result notification. For example you perform actions like making payments without waiting for the result and are later made aware via an event if the payment was successful or not.

Language Bindings

Although the core SDK is written in Rust, LDK supports many other programming languages. These include Java/Kotlin, Swift, JavaScript/TypeScript (Beta), C++ (Alpha). Check out examples to see some of the implementations out in the wild!

- + diff --git a/introduction/blockchain_data/index.html b/introduction/blockchain_data/index.html index 63d2bf79f..f830cb0d2 100644 --- a/introduction/blockchain_data/index.html +++ b/introduction/blockchain_data/index.html @@ -29,7 +29,7 @@ - + @@ -57,7 +57,7 @@ GitHub (opens new window) GitHub - (opens new window)

# Blockchain Data

LDK provides a simple block_connected/block_disconnected API which you pass block headers and transaction information to. LDK also provides an API for getting information about transactions it wishes to be informed of, which is compatible with Electrum server requests/neutrino filtering/etc.

Blockchain Data Guide (opens new window)

Sample module in Rust (opens new window)

- + diff --git a/introduction/index.html b/introduction/index.html index db0be106c..e40188317 100644 --- a/introduction/index.html +++ b/introduction/index.html @@ -29,7 +29,7 @@ - + @@ -62,7 +62,7 @@ the Rust docs for the Rust version of that struct/method is your best bet.

# Swift LDK Documentation (opens new window)

These docs are mainly geared towards how Swift could call LDK C bindings directly, but still may provide a useful overview of Rust Lightning in the context of language bindings.

# Rust Sample Node (opens new window)

The sample serves as a complete reference for constructing a Lightning node with the LDK. This is a good starting point if you want a self-guided tour!

# Architecture

Gives a high-level organization of LDK and how the pieces fit together. Variations of this diagram -are used throughout the site. This is the primary source and is still a work in progress.

- + diff --git a/introduction/networking/index.html b/introduction/networking/index.html index cf594b886..a386e4fb9 100644 --- a/introduction/networking/index.html +++ b/introduction/networking/index.html @@ -29,7 +29,7 @@ - + @@ -57,7 +57,7 @@ GitHub (opens new window) GitHub - (opens new window)

# Networking

To enable you to run a full Lightning node on an embedded machine, LDK doesn't specify exactly how to connect to another node at all! The default implementation uses TCP sockets, but, e.g., if you wanted to run your full Lightning node on a hardware wallet, you could, by piping the Lightning network messages over USB/serial and then sending them in a TCP socket from another machine.

Learn more about connect to peers.

- + diff --git a/introduction/peer-management/index.html b/introduction/peer-management/index.html index 923642fed..1c962f469 100644 --- a/introduction/peer-management/index.html +++ b/introduction/peer-management/index.html @@ -29,7 +29,7 @@ - + @@ -57,7 +57,7 @@ GitHub (opens new window) GitHub - (opens new window)

# Peer Management

Peer Management

One of the first things you'll need to do when building your own Lightning node is connect to a peer. In LDK this is handled by the PeerManager (opens new window).

The PeerManager has two dependencies:

Since LDK knows nothing about your networking stack, you'll need to implement your own networking logic in order to connect to peers on the network. Provide LDK with raw TCP/IP socket data and the library will handle the rest for you.

LDK also handles a number of background tasks that need to happen periodically via BackgroundProcessor (opens new window)

Default Implementation

If you are developing in a Rust Tokio (opens new window) environment, LDK ships with a socket handling crate (opens new window) that let's you easily create new connections with peers.

- + diff --git a/introduction/persistent_storage/index.html b/introduction/persistent_storage/index.html index 0bd9b51e7..5f79c85cc 100644 --- a/introduction/persistent_storage/index.html +++ b/introduction/persistent_storage/index.html @@ -29,7 +29,7 @@ - + @@ -57,7 +57,7 @@ GitHub (opens new window) GitHub - (opens new window)

# Persistent Storage

You can store the channel state any way you want - whether Google Drive/iCloud, a local disk, any key-value store/database/a remote server, or any combination of them - LDK provides a clean API, where objects can be serialized into simple binary blobs, and stored in any way you wish.

LDK's Persist docs (opens new window)

Sample module in Rust (opens new window)

- + diff --git a/introduction/private_key_management/index.html b/introduction/private_key_management/index.html index 74f3b8701..595d77dfc 100644 --- a/introduction/private_key_management/index.html +++ b/introduction/private_key_management/index.html @@ -29,7 +29,7 @@ - + @@ -57,7 +57,7 @@ GitHub (opens new window) GitHub - (opens new window)

# Private Key Management

LDK provides a default implementation for key management, but you can choose to provide private keys to LDK in any way you wish following a simple API. LDK even supports a generic API for signing transactions, allowing you to run LDK without any private keys in memory and/or putting private keys only on hardware wallets.

While LDK's default implementation is currently located within the rust-lightning crate, it is still considered a sample module.

LDK's KeysManager docs (opens new window).

- + diff --git a/introduction/random_number_generation/index.html b/introduction/random_number_generation/index.html index 68770c11b..f519011dd 100644 --- a/introduction/random_number_generation/index.html +++ b/introduction/random_number_generation/index.html @@ -29,7 +29,7 @@ - + @@ -57,7 +57,7 @@ GitHub (opens new window) GitHub - (opens new window)

# Random Number Generation

LDK aims to make no system calls, it is therefore restricted from generating its own randomness.

The sample node implementation uses Rust's rand crate here (opens new window) and elsewhere.

- + diff --git a/introduction/transactions/index.html b/introduction/transactions/index.html index 39dced0cc..df3177211 100644 --- a/introduction/transactions/index.html +++ b/introduction/transactions/index.html @@ -29,7 +29,7 @@ - + @@ -57,7 +57,7 @@ GitHub (opens new window) GitHub - (opens new window)

# Transactions

# Transaction Filtering

Clients running a light client may wish to filter for transactions on a separate server, in which case LDK will tell them about transactions to filter for.

LDK's Filter API reference (opens new window)

More information is available in the Blockchain Data guide.

# Fee Estimation

LDK let's you decide your source for fee estimation. This could be Bitcoin Core's fee estimation through estimatesmartfee RPC method or third-party fee-estimators (opens new window).

LDK's FeeEstimator docs (opens new window)

LDK's sample node implementation uses Bitcoin Core's fee estimation API here. (opens new window)

# Transaction Broadcasting

You can broadcast transactions in a few ways, using Bitcoin core or other external API's (opens new window)

LDK's BroadcasterInterface docs (opens new window)

LDK's sample node implementation uses Bitcoin Core's transaction broadcasting API here. (opens new window)

- + diff --git a/introduction/use-cases/index.html b/introduction/use-cases/index.html index 48cdfa9bc..cc5ab6921 100644 --- a/introduction/use-cases/index.html +++ b/introduction/use-cases/index.html @@ -31,7 +31,7 @@ - + @@ -85,7 +85,7 @@ business logic may be difficult with existing Lightning implementations focusing on standalone operation. For such transactors, LDK offers the possibility of integrating a library in their native runtime, storing and handling Lightning -data and events in the same way they do blockchain events.

- + diff --git a/introduction/wallet_management/index.html b/introduction/wallet_management/index.html index 8c3860daa..0bf682fae 100644 --- a/introduction/wallet_management/index.html +++ b/introduction/wallet_management/index.html @@ -29,7 +29,7 @@ - + @@ -57,7 +57,7 @@ GitHub (opens new window) GitHub - (opens new window)

# Wallet Management

LDK owns on-chain funds as long as they are claimable as a part of a Lightning output which can be contested - once a channel is closed and all on-chain outputs are spendable only by you, LDK provides you notifications that a UTXO is "yours" again and it is up to you to spend it as you wish.

Additionally, channel funding is accomplished with a generic API which notifies users of the output which needs to appear on-chain, which they can then create a transaction for. Once a transaction is created, LDK handles the rest. This is a large part of our API's goals - making it easier to integrate Lightning into existing on-chain wallets which have their own on-chain logic - without needing to move funds in and out of a separate Lightning wallet with on-chain transactions and a separate private key system.

LDK does not currently provide a sample wallet module, but its sample node implementation uses Bitcoin Core's wallet for UTXO management e.g. here (opens new window)

- + diff --git a/key_management/index.html b/key_management/index.html index ab6e96065..f62cf13a7 100644 --- a/key_management/index.html +++ b/key_management/index.html @@ -29,7 +29,7 @@ - + @@ -455,7 +455,7 @@ return myKeysManager!.inner.asSignerProvider().readChanSigner(reader: reader) } } -
- + diff --git a/language_bindings/index.html b/language_bindings/index.html index 021d3de21..e35aa4d61 100644 --- a/language_bindings/index.html +++ b/language_bindings/index.html @@ -29,7 +29,7 @@ - + @@ -57,7 +57,7 @@ GitHub (opens new window) GitHub - (opens new window)

# Language Bindings

TODO

state of language bindings on a per-language basis