├── .github └── workflows │ └── codeql-analysis.yml ├── .gitignore ├── LICENSE ├── README.md ├── btcpck.js ├── css ├── input_style.css ├── log.css ├── main.css ├── table.css └── tooltip.css ├── customMode.html ├── doc ├── img │ ├── auto_pilot_mode.png │ ├── connect.png │ ├── connectNode.png │ ├── createInvoice.png │ ├── image_screen.png │ ├── login.png │ └── signup.png └── tooltip │ ├── 34-35.png │ ├── 3400-3500.png │ ├── BR1a.png │ ├── C2a.png │ ├── C2b.png │ ├── Cx-RDx.png │ ├── FundingAsset.png │ ├── HTLC-1.png │ ├── HTLC-2.png │ ├── HTLC-3.png │ ├── HTLC-4.png │ ├── HTLC-5.png │ ├── funding_pubkey.png │ └── help.png ├── index.html ├── js ├── common.js └── qrcode.min.js ├── json ├── api_list.json ├── manage_asset.json ├── user_data_list.json └── util_list.json ├── log.html ├── sdk ├── auto_pilot.js ├── basic.js ├── btctool.js ├── content_tips.js ├── contracts.js ├── htlc.js ├── manage_asset.js ├── number_precision.js ├── obdapi.js ├── pojo.js ├── query.js ├── util.js └── wallet.js ├── ts ├── go.bat ├── number_precision.ts ├── obdapi.ts ├── pojo.ts └── tsconfig.json └── userData.html /.github/workflows/codeql-analysis.yml: -------------------------------------------------------------------------------- 1 | # For most projects, this workflow file will not need changing; you simply need 2 | # to commit it to your repository. 3 | # 4 | # You may wish to alter this file to override the set of languages analyzed, 5 | # or to provide custom queries or build logic. 6 | name: "CodeQL" 7 | 8 | on: 9 | push: 10 | branches: [master] 11 | pull_request: 12 | # The branches below must be a subset of the branches above 13 | branches: [master] 14 | schedule: 15 | - cron: '0 15 * * 6' 16 | 17 | jobs: 18 | analyze: 19 | name: Analyze 20 | runs-on: ubuntu-latest 21 | 22 | strategy: 23 | fail-fast: false 24 | matrix: 25 | # Override automatic language detection by changing the below list 26 | # Supported options are ['csharp', 'cpp', 'go', 'java', 'javascript', 'python'] 27 | language: ['javascript'] 28 | # Learn more... 29 | # https://docs.github.com/en/github/finding-security-vulnerabilities-and-errors-in-your-code/configuring-code-scanning#overriding-automatic-language-detection 30 | 31 | steps: 32 | - name: Checkout repository 33 | uses: actions/checkout@v2 34 | with: 35 | # We must fetch at least the immediate parents so that if this is 36 | # a pull request then we can checkout the head. 37 | fetch-depth: 2 38 | 39 | # If this run was triggered by a pull request event, then checkout 40 | # the head of the pull request instead of the merge commit. 41 | - run: git checkout HEAD^2 42 | if: ${{ github.event_name == 'pull_request' }} 43 | 44 | # Initializes the CodeQL tools for scanning. 45 | - name: Initialize CodeQL 46 | uses: github/codeql-action/init@v1 47 | with: 48 | languages: ${{ matrix.language }} 49 | # If you wish to specify custom queries, you can do so here or in a config file. 50 | # By default, queries listed here will override any specified in a config file. 51 | # Prefix the list here with "+" to use these queries and those in the config file. 52 | # queries: ./path/to/local/query, your-org/your-repo/queries@main 53 | 54 | # Autobuild attempts to build any compiled languages (C/C++, C#, or Java). 55 | # If this step fails, then you should remove it and run the build manually (see below) 56 | - name: Autobuild 57 | uses: github/codeql-action/autobuild@v1 58 | 59 | # ℹ️ Command-line programs to run using the OS shell. 60 | # 📚 https://git.io/JvXDl 61 | 62 | # ✏️ If the Autobuild fails above, remove it and uncomment the following three lines 63 | # and modify them (or add more) to build your code if your project 64 | # uses a compiled language 65 | 66 | #- run: | 67 | # make bootstrap 68 | # make release 69 | 70 | - name: Perform CodeQL Analysis 71 | uses: github/codeql-action/analyze@v1 72 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Compiled class file 2 | *.class 3 | 4 | # Log file 5 | *.log 6 | 7 | # BlueJ files 8 | *.ctxt 9 | 10 | # Mobile Tools for Java (J2ME) 11 | .mtj.tmp/ 12 | 13 | # Package Files # 14 | *.jar 15 | *.war 16 | *.nar 17 | *.ear 18 | *.zip 19 | *.tar.gz 20 | *.rar 21 | 22 | # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml 23 | hs_err_pid* 24 | 25 | # Visual Studio Code related 26 | .vscode/ 27 | 28 | # Miscellaneous 29 | .DS_Store -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 OmniLab 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # OBD GUI Tool 2 | [![](https://img.shields.io/badge/license-MIT-blue)](https://github.com/omnilaboratory/obd/blob/master/LICENSE) [![](https://img.shields.io/badge/standard%20readme-OK-brightgreen)](https://github.com/omnilaboratory/obd/blob/master/README.md) [![](https://img.shields.io/badge/protocol-OmniBOLT-brightgreen)](https://github.com/omnilaboratory/OmniBOLT-spec) 3 | [![](https://img.shields.io/badge/API%20V0.3-Document-blue)](https://api.omnilab.online) 4 | 5 | 6 | OmniBOLT Daemon Debugging Tool. This is a graphic user interface for developers. Every API on the left navigation tree has been defined in [api.omnilab.online](https://api.omnilab.online). This tool is in fact a lightning wallet. 7 | 8 | If you come to this tool in developing modules for OmniBOLT, you must have successfully installed and ran OBD on your local or remote machine. If you do not familiar with the whole process yet, we suggest you [install](https://github.com/omnilaboratory/obd#table-of-contents) OBD first and try to run it for a quick experience. 9 | 10 | In this tutorial, you can connect either your own OBD node, or the [nodes in the testnet](https://github.com/omnilaboratory/DebuggingTool#Nodes-in-testnet) we configured for our community. 11 | 12 | 13 |

14 | Debugging Tool Screenshot 15 |

16 | 17 | The latest document/tutorial has been moved to [GUI Playground](https://omnilaboratory.github.io/obd/#/GUI-tool). 18 | -------------------------------------------------------------------------------- /btcpck.js: -------------------------------------------------------------------------------- 1 | var bitcoin = require('bitcoinjs-lib') 2 | var bip39 = require('bip39') 3 | var buffer = require('buffer') 4 | const bip32 = require('bip32') 5 | 6 | 7 | function generateMnemonic(size = 128) { 8 | return bip39.generateMnemonic(size); 9 | } 10 | 11 | function validateMnemonic(mnemonic) { 12 | return bip39.validateMnemonic(mnemonic); 13 | } 14 | 15 | function generateWalletInfo(mnemonic, index, isTestNet = false) { 16 | let retNode = new Object(); 17 | 18 | if (validateMnemonic(mnemonic) == false) { 19 | retNode.status = false; 20 | retNode.msg = "error mnemonic: " + mnemonic; 21 | return retNode; 22 | } 23 | if (index == null || index < 0) { 24 | retNode.status = false; 25 | retNode.msg = "error index " + index; 26 | return retNode; 27 | } 28 | let seedHex = bip39.mnemonicToSeedSync(mnemonic, ""); 29 | let root = bip32.fromSeed(seedHex); 30 | let child0 = root.derivePath("m/44'/0'/" + index); 31 | let network = bitcoin.networks.bitcoin; 32 | networkName = "bitcoin" 33 | if (isTestNet) { 34 | child0 = root.derivePath("m/44'/1'/" + index); 35 | network = bitcoin.networks.testnet; 36 | networkName = "testnet" 37 | } 38 | let keyPair = bitcoin.ECPair.fromPrivateKey(child0.privateKey, { 39 | compressed: true, 40 | network: network 41 | }); 42 | 43 | let walletAddress = bitcoin.payments.p2pkh({ 44 | pubkey: child0.publicKey, 45 | network 46 | }).address; 47 | retNode.status = true; 48 | retNode.msg = "success"; 49 | retNode.result = { "index": index, "address": walletAddress, "pubkey": child0.publicKey.toString("hex"), "wif": keyPair.toWIF(), "network": networkName } 50 | return retNode 51 | } 52 | 53 | module.exports = { 54 | buffer, 55 | bitcoin, 56 | bip39, 57 | bip32, 58 | generateMnemonic, 59 | validateMnemonic, 60 | generateWalletInfo 61 | } -------------------------------------------------------------------------------- /css/input_style.css: -------------------------------------------------------------------------------- 1 | @supports (-webkit-appearance: none) or (-moz-appearance: none) { 2 | input[type='checkbox'], 3 | input[type='radio'] { 4 | --active: #275EFE; 5 | --active-inner: #fff; 6 | --focus: 2px rgba(39, 94, 254, .3); 7 | --border: #BBC1E1; 8 | --border-hover: #275EFE; 9 | --background: #fff; 10 | --disabled: #F6F8FF; 11 | --disabled-inner: #E1E6F9; 12 | -webkit-appearance: none; 13 | -moz-appearance: none; 14 | height: 21px; 15 | outline: none; 16 | display: inline-block; 17 | vertical-align: top; 18 | position: relative; 19 | margin: 0; 20 | cursor: pointer; 21 | border: 1px solid var(--bc, var(--border)); 22 | background: var(--b, var(--background)); 23 | -webkit-transition: background .3s, border-color .3s, box-shadow .2s; 24 | transition: background .3s, border-color .3s, box-shadow .2s; 25 | } 26 | input[type='checkbox']:after, 27 | input[type='radio']:after { 28 | content: ''; 29 | display: block; 30 | left: 0; 31 | top: 0; 32 | position: absolute; 33 | -webkit-transition: opacity var(--d-o, 0.2s), -webkit-transform var(--d-t, 0.3s) var(--d-t-e, ease); 34 | transition: opacity var(--d-o, 0.2s), -webkit-transform var(--d-t, 0.3s) var(--d-t-e, ease); 35 | transition: transform var(--d-t, 0.3s) var(--d-t-e, ease), opacity var(--d-o, 0.2s); 36 | transition: transform var(--d-t, 0.3s) var(--d-t-e, ease), opacity var(--d-o, 0.2s), -webkit-transform var(--d-t, 0.3s) var(--d-t-e, ease); 37 | } 38 | input[type='checkbox']:checked, 39 | input[type='radio']:checked { 40 | --b: var(--active); 41 | --bc: var(--active); 42 | --d-o: .3s; 43 | --d-t: .6s; 44 | --d-t-e: cubic-bezier(.2, .85, .32, 1.2); 45 | } 46 | input[type='checkbox']:disabled, 47 | input[type='radio']:disabled { 48 | --b: var(--disabled); 49 | cursor: not-allowed; 50 | opacity: .9; 51 | } 52 | input[type='checkbox']:disabled:checked, 53 | input[type='radio']:disabled:checked { 54 | --b: var(--disabled-inner); 55 | --bc: var(--border); 56 | } 57 | input[type='checkbox']:disabled + label, 58 | input[type='radio']:disabled + label { 59 | cursor: not-allowed; 60 | } 61 | input[type='checkbox']:hover:not(:checked):not(:disabled), 62 | input[type='radio']:hover:not(:checked):not(:disabled) { 63 | --bc: var(--border-hover); 64 | } 65 | input[type='checkbox']:focus, 66 | input[type='radio']:focus { 67 | box-shadow: 0 0 0 var(--focus); 68 | } 69 | input[type='checkbox']:not(.switch), 70 | input[type='radio']:not(.switch) { 71 | width: 21px; 72 | } 73 | input[type='checkbox']:not(.switch):after, 74 | input[type='radio']:not(.switch):after { 75 | opacity: var(--o, 0); 76 | } 77 | input[type='checkbox']:not(.switch):checked, 78 | input[type='radio']:not(.switch):checked { 79 | --o: 1; 80 | } 81 | input[type='checkbox'] + label, 82 | input[type='radio'] + label { 83 | font-size: 14px; 84 | line-height: 21px; 85 | display: inline-block; 86 | vertical-align: top; 87 | cursor: pointer; 88 | margin-left: 4px; 89 | } 90 | 91 | input[type='checkbox']:not(.switch) { 92 | border-radius: 7px; 93 | } 94 | input[type='checkbox']:not(.switch):after { 95 | width: 5px; 96 | height: 9px; 97 | border: 2px solid var(--active-inner); 98 | border-top: 0; 99 | border-left: 0; 100 | left: 7px; 101 | top: 4px; 102 | -webkit-transform: rotate(var(--r, 20deg)); 103 | transform: rotate(var(--r, 20deg)); 104 | } 105 | 106 | input[type='checkbox']:not(.switch):checked { 107 | --r: 43deg; 108 | } 109 | 110 | input[type='checkbox'].switch { 111 | margin-left: 10px; 112 | width: 46px; 113 | border-radius: 11px; 114 | } 115 | 116 | input[type='checkbox'].switch:after { 117 | left: 2px; 118 | top: 2px; 119 | border-radius: 50%; 120 | width: 15px; 121 | height: 15px; 122 | background: var(--ab, var(--border)); 123 | -webkit-transform: translateX(var(--x, 0)); 124 | transform: translateX(var(--x, 0)); 125 | } 126 | 127 | input[type='checkbox'].switch:checked { 128 | --ab: var(--active-inner); 129 | --x: 25px; 130 | } 131 | 132 | input[type='checkbox'].switch:disabled:not(:checked):after { 133 | opacity: .6; 134 | } 135 | 136 | input[type='radio'] { 137 | border-radius: 50%; 138 | } 139 | input[type='radio']:after { 140 | width: 19px; 141 | height: 19px; 142 | border-radius: 50%; 143 | background: var(--active-inner); 144 | opacity: 0; 145 | -webkit-transform: scale(var(--s, 0.7)); 146 | transform: scale(var(--s, 0.7)); 147 | } 148 | input[type='radio']:checked { 149 | --s: .5; 150 | } 151 | } -------------------------------------------------------------------------------- /css/log.css: -------------------------------------------------------------------------------- 1 | /* ---- FOR JSON FORMAT */ 2 | pre { 3 | background-color: #FFF; 4 | outline: 1px solid #ccc; 5 | padding: 15px; 6 | margin-left: 60px; 7 | margin-top: 50px; 8 | margin-bottom: 50px; 9 | width: 90%; 10 | /* height: 560px; */ 11 | font-size: 15px; 12 | overflow-y: auto; 13 | white-space: pre-wrap; 14 | word-wrap: break-word; 15 | } 16 | 17 | .string { color: green; } 18 | .number {color: darkorange; } 19 | .boolean { color: blue; } 20 | .null { color: magenta; } 21 | .key { color: red; font-weight: bold; } 22 | /* -------------- */ 23 | 24 | .top{ 25 | height: 60px; 26 | background: #1E222A; 27 | width: 89%; 28 | color: #FFF; 29 | line-height: 60px; 30 | font-size: 22px; 31 | font-weight: 600; 32 | padding-left: 20px; 33 | padding-right: 30px; 34 | margin-left: 60px; 35 | /* display: flex; */ 36 | } 37 | 38 | .topDataKey{ 39 | padding-left: 100px; 40 | font-size: 16px; 41 | font-weight: 300; 42 | } 43 | 44 | .topDataVal{ 45 | padding-left: 10px; 46 | font-size: 16px; 47 | font-weight: 600; 48 | } 49 | 50 | .copyright { 51 | background-color:#1E222A; 52 | color: #eeeff5; 53 | line-height: 50px; 54 | font-size: 20px; 55 | font-weight: 500; 56 | text-align:center; 57 | width: 92%; 58 | margin-left: 60px; 59 | /* height: 6%; */ 60 | } 61 | -------------------------------------------------------------------------------- /css/main.css: -------------------------------------------------------------------------------- 1 | html { 2 | height: 100%; 3 | } 4 | 5 | body { 6 | padding: 0; 7 | margin: 0; 8 | background: #FFF; 9 | width: 100%; 10 | height: 100%; 11 | /* min-width: 1180px; */ 12 | } 13 | 14 | a { text-decoration: none; } 15 | 16 | .api_description { 17 | word-break: normal; 18 | } 19 | 20 | .textarea { 21 | flex: 1; 22 | padding-left: 60px; 23 | display: flex; 24 | justify-content: space-between; 25 | color: #FFF; 26 | word-wrap:break-word; 27 | word-break:break-all; 28 | } 29 | 30 | /* ---- FOR JSON FORMAT */ 31 | pre { 32 | background-color: #FFF; 33 | outline: 1px solid #ccc; 34 | padding: 15px; 35 | margin-left: 60px; 36 | margin-top: 0px; 37 | /* width: 125%; */ 38 | /* width: 350px; */ 39 | height: 500px; 40 | overflow-y: auto; 41 | white-space: pre-wrap; 42 | word-wrap: break-word; 43 | } 44 | 45 | .string { color: green; } 46 | .number {color: darkorange; } 47 | .boolean { color: blue; } 48 | .null { color: magenta; } 49 | .key { color: red; font-weight: bold; } 50 | /* -------------- */ 51 | 52 | .custom_textarea { 53 | font-size: 15px; 54 | } 55 | 56 | .input { 57 | width: 160px; 58 | height: 25px; 59 | font-size: 15px; 60 | margin-left: 10px; 61 | } 62 | 63 | .input_node_url { 64 | width: 380px; 65 | height: 25px; 66 | font-size: 15px; 67 | margin-left: 10px; 68 | } 69 | 70 | .input_conn_node { 71 | width: 260px; 72 | height: 25px; 73 | font-size: 15px; 74 | margin-left: 10px; 75 | } 76 | 77 | .input_color { 78 | color: rgb(126, 109, 109); 79 | background: rgb(245, 239, 239); 80 | border-radius: 3px; 81 | border: 1px solid; 82 | } 83 | 84 | .disabled { 85 | cursor: not-allowed; 86 | } 87 | 88 | .button { 89 | background-color: white; 90 | border: 1px solid #1e222a; 91 | border-radius: 4px; 92 | color: #1e222a; 93 | text-align: center; 94 | transition-duration: 0.4s; 95 | } 96 | 97 | .button_small { 98 | padding: 6px 15px; 99 | font-size: 15px; 100 | margin-left: 15px; 101 | border-radius: 4px; 102 | } 103 | 104 | .button_big { 105 | padding: 8px 25px; 106 | font-size: 16px; 107 | margin-left: 30px; 108 | } 109 | 110 | .button_clear { 111 | padding: 7px 30px; 112 | font-size: 15px; 113 | margin-bottom: 20px; 114 | margin-left: 60px; 115 | } 116 | 117 | .button_log { 118 | margin-left: 30px; 119 | } 120 | 121 | .button_clear_history { 122 | padding: 6px 25px; 123 | font-size: 15px; 124 | margin-bottom: 10px; 125 | } 126 | 127 | .button_clear_cq { 128 | margin-left: 360px; 129 | } 130 | 131 | .button_request { 132 | padding: 8px 35px; 133 | font-size: 16px; 134 | margin-top: 5px; 135 | margin-bottom: 15px; 136 | } 137 | 138 | .button:hover { 139 | /* Green */ 140 | background-color: #4CAF50; 141 | border: 1px solid #dde0e7; 142 | color: white; 143 | cursor: pointer; 144 | } 145 | 146 | .url { 147 | color: #26272e; 148 | height: 25px; 149 | line-height: 25px; 150 | font-size: 16px; 151 | font-weight: 500; 152 | padding-top: 5px; 153 | padding-bottom: 5px; 154 | padding-left: 10px; 155 | padding-right: 10px; 156 | cursor: pointer; 157 | } 158 | 159 | .url:hover { 160 | background-color: rgb(65, 165, 247); 161 | /* border: 1px solid #e9ebf0; */ 162 | color: white; 163 | } 164 | 165 | .url_blue { 166 | color: #4f59a0; 167 | } 168 | 169 | .url_conn_history { 170 | color: #4f59a0; 171 | font-size: 15px; 172 | margin-left: -10px; 173 | } 174 | 175 | .url_red { 176 | color: #6799b1; 177 | border: 1px solid #6799b1; 178 | margin-right: 15px; 179 | } 180 | 181 | .url_red:hover { 182 | background-color: #8b3402; 183 | color: white; 184 | cursor: pointer; 185 | } 186 | 187 | .top{ 188 | height: 60px; 189 | background: #1E222A; 190 | width: 100%; 191 | display: flex; 192 | } 193 | 194 | .topLeft{ 195 | color: #FFF; 196 | height: 60px; 197 | line-height: 60px; 198 | font-size: 22px; 199 | font-weight: 600; 200 | width: 220px; 201 | /* width: 15%; */ 202 | padding-left: 20px; 203 | /* padding-right: 20px; */ 204 | /* margin-right: 20px; */ 205 | } 206 | 207 | .topRight{ 208 | flex: 1; 209 | height: 60px; 210 | padding-left: 20px; 211 | padding-right: 30px; 212 | display: flex; 213 | align-items: center; 214 | justify-content: space-between; 215 | color: #FFF; 216 | font-size: 16px; 217 | } 218 | 219 | .topData{ 220 | display: flex; 221 | } 222 | 223 | .topDataKey{ 224 | padding-left: 30px; 225 | } 226 | 227 | .topDataVal{ 228 | padding-left: 10px; 229 | font-weight: 600; 230 | } 231 | 232 | .main{ 233 | background: #f5f6f8; 234 | padding: 30px 30px 30px 20px; 235 | display: flex; 236 | /* width: 100%; */ 237 | /* height: 100%; */ 238 | } 239 | 240 | .leftSide{ 241 | background: #f5f6f8; 242 | margin-top: -20px; 243 | margin-right: 30px; 244 | padding-left: 30px; 245 | padding-right: 10px; 246 | /* width: 180px; */ 247 | width: 13%; 248 | height: 900px; 249 | overflow: auto; 250 | } 251 | 252 | .request_div { 253 | /* width: 700px; */ 254 | width: 52%; 255 | /* margin-left: 0px; */ 256 | } 257 | 258 | .custom_request_div{ 259 | width: 48%; 260 | /* width: 650px; */ 261 | /* padding-left: 30px; */ 262 | /* padding-right: 50px; */ 263 | margin-left: 50px; 264 | } 265 | 266 | .obd_messages_div { 267 | width: 30%; 268 | } 269 | 270 | .copyright { 271 | background-color:#1E222A; 272 | color: #eeeff5; 273 | line-height: 50px; 274 | font-size: 20px; 275 | font-weight: 500; 276 | text-align:center; 277 | /* height: 60px; */ 278 | /* margin-top: 50px; */ 279 | } 280 | 281 | .bigText { 282 | color: #26272e; 283 | line-height: 30px; 284 | font-size: 16px; 285 | font-weight: 500; 286 | } 287 | 288 | .funcText { 289 | color: #26272e; 290 | line-height: 25px; 291 | font-size: 18px; 292 | font-weight: 600; 293 | padding-left: 15px; 294 | padding-right: 15px; 295 | } 296 | 297 | .responseText { 298 | color: #26272e; 299 | line-height: 25px; 300 | font-weight: 500; 301 | padding-left: 15px; 302 | } 303 | 304 | .menuTitle{ 305 | height: 30px; 306 | line-height: 30px; 307 | color: #9195a5; 308 | cursor: default; 309 | padding-top: 20px; 310 | padding-bottom: 10px; 311 | } 312 | 313 | .panelItem{ 314 | background: #fff; 315 | -webkit-box-shadow: 0 2px 20px 0 rgba(0, 0, 0, 0.05); 316 | box-shadow: 0 2px 20px 0 rgba(0, 0, 0, 0.05); 317 | border-radius: 6px; 318 | padding: 5px 30px; 319 | padding-bottom: 20px; 320 | margin-bottom: 20px; 321 | color: #9195a5; 322 | word-wrap:break-word; 323 | word-break:break-all; 324 | } 325 | 326 | .panelTitle{ 327 | color: #45474e; 328 | font-weight: 600; 329 | margin-top: -10px; 330 | } 331 | 332 | .str_invoice { 333 | margin-left:30px; 334 | margin-right:30px; 335 | margin-top:30px; 336 | } 337 | 338 | .qrcode { 339 | height:200px; 340 | margin-left:200px; 341 | margin-top:50px; 342 | } 343 | 344 | .invoice_payment { 345 | color: #26272e; 346 | font-size: 18px; 347 | font-weight: 600; 348 | padding-right: 25px; 349 | } 350 | 351 | .tooltip_area { 352 | height: 50px; 353 | background: #dae0a3; 354 | width: 100%; 355 | display: flex; 356 | align-items: center; 357 | } 358 | 359 | .header { 360 | width: 100%; 361 | position: relative; 362 | z-index: 999; 363 | } 364 | 365 | .header-active{ 366 | position: fixed; 367 | top: 0; 368 | } 369 | 370 | .resp_area { 371 | background: #dae0a3; 372 | padding: 20px; 373 | /* display: flex; */ 374 | /* align-items: center; */ 375 | 376 | box-shadow: 0 2px 20px 0 rgba(0, 0, 0, 0.05); 377 | border-radius: 6px; 378 | word-wrap:break-word; 379 | word-break:break-all; 380 | } 381 | -------------------------------------------------------------------------------- /css/table.css: -------------------------------------------------------------------------------- 1 | #tracker 2 | { 3 | /* font-family:"Trebuchet MS", Arial, Helvetica, sans-serif; */ 4 | width:100%; 5 | border-collapse:collapse; 6 | } 7 | 8 | #tracker td, #tracker th 9 | { 10 | font-size:13px; 11 | border:1px solid #a9aaa7; 12 | padding:10px 10px 10px 10px; 13 | vertical-align: middle; 14 | word-wrap:break-word; 15 | word-break:break-all; 16 | text-align: center; 17 | } 18 | 19 | #tracker th 20 | { 21 | /* font-size:13px; */ 22 | padding-top:8px; 23 | padding-bottom:8px; 24 | background-color:rgb(78, 81, 87); 25 | color:#ffffff; 26 | text-align: center; 27 | } 28 | 29 | #tracker tr.alt td 30 | { 31 | color:#000000; 32 | background-color:rgb(214, 236, 223); 33 | } 34 | 35 | tr.change_color:hover { 36 | background-color:rgb(13, 126, 60); 37 | cursor: pointer; 38 | } 39 | 40 | .col_1_width{ 41 | width: 20px; 42 | } 43 | 44 | .col_2_width{ 45 | width: 36px; 46 | } 47 | 48 | .col_3_width{ 49 | width: 50px; 50 | } 51 | 52 | .col_4_width{ 53 | width: 68px; 54 | } 55 | 56 | .col_5_width{ 57 | width: 110px; 58 | } 59 | 60 | .col_6_width{ 61 | width: 280px; 62 | } 63 | 64 | .bottom_div { 65 | margin-top: 30px; 66 | font-size: 15px; 67 | /* position: absolute; */ 68 | position: fixed; 69 | bottom: 30px; 70 | } 71 | 72 | .margin_right { 73 | margin-right: 50px; 74 | } 75 | 76 | .bottom_margin { 77 | margin-bottom: 10px; 78 | } 79 | -------------------------------------------------------------------------------- /css/tooltip.css: -------------------------------------------------------------------------------- 1 | .wrapper { 2 | padding-left: 10px; 3 | font-weight: 600; 4 | position: relative; 5 | } 6 | 7 | .wrapper .tooltip { 8 | background: #093c49; 9 | /*bottom: 100%;*/ 10 | top: 100%; 11 | color: rgb(102, 221, 55); 12 | display: block; 13 | left: -100px; 14 | /* margin-bottom: 15px; */ 15 | margin-top: 15px; 16 | opacity: 0; 17 | padding: 20px; 18 | pointer-events: none; 19 | position: absolute; 20 | /* width: 100%; */ 21 | width: 260px; 22 | /* height: 100%; */ 23 | -webkit-transform: translateY(10px); 24 | -moz-transform: translateY(10px); 25 | -ms-transform: translateY(10px); 26 | -o-transform: translateY(10px); 27 | transform: translateY(10px); 28 | -webkit-transition: all .25s ease-out; 29 | -moz-transition: all .25s ease-out; 30 | -ms-transition: all .25s ease-out; 31 | -o-transition: all .25s ease-out; 32 | transition: all .25s ease-out; 33 | -webkit-box-shadow: 2px 2px 6px rgba(0, 0, 0, 0.28); 34 | -moz-box-shadow: 2px 2px 6px rgba(0, 0, 0, 0.28); 35 | -ms-box-shadow: 2px 2px 6px rgba(0, 0, 0, 0.28); 36 | -o-box-shadow: 2px 2px 6px rgba(0, 0, 0, 0.28); 37 | box-shadow: 2px 2px 6px rgba(0, 0, 0, 0.28); 38 | } 39 | 40 | /* This bridges the gap so you can mouse into the tooltip without it disappearing */ 41 | .wrapper .tooltip:before { 42 | /* bottom: -20px; */ 43 | top: -20px; 44 | content: " "; 45 | display: block; 46 | height: 20px; 47 | left: 0; 48 | position: absolute; 49 | width: 100%; 50 | } 51 | 52 | /* CSS Triangles - see Trevor's post */ 53 | .wrapper .tooltip:after { 54 | border-left: solid transparent 10px; 55 | border-right: solid transparent 10px; 56 | /* border-top: solid #1496bb 10px; */ 57 | /* border-bottom: solid #1496bb 10px; */ 58 | border-bottom: solid #093c49 10px; 59 | /* bottom: -10px; */ 60 | top: -10px; 61 | content: " "; 62 | height: 0; 63 | left: 50%; 64 | margin-left: -13px; 65 | position: absolute; 66 | width: 0; 67 | } 68 | 69 | .wrapper:hover .tooltip { 70 | opacity: 1; 71 | pointer-events: auto; 72 | -webkit-transform: translateY(0px); 73 | -moz-transform: translateY(0px); 74 | -ms-transform: translateY(0px); 75 | -o-transform: translateY(0px); 76 | transform: translateY(0px); 77 | } 78 | 79 | .wrapper .tooltip_help { 80 | background: #093c49; 81 | top: 100%; 82 | color: rgb(102, 221, 55); 83 | display: block; 84 | left: -32px; 85 | margin-top: -6px; 86 | opacity: 0; 87 | padding: 20px; 88 | pointer-events: none; 89 | position: absolute; 90 | z-index: 1; 91 | width: 500px; 92 | word-break: normal; 93 | transform: translateY(10px); 94 | transition: all .25s ease-out; 95 | box-shadow: 2px 2px 6px rgba(0, 0, 0, 0.28); 96 | } 97 | 98 | /* This bridges the gap so you can mouse into the tooltip without it disappearing */ 99 | .wrapper .tooltip_help:before { 100 | top: -20px; 101 | content: " "; 102 | display: block; 103 | height: 20px; 104 | left: 0; 105 | position: absolute; 106 | width: 100%; 107 | } 108 | 109 | /* CSS Triangles - see Trevor's post */ 110 | .wrapper .tooltip_help:after { 111 | border-left: solid transparent 10px; 112 | border-right: solid transparent 10px; 113 | border-bottom: solid #093c49 10px; 114 | top: -10px; 115 | content: " "; 116 | height: 0; 117 | left: 47px; 118 | /* left: 20%; */ 119 | margin-left: -13px; 120 | position: absolute; 121 | width: 0; 122 | } 123 | 124 | .wrapper:hover .tooltip_help { 125 | opacity: 1; 126 | pointer-events: auto; 127 | transform: translateY(0px); 128 | } 129 | 130 | /* ==================== */ 131 | /* for .fa.fa-info-circle */ 132 | /* for Auto Pilot tooltip */ 133 | .wrapper .info_icon { 134 | background: #093c49; 135 | top: 100%; 136 | color: rgb(102, 221, 55); 137 | display: block; 138 | left: -30px; 139 | margin-top: 10px; 140 | opacity: 0; 141 | padding: 20px; 142 | pointer-events: none; 143 | position: absolute; 144 | z-index: 1; 145 | width: 220px; 146 | word-break: normal; 147 | transform: translateY(10px); 148 | transition: all .25s ease-out; 149 | box-shadow: 2px 2px 6px rgba(0, 0, 0, 0.28); 150 | } 151 | 152 | /* This bridges the gap so you can mouse into the tooltip without it disappearing */ 153 | .wrapper .info_icon:before { 154 | top: -20px; 155 | content: " "; 156 | display: block; 157 | height: 20px; 158 | left: 0; 159 | position: absolute; 160 | width: 100%; 161 | } 162 | 163 | /* CSS Triangles - see Trevor's post */ 164 | .wrapper .info_icon:after { 165 | border-left: solid transparent 10px; 166 | border-right: solid transparent 10px; 167 | border-bottom: solid #093c49 10px; 168 | top: -10px; 169 | content: " "; 170 | height: 0; 171 | left: 25px; 172 | /* left: 20%; */ 173 | margin-left: -13px; 174 | position: absolute; 175 | width: 0; 176 | } 177 | 178 | .wrapper:hover .info_icon { 179 | opacity: 1; 180 | pointer-events: auto; 181 | transform: translateY(0px); 182 | } 183 | /* ======================= */ 184 | 185 | .parent_div { 186 | display: flex; 187 | } 188 | 189 | .btn_help { 190 | margin-top: 2px; 191 | margin-right: 10px; 192 | margin-left: -13px; 193 | 194 | /* width: 30px; 195 | height: 30px; 196 | vertical-align: bottom; 197 | padding-right: 10px; */ 198 | } 199 | 200 | .auto_pilot_help { 201 | margin-top: 15px; 202 | margin-right: 10px; 203 | margin-left: -33px; 204 | } 205 | 206 | 207 | .auto_mode { 208 | font-size: 17px; 209 | font-weight: 600; 210 | margin-top: 20px; 211 | } 212 | 213 | .fa.fa-info-circle { 214 | font-size: 21px; 215 | color: rgb(92, 92, 202); 216 | /* margin-top: 20px; 217 | margin-right: 10px; 218 | margin-left: -25px; */ 219 | } 220 | 221 | .fa_pos { 222 | margin-top: 20px; 223 | margin-right: 10px; 224 | margin-left: -25px; 225 | } 226 | 227 | 228 | /* ==================== */ 229 | /* For display Channel List at top right */ 230 | .wrapper .channel_list { 231 | background: #093c49; 232 | top: 100%; 233 | color: rgb(102, 221, 55); 234 | display: block; 235 | left: -530px; 236 | margin-top: 15px; 237 | opacity: 0; 238 | padding: 20px; 239 | pointer-events: none; 240 | position: absolute; 241 | z-index: 1; 242 | width: 600px; 243 | height: 460px; 244 | word-break: normal; 245 | transform: translateY(10px); 246 | transition: all .25s ease-out; 247 | box-shadow: 2px 2px 6px rgba(0, 0, 0, 0.28); 248 | } 249 | 250 | /* This bridges the gap so you can mouse into the tooltip without it disappearing */ 251 | .wrapper .channel_list:before { 252 | top: -20px; 253 | content: " "; 254 | display: block; 255 | height: 20px; 256 | left: 0; 257 | position: absolute; 258 | width: 100%; 259 | } 260 | 261 | /* CSS Triangles - see Trevor's post */ 262 | .wrapper .channel_list:after { 263 | border-left: solid transparent 10px; 264 | border-right: solid transparent 10px; 265 | border-bottom: solid #093c49 10px; 266 | top: -10px; 267 | content: " "; 268 | height: 0; 269 | left: 580px; 270 | margin-left: -13px; 271 | position: absolute; 272 | width: 0; 273 | } 274 | 275 | .wrapper:hover .channel_list { 276 | opacity: 1; 277 | pointer-events: auto; 278 | transform: translateY(0px); 279 | } 280 | /* ======================= */ -------------------------------------------------------------------------------- /customMode.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Custom Mode 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 |
21 |
OBD Debug Tool
22 |
23 |
24 |
Status:
25 |
26 |
27 |
28 |
Logged In:
29 |
No One
30 |
31 | 32 | 36 |
37 |
38 | 39 | 40 |
41 | 42 | 45 | 46 | 47 |
48 | 49 |
50 | 51 | 52 |
53 | 54 | 55 |
56 |
57 |
58 | 59 | 60 | 61 | 62 | 63 | 69 | 70 | -------------------------------------------------------------------------------- /doc/img/auto_pilot_mode.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/omnilaboratory/DebuggingTool/948119d41915eb17439c218672a0b72bd04ad91d/doc/img/auto_pilot_mode.png -------------------------------------------------------------------------------- /doc/img/connect.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/omnilaboratory/DebuggingTool/948119d41915eb17439c218672a0b72bd04ad91d/doc/img/connect.png -------------------------------------------------------------------------------- /doc/img/connectNode.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/omnilaboratory/DebuggingTool/948119d41915eb17439c218672a0b72bd04ad91d/doc/img/connectNode.png -------------------------------------------------------------------------------- /doc/img/createInvoice.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/omnilaboratory/DebuggingTool/948119d41915eb17439c218672a0b72bd04ad91d/doc/img/createInvoice.png -------------------------------------------------------------------------------- /doc/img/image_screen.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/omnilaboratory/DebuggingTool/948119d41915eb17439c218672a0b72bd04ad91d/doc/img/image_screen.png -------------------------------------------------------------------------------- /doc/img/login.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/omnilaboratory/DebuggingTool/948119d41915eb17439c218672a0b72bd04ad91d/doc/img/login.png -------------------------------------------------------------------------------- /doc/img/signup.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/omnilaboratory/DebuggingTool/948119d41915eb17439c218672a0b72bd04ad91d/doc/img/signup.png -------------------------------------------------------------------------------- /doc/tooltip/34-35.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/omnilaboratory/DebuggingTool/948119d41915eb17439c218672a0b72bd04ad91d/doc/tooltip/34-35.png -------------------------------------------------------------------------------- /doc/tooltip/3400-3500.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/omnilaboratory/DebuggingTool/948119d41915eb17439c218672a0b72bd04ad91d/doc/tooltip/3400-3500.png -------------------------------------------------------------------------------- /doc/tooltip/BR1a.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/omnilaboratory/DebuggingTool/948119d41915eb17439c218672a0b72bd04ad91d/doc/tooltip/BR1a.png -------------------------------------------------------------------------------- /doc/tooltip/C2a.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/omnilaboratory/DebuggingTool/948119d41915eb17439c218672a0b72bd04ad91d/doc/tooltip/C2a.png -------------------------------------------------------------------------------- /doc/tooltip/C2b.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/omnilaboratory/DebuggingTool/948119d41915eb17439c218672a0b72bd04ad91d/doc/tooltip/C2b.png -------------------------------------------------------------------------------- /doc/tooltip/Cx-RDx.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/omnilaboratory/DebuggingTool/948119d41915eb17439c218672a0b72bd04ad91d/doc/tooltip/Cx-RDx.png -------------------------------------------------------------------------------- /doc/tooltip/FundingAsset.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/omnilaboratory/DebuggingTool/948119d41915eb17439c218672a0b72bd04ad91d/doc/tooltip/FundingAsset.png -------------------------------------------------------------------------------- /doc/tooltip/HTLC-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/omnilaboratory/DebuggingTool/948119d41915eb17439c218672a0b72bd04ad91d/doc/tooltip/HTLC-1.png -------------------------------------------------------------------------------- /doc/tooltip/HTLC-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/omnilaboratory/DebuggingTool/948119d41915eb17439c218672a0b72bd04ad91d/doc/tooltip/HTLC-2.png -------------------------------------------------------------------------------- /doc/tooltip/HTLC-3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/omnilaboratory/DebuggingTool/948119d41915eb17439c218672a0b72bd04ad91d/doc/tooltip/HTLC-3.png -------------------------------------------------------------------------------- /doc/tooltip/HTLC-4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/omnilaboratory/DebuggingTool/948119d41915eb17439c218672a0b72bd04ad91d/doc/tooltip/HTLC-4.png -------------------------------------------------------------------------------- /doc/tooltip/HTLC-5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/omnilaboratory/DebuggingTool/948119d41915eb17439c218672a0b72bd04ad91d/doc/tooltip/HTLC-5.png -------------------------------------------------------------------------------- /doc/tooltip/funding_pubkey.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/omnilaboratory/DebuggingTool/948119d41915eb17439c218672a0b72bd04ad91d/doc/tooltip/funding_pubkey.png -------------------------------------------------------------------------------- /doc/tooltip/help.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/omnilaboratory/DebuggingTool/948119d41915eb17439c218672a0b72bd04ad91d/doc/tooltip/help.png -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | OBD Debugging Tool 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 |
32 | 33 |
34 | 35 |
36 |
OBD Debug Tool
37 |
38 |
39 |
Status:
40 |
41 |
42 |
43 |
Logged In:
44 |
No One
45 |
46 |
47 |
48 |
49 |
You need to login.
50 |
51 |
52 |
53 |
54 |
55 | 56 | 57 |
58 |
In Channel:
59 |
Not Logged in
60 |
Next Step:
61 |
62 |
63 |
64 |
65 | 66 | 67 |
68 | 69 | 114 | 115 | 116 |
117 | 118 |
119 |
120 | 121 | 122 |
123 | 124 | 125 |
126 |
127 |
128 | 129 | 130 | 131 |
132 | 133 | 134 | 146 | 147 | -------------------------------------------------------------------------------- /js/qrcode.min.js: -------------------------------------------------------------------------------- 1 | var QRCode;!function(){function a(a){this.mode=c.MODE_8BIT_BYTE,this.data=a,this.parsedData=[];for(var b=[],d=0,e=this.data.length;e>d;d++){var f=this.data.charCodeAt(d);f>65536?(b[0]=240|(1835008&f)>>>18,b[1]=128|(258048&f)>>>12,b[2]=128|(4032&f)>>>6,b[3]=128|63&f):f>2048?(b[0]=224|(61440&f)>>>12,b[1]=128|(4032&f)>>>6,b[2]=128|63&f):f>128?(b[0]=192|(1984&f)>>>6,b[1]=128|63&f):b[0]=f,this.parsedData=this.parsedData.concat(b)}this.parsedData.length!=this.data.length&&(this.parsedData.unshift(191),this.parsedData.unshift(187),this.parsedData.unshift(239))}function b(a,b){this.typeNumber=a,this.errorCorrectLevel=b,this.modules=null,this.moduleCount=0,this.dataCache=null,this.dataList=[]}function i(a,b){if(void 0==a.length)throw new Error(a.length+"/"+b);for(var c=0;c=f;f++){var h=0;switch(b){case d.L:h=l[f][0];break;case d.M:h=l[f][1];break;case d.Q:h=l[f][2];break;case d.H:h=l[f][3]}if(h>=e)break;c++}if(c>l.length)throw new Error("Too long data");return c}function s(a){var b=encodeURI(a).toString().replace(/\%[0-9a-fA-F]{2}/g,"a");return b.length+(b.length!=a?3:0)}a.prototype={getLength:function(){return this.parsedData.length},write:function(a){for(var b=0,c=this.parsedData.length;c>b;b++)a.put(this.parsedData[b],8)}},b.prototype={addData:function(b){var c=new a(b);this.dataList.push(c),this.dataCache=null},isDark:function(a,b){if(0>a||this.moduleCount<=a||0>b||this.moduleCount<=b)throw new Error(a+","+b);return this.modules[a][b]},getModuleCount:function(){return this.moduleCount},make:function(){this.makeImpl(!1,this.getBestMaskPattern())},makeImpl:function(a,c){this.moduleCount=4*this.typeNumber+17,this.modules=new Array(this.moduleCount);for(var d=0;d=7&&this.setupTypeNumber(a),null==this.dataCache&&(this.dataCache=b.createData(this.typeNumber,this.errorCorrectLevel,this.dataList)),this.mapData(this.dataCache,c)},setupPositionProbePattern:function(a,b){for(var c=-1;7>=c;c++)if(!(-1>=a+c||this.moduleCount<=a+c))for(var d=-1;7>=d;d++)-1>=b+d||this.moduleCount<=b+d||(this.modules[a+c][b+d]=c>=0&&6>=c&&(0==d||6==d)||d>=0&&6>=d&&(0==c||6==c)||c>=2&&4>=c&&d>=2&&4>=d?!0:!1)},getBestMaskPattern:function(){for(var a=0,b=0,c=0;8>c;c++){this.makeImpl(!0,c);var d=f.getLostPoint(this);(0==c||a>d)&&(a=d,b=c)}return b},createMovieClip:function(a,b,c){var d=a.createEmptyMovieClip(b,c),e=1;this.make();for(var f=0;f=g;g++)for(var h=-2;2>=h;h++)this.modules[d+g][e+h]=-2==g||2==g||-2==h||2==h||0==g&&0==h?!0:!1}},setupTypeNumber:function(a){for(var b=f.getBCHTypeNumber(this.typeNumber),c=0;18>c;c++){var d=!a&&1==(1&b>>c);this.modules[Math.floor(c/3)][c%3+this.moduleCount-8-3]=d}for(var c=0;18>c;c++){var d=!a&&1==(1&b>>c);this.modules[c%3+this.moduleCount-8-3][Math.floor(c/3)]=d}},setupTypeInfo:function(a,b){for(var c=this.errorCorrectLevel<<3|b,d=f.getBCHTypeInfo(c),e=0;15>e;e++){var g=!a&&1==(1&d>>e);6>e?this.modules[e][8]=g:8>e?this.modules[e+1][8]=g:this.modules[this.moduleCount-15+e][8]=g}for(var e=0;15>e;e++){var g=!a&&1==(1&d>>e);8>e?this.modules[8][this.moduleCount-e-1]=g:9>e?this.modules[8][15-e-1+1]=g:this.modules[8][15-e-1]=g}this.modules[this.moduleCount-8][8]=!a},mapData:function(a,b){for(var c=-1,d=this.moduleCount-1,e=7,g=0,h=this.moduleCount-1;h>0;h-=2)for(6==h&&h--;;){for(var i=0;2>i;i++)if(null==this.modules[d][h-i]){var j=!1;g>>e));var k=f.getMask(b,d,h-i);k&&(j=!j),this.modules[d][h-i]=j,e--,-1==e&&(g++,e=7)}if(d+=c,0>d||this.moduleCount<=d){d-=c,c=-c;break}}}},b.PAD0=236,b.PAD1=17,b.createData=function(a,c,d){for(var e=j.getRSBlocks(a,c),g=new k,h=0;h8*l)throw new Error("code length overflow. ("+g.getLengthInBits()+">"+8*l+")");for(g.getLengthInBits()+4<=8*l&&g.put(0,4);0!=g.getLengthInBits()%8;)g.putBit(!1);for(;;){if(g.getLengthInBits()>=8*l)break;if(g.put(b.PAD0,8),g.getLengthInBits()>=8*l)break;g.put(b.PAD1,8)}return b.createBytes(g,e)},b.createBytes=function(a,b){for(var c=0,d=0,e=0,g=new Array(b.length),h=new Array(b.length),j=0;j=0?p.get(q):0}}for(var r=0,m=0;mm;m++)for(var j=0;jm;m++)for(var j=0;j=0;)b^=f.G15<=0;)b^=f.G18<>>=1;return b},getPatternPosition:function(a){return f.PATTERN_POSITION_TABLE[a-1]},getMask:function(a,b,c){switch(a){case e.PATTERN000:return 0==(b+c)%2;case e.PATTERN001:return 0==b%2;case e.PATTERN010:return 0==c%3;case e.PATTERN011:return 0==(b+c)%3;case e.PATTERN100:return 0==(Math.floor(b/2)+Math.floor(c/3))%2;case e.PATTERN101:return 0==b*c%2+b*c%3;case e.PATTERN110:return 0==(b*c%2+b*c%3)%2;case e.PATTERN111:return 0==(b*c%3+(b+c)%2)%2;default:throw new Error("bad maskPattern:"+a)}},getErrorCorrectPolynomial:function(a){for(var b=new i([1],0),c=0;a>c;c++)b=b.multiply(new i([1,g.gexp(c)],0));return b},getLengthInBits:function(a,b){if(b>=1&&10>b)switch(a){case c.MODE_NUMBER:return 10;case c.MODE_ALPHA_NUM:return 9;case c.MODE_8BIT_BYTE:return 8;case c.MODE_KANJI:return 8;default:throw new Error("mode:"+a)}else if(27>b)switch(a){case c.MODE_NUMBER:return 12;case c.MODE_ALPHA_NUM:return 11;case c.MODE_8BIT_BYTE:return 16;case c.MODE_KANJI:return 10;default:throw new Error("mode:"+a)}else{if(!(41>b))throw new Error("type:"+b);switch(a){case c.MODE_NUMBER:return 14;case c.MODE_ALPHA_NUM:return 13;case c.MODE_8BIT_BYTE:return 16;case c.MODE_KANJI:return 12;default:throw new Error("mode:"+a)}}},getLostPoint:function(a){for(var b=a.getModuleCount(),c=0,d=0;b>d;d++)for(var e=0;b>e;e++){for(var f=0,g=a.isDark(d,e),h=-1;1>=h;h++)if(!(0>d+h||d+h>=b))for(var i=-1;1>=i;i++)0>e+i||e+i>=b||(0!=h||0!=i)&&g==a.isDark(d+h,e+i)&&f++;f>5&&(c+=3+f-5)}for(var d=0;b-1>d;d++)for(var e=0;b-1>e;e++){var j=0;a.isDark(d,e)&&j++,a.isDark(d+1,e)&&j++,a.isDark(d,e+1)&&j++,a.isDark(d+1,e+1)&&j++,(0==j||4==j)&&(c+=3)}for(var d=0;b>d;d++)for(var e=0;b-6>e;e++)a.isDark(d,e)&&!a.isDark(d,e+1)&&a.isDark(d,e+2)&&a.isDark(d,e+3)&&a.isDark(d,e+4)&&!a.isDark(d,e+5)&&a.isDark(d,e+6)&&(c+=40);for(var e=0;b>e;e++)for(var d=0;b-6>d;d++)a.isDark(d,e)&&!a.isDark(d+1,e)&&a.isDark(d+2,e)&&a.isDark(d+3,e)&&a.isDark(d+4,e)&&!a.isDark(d+5,e)&&a.isDark(d+6,e)&&(c+=40);for(var k=0,e=0;b>e;e++)for(var d=0;b>d;d++)a.isDark(d,e)&&k++;var l=Math.abs(100*k/b/b-50)/5;return c+=10*l}},g={glog:function(a){if(1>a)throw new Error("glog("+a+")");return g.LOG_TABLE[a]},gexp:function(a){for(;0>a;)a+=255;for(;a>=256;)a-=255;return g.EXP_TABLE[a]},EXP_TABLE:new Array(256),LOG_TABLE:new Array(256)},h=0;8>h;h++)g.EXP_TABLE[h]=1<h;h++)g.EXP_TABLE[h]=g.EXP_TABLE[h-4]^g.EXP_TABLE[h-5]^g.EXP_TABLE[h-6]^g.EXP_TABLE[h-8];for(var h=0;255>h;h++)g.LOG_TABLE[g.EXP_TABLE[h]]=h;i.prototype={get:function(a){return this.num[a]},getLength:function(){return this.num.length},multiply:function(a){for(var b=new Array(this.getLength()+a.getLength()-1),c=0;cf;f++)for(var g=c[3*f+0],h=c[3*f+1],i=c[3*f+2],k=0;g>k;k++)e.push(new j(h,i));return e},j.getRsBlockTable=function(a,b){switch(b){case d.L:return j.RS_BLOCK_TABLE[4*(a-1)+0];case d.M:return j.RS_BLOCK_TABLE[4*(a-1)+1];case d.Q:return j.RS_BLOCK_TABLE[4*(a-1)+2];case d.H:return j.RS_BLOCK_TABLE[4*(a-1)+3];default:return void 0}},k.prototype={get:function(a){var b=Math.floor(a/8);return 1==(1&this.buffer[b]>>>7-a%8)},put:function(a,b){for(var c=0;b>c;c++)this.putBit(1==(1&a>>>b-c-1))},getLengthInBits:function(){return this.length},putBit:function(a){var b=Math.floor(this.length/8);this.buffer.length<=b&&this.buffer.push(0),a&&(this.buffer[b]|=128>>>this.length%8),this.length++}};var l=[[17,14,11,7],[32,26,20,14],[53,42,32,24],[78,62,46,34],[106,84,60,44],[134,106,74,58],[154,122,86,64],[192,152,108,84],[230,180,130,98],[271,213,151,119],[321,251,177,137],[367,287,203,155],[425,331,241,177],[458,362,258,194],[520,412,292,220],[586,450,322,250],[644,504,364,280],[718,560,394,310],[792,624,442,338],[858,666,482,382],[929,711,509,403],[1003,779,565,439],[1091,857,611,461],[1171,911,661,511],[1273,997,715,535],[1367,1059,751,593],[1465,1125,805,625],[1528,1190,868,658],[1628,1264,908,698],[1732,1370,982,742],[1840,1452,1030,790],[1952,1538,1112,842],[2068,1628,1168,898],[2188,1722,1228,958],[2303,1809,1283,983],[2431,1911,1351,1051],[2563,1989,1423,1093],[2699,2099,1499,1139],[2809,2213,1579,1219],[2953,2331,1663,1273]],o=function(){var a=function(a,b){this._el=a,this._htOption=b};return a.prototype.draw=function(a){function g(a,b){var c=document.createElementNS("http://www.w3.org/2000/svg",a);for(var d in b)b.hasOwnProperty(d)&&c.setAttribute(d,b[d]);return c}var b=this._htOption,c=this._el,d=a.getModuleCount();Math.floor(b.width/d),Math.floor(b.height/d),this.clear();var h=g("svg",{viewBox:"0 0 "+String(d)+" "+String(d),width:"100%",height:"100%",fill:b.colorLight});h.setAttributeNS("http://www.w3.org/2000/xmlns/","xmlns:xlink","http://www.w3.org/1999/xlink"),c.appendChild(h),h.appendChild(g("rect",{fill:b.colorDark,width:"1",height:"1",id:"template"}));for(var i=0;d>i;i++)for(var j=0;d>j;j++)if(a.isDark(i,j)){var k=g("use",{x:String(i),y:String(j)});k.setAttributeNS("http://www.w3.org/1999/xlink","href","#template"),h.appendChild(k)}},a.prototype.clear=function(){for(;this._el.hasChildNodes();)this._el.removeChild(this._el.lastChild)},a}(),p="svg"===document.documentElement.tagName.toLowerCase(),q=p?o:m()?function(){function a(){this._elImage.src=this._elCanvas.toDataURL("image/png"),this._elImage.style.display="block",this._elCanvas.style.display="none"}function d(a,b){var c=this;if(c._fFail=b,c._fSuccess=a,null===c._bSupportDataURI){var d=document.createElement("img"),e=function(){c._bSupportDataURI=!1,c._fFail&&_fFail.call(c)},f=function(){c._bSupportDataURI=!0,c._fSuccess&&c._fSuccess.call(c)};return d.onabort=e,d.onerror=e,d.onload=f,d.src="data:image/gif;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg==",void 0}c._bSupportDataURI===!0&&c._fSuccess?c._fSuccess.call(c):c._bSupportDataURI===!1&&c._fFail&&c._fFail.call(c)}if(this._android&&this._android<=2.1){var b=1/window.devicePixelRatio,c=CanvasRenderingContext2D.prototype.drawImage;CanvasRenderingContext2D.prototype.drawImage=function(a,d,e,f,g,h,i,j){if("nodeName"in a&&/img/i.test(a.nodeName))for(var l=arguments.length-1;l>=1;l--)arguments[l]=arguments[l]*b;else"undefined"==typeof j&&(arguments[1]*=b,arguments[2]*=b,arguments[3]*=b,arguments[4]*=b);c.apply(this,arguments)}}var e=function(a,b){this._bIsPainted=!1,this._android=n(),this._htOption=b,this._elCanvas=document.createElement("canvas"),this._elCanvas.width=b.width,this._elCanvas.height=b.height,a.appendChild(this._elCanvas),this._el=a,this._oContext=this._elCanvas.getContext("2d"),this._bIsPainted=!1,this._elImage=document.createElement("img"),this._elImage.style.display="none",this._el.appendChild(this._elImage),this._bSupportDataURI=null};return e.prototype.draw=function(a){var b=this._elImage,c=this._oContext,d=this._htOption,e=a.getModuleCount(),f=d.width/e,g=d.height/e,h=Math.round(f),i=Math.round(g);b.style.display="none",this.clear();for(var j=0;e>j;j++)for(var k=0;e>k;k++){var l=a.isDark(j,k),m=k*f,n=j*g;c.strokeStyle=l?d.colorDark:d.colorLight,c.lineWidth=1,c.fillStyle=l?d.colorDark:d.colorLight,c.fillRect(m,n,f,g),c.strokeRect(Math.floor(m)+.5,Math.floor(n)+.5,h,i),c.strokeRect(Math.ceil(m)-.5,Math.ceil(n)-.5,h,i)}this._bIsPainted=!0},e.prototype.makeImage=function(){this._bIsPainted&&d.call(this,a)},e.prototype.isPainted=function(){return this._bIsPainted},e.prototype.clear=function(){this._oContext.clearRect(0,0,this._elCanvas.width,this._elCanvas.height),this._bIsPainted=!1},e.prototype.round=function(a){return a?Math.floor(1e3*a)/1e3:a},e}():function(){var a=function(a,b){this._el=a,this._htOption=b};return a.prototype.draw=function(a){for(var b=this._htOption,c=this._el,d=a.getModuleCount(),e=Math.floor(b.width/d),f=Math.floor(b.height/d),g=[''],h=0;d>h;h++){g.push("");for(var i=0;d>i;i++)g.push('');g.push("")}g.push("
"),c.innerHTML=g.join("");var j=c.childNodes[0],k=(b.width-j.offsetWidth)/2,l=(b.height-j.offsetHeight)/2;k>0&&l>0&&(j.style.margin=l+"px "+k+"px")},a.prototype.clear=function(){this._el.innerHTML=""},a}();QRCode=function(a,b){if(this._htOption={width:256,height:256,typeNumber:4,colorDark:"#000000",colorLight:"#ffffff",correctLevel:d.H},"string"==typeof b&&(b={text:b}),b)for(var c in b)this._htOption[c]=b[c];"string"==typeof a&&(a=document.getElementById(a)),this._android=n(),this._el=a,this._oQRCode=null,this._oDrawing=new q(this._el,this._htOption),this._htOption.text&&this.makeCode(this._htOption.text)},QRCode.prototype.makeCode=function(a){this._oQRCode=new b(r(a,this._htOption.correctLevel),this._htOption.correctLevel),this._oQRCode.addData(a),this._oQRCode.make(),this._el.title=a,this._oDrawing.draw(this._oQRCode),this.makeImage()},QRCode.prototype.makeImage=function(){"function"==typeof this._oDrawing.makeImage&&(!this._android||this._android>=3)&&this._oDrawing.makeImage()},QRCode.prototype.clear=function(){this._oDrawing.clear()},QRCode.CorrectLevel=d}(); -------------------------------------------------------------------------------- /json/manage_asset.json: -------------------------------------------------------------------------------- 1 | { 2 | "data": [ 3 | { 4 | "id": "issueFixedAmount", 5 | "type_id": -102113, 6 | "description": "issueFixedAmount is used to create new tokens with fixed total supply.", 7 | "parameters": [ 8 | { 9 | "name": "from_address", 10 | "help": "The address sends out tokens. This address must belong to my wallet (ismine = true) and has enough satoshis to pay miner fee. You could import the address to omnicore (will be ismine = true).", 11 | "buttons": [ 12 | { 13 | "innerText": "Select", 14 | "onclick": "displayUserDataInNewHtml('MyAddresses')" 15 | }, 16 | { 17 | "innerText": "Import to Omni Core", 18 | "onclick": "importToOmniCore()" 19 | } 20 | ] 21 | }, 22 | { 23 | "name": "name", 24 | "help": "the name for the new tokens to be created", 25 | "buttons": [] 26 | }, 27 | { 28 | "name": "ecosystem", 29 | "help": "the ecosystem to create the tokens in (1 for main ecosystem, 2 for testing ecosystem)", 30 | "buttons": [] 31 | }, 32 | { 33 | "name": "divisible_type", 34 | "help": "the type of the tokens to create: (1 for indivisible tokens, 2 for divisible tokens)", 35 | "buttons": [] 36 | }, 37 | { 38 | "name": "data", 39 | "help": "a description for the new tokens (can be empty '')", 40 | "buttons": [] 41 | }, 42 | { 43 | "name": "amount", 44 | "help": "the number of tokens to create. The minimum amount is 1.", 45 | "buttons": [] 46 | } 47 | ] 48 | }, 49 | { 50 | "id": "issueManagedAmout", 51 | "type_id": -102114, 52 | "description": "issueManagedAmout is used to create new tokens with manageable supply. NOTE: Record the txid returned by the OBD, and then you can use the GetTransaction (type-102118) API to get the property ID of the manageable asset you issued.", 53 | "parameters": [ 54 | { 55 | "name": "from_address", 56 | "help": "the address sends out tokens. This address must belong to your wallet (ismine = true) and has enough satoshis to pay miner fee. You could import the address to omnicore (will be ismine = true).", 57 | "buttons": [ 58 | { 59 | "innerText": "Select", 60 | "onclick": "displayUserDataInNewHtml('MyAddresses')" 61 | }, 62 | { 63 | "innerText": "Import to Omni Core", 64 | "onclick": "importToOmniCore()" 65 | } 66 | ] 67 | }, 68 | { 69 | "name": "name", 70 | "help": "the name of the new tokens to create", 71 | "buttons": [] 72 | }, 73 | { 74 | "name": "ecosystem", 75 | "help": "the ecosystem to create the tokens in (1 for main ecosystem, 2 for testing ecosystem)", 76 | "buttons": [] 77 | }, 78 | { 79 | "name": "divisible_type", 80 | "help": "the type of the tokens to create: (1 for indivisible tokens, 2 for divisible tokens)", 81 | "buttons": [] 82 | }, 83 | { 84 | "name": "data", 85 | "help": "a description for the new tokens (can be empty '')", 86 | "buttons": [] 87 | } 88 | ] 89 | }, 90 | { 91 | "id": "sendGrant", 92 | "type_id": -102115, 93 | "description": "sendGrant is used to issue or grant new units of managed tokens.", 94 | "parameters": [ 95 | { 96 | "name": "from_address", 97 | "help": "the address to send from", 98 | "buttons": [ 99 | { 100 | "innerText": "Select", 101 | "onclick": "displayUserDataInNewHtml('MyAddresses')" 102 | } 103 | ] 104 | }, 105 | { 106 | "name": "property_id", 107 | "help": "The identifier of the tokens to grant. Get it by invoke GetTransaction (type 1206) interface by the txid returned by issuanceManaged (type 1202) API.", 108 | "buttons": [] 109 | }, 110 | { 111 | "name": "amount", 112 | "help": "the amount of tokens to create", 113 | "buttons": [] 114 | }, 115 | { 116 | "name": "memo", 117 | "help": "a text note attached to this transaction (none by default)", 118 | "buttons": [] 119 | } 120 | ] 121 | }, 122 | { 123 | "id": "sendRevoke", 124 | "type_id": -102116, 125 | "description": "sendRevoke is used to revoke units of managed tokens.", 126 | "parameters": [ 127 | { 128 | "name": "from_address", 129 | "help": "the address to send from", 130 | "buttons": [ 131 | { 132 | "innerText": "Select", 133 | "onclick": "displayUserDataInNewHtml('MyAddresses')" 134 | } 135 | ] 136 | }, 137 | { 138 | "name": "property_id", 139 | "help": "The identifier of the tokens to be revoked. Get it by invoke GetTransaction (type 1206) API by the txid returned by issuanceManaged (type 1202) API.", 140 | "buttons": [] 141 | }, 142 | { 143 | "name": "amount", 144 | "help": "the amount of tokens to revoke", 145 | "buttons": [] 146 | }, 147 | { 148 | "name": "memo", 149 | "help": "a text note attached to this transaction (none by default)", 150 | "buttons": [] 151 | } 152 | ] 153 | } 154 | ] 155 | } 156 | -------------------------------------------------------------------------------- /json/user_data_list.json: -------------------------------------------------------------------------------- 1 | { 2 | "data": [ 3 | { 4 | "id": "MnemonicWords", 5 | "description": "Mnemonic words are used for unlock(or restore) your local wallet, and its encrypted hashed value is a your wallet ID to connect a OBD node." 6 | }, 7 | { 8 | "id": "MyAddresses", 9 | "description": "Addresses generated by mnemonic." 10 | }, 11 | { 12 | "id": "Counterparties", 13 | "description": "List of counterparties who have interacted with me." 14 | }, 15 | { 16 | "id": "ChannelList", 17 | "description": "List of channels created." 18 | }, 19 | { 20 | "id": "OmniFaucet", 21 | "description": "Omni Faucet sends you omnilayer assets to test." 22 | } 23 | ] 24 | } 25 | -------------------------------------------------------------------------------- /json/util_list.json: -------------------------------------------------------------------------------- 1 | { 2 | "data": [ 3 | { 4 | "id": "getAddressInfo", 5 | "type_id": -103001, 6 | "description": "getAddressInfo is used to get details of an address generated by mnemonic words.", 7 | "parameters": [ 8 | { 9 | "name": "index", 10 | "buttons": [] 11 | } 12 | ] 13 | }, 14 | { 15 | "id": "getMyChannels", 16 | "type_id": -103150, 17 | "description": "getMyChannels is used to get the channels of current user.", 18 | "parameters": [] 19 | }, 20 | { 21 | "id": "getChannelDetailFromChannelID", 22 | "type_id": -103154, 23 | "description": "getChannelDetailFromChannelID is used to get detail data of the channel from a channel ID.", 24 | "parameters": [ 25 | { 26 | "name": "channel_id", 27 | "buttons": [ 28 | { 29 | "innerText": "Display", 30 | "onclick": "displayMyChannelList(5, 1)" 31 | } 32 | ] 33 | } 34 | ] 35 | }, 36 | { 37 | "id": "getChannelDetailFromDatabaseID", 38 | "type_id": -103155, 39 | "description": "getChannelDetailFromDatabaseID is used to get detail data of a channel from a database ID.", 40 | "parameters": [ 41 | { 42 | "name": "id", 43 | "buttons": [ 44 | ] 45 | } 46 | ] 47 | }, 48 | { 49 | "id": "getAllCommitmentTransactions", 50 | "type_id": -103200, 51 | "description": "getAllCommitmentTransactions is used to list the history of commitment transactions inside a channel.", 52 | "parameters": [ 53 | { 54 | "name": "channel_id", 55 | "buttons": [ 56 | { 57 | "innerText": "Select", 58 | "onclick": "displayMyChannelList(5, 1)" 59 | } 60 | ] 61 | } 62 | ] 63 | }, 64 | { 65 | "id": "getLatestCommitmentTransaction", 66 | "type_id": -103203, 67 | "description": "getLatestCommitmentTransaction is used to get the latest commitment transaction.", 68 | "parameters": [ 69 | { 70 | "name": "channel_id", 71 | "buttons": [ 72 | { 73 | "innerText": "Select", 74 | "onclick": "displayMyChannelList(5, 1)" 75 | } 76 | ] 77 | } 78 | ] 79 | }, 80 | { 81 | "id": "getLatestRevockableDeliveryTransaction", 82 | "type_id": -103204, 83 | "description": "getLatestRevockableDeliveryTransaction is used to get the latest Revockable Delivery transaction.", 84 | "parameters": [ 85 | { 86 | "name": "channel_id", 87 | "buttons": [ 88 | { 89 | "innerText": "Select", 90 | "onclick": "displayMyChannelList(5, 1)" 91 | } 92 | ] 93 | } 94 | ] 95 | }, 96 | { 97 | "id": "getLatestBreachRemedyTransaction", 98 | "type_id": -103205, 99 | "description": "getLatestBreachRemedyTransaction is used to get the latest Breach Remedy transaction.", 100 | "parameters": [ 101 | { 102 | "name": "channel_id", 103 | "buttons": [ 104 | { 105 | "innerText": "Select", 106 | "onclick": "displayMyChannelList(5, 1)" 107 | } 108 | ] 109 | } 110 | ] 111 | }, 112 | { 113 | "id": "getAllRevockableDeliveryTransactions", 114 | "type_id": -103207, 115 | "description": "getAllRevockableDeliveryTransactions is used to list the history of all of the Revockable Delivery transactions inside the channel.", 116 | "parameters": [ 117 | { 118 | "name": "channel_id", 119 | "buttons": [ 120 | { 121 | "innerText": "Select", 122 | "onclick": "displayMyChannelList(5, 1)" 123 | } 124 | ] 125 | } 126 | ] 127 | }, 128 | { 129 | "id": "getAllBreachRemedyTransactions", 130 | "type_id": -103208, 131 | "description": "getAllBreachRemedyTransactions is used to list all of the Breach Remedy transactions inside te channel.", 132 | "parameters": [ 133 | { 134 | "name": "channel_id", 135 | "buttons": [ 136 | { 137 | "innerText": "Select", 138 | "onclick": "displayMyChannelList(5, 1)" 139 | } 140 | ] 141 | } 142 | ] 143 | }, 144 | { 145 | "id": "getAllBalancesForAddress", 146 | "type_id": -102112, 147 | "description": "getAllBalancesForAddress is used to get all omni assets details of an address.", 148 | "parameters": [ 149 | { 150 | "name": "address", 151 | "buttons": [ 152 | { 153 | "innerText": "Select", 154 | "onclick": "displayUserDataInNewHtml('MyAddresses')" 155 | } 156 | ] 157 | } 158 | ] 159 | }, 160 | { 161 | "id": "listProperties", 162 | "type_id": -102117, 163 | "description": "listProperties is used to list all tokens or smart properties. This call may take a long time, it may return a large amount of data, please use it with caution.", 164 | "parameters": [] 165 | }, 166 | { 167 | "id": "getTransaction", 168 | "type_id": -102118, 169 | "description": "getTransaction is used to get detailed information about an Omnilayer transaction.", 170 | "parameters": [ 171 | { 172 | "name": "txid", 173 | "buttons": [] 174 | } 175 | ] 176 | }, 177 | { 178 | "id": "getProperty", 179 | "type_id": -102119, 180 | "description": "getProperty is used to get omni asset details by an asset id (Property Id) .", 181 | "parameters": [ 182 | { 183 | "name": "PropertyID", 184 | "buttons": [] 185 | } 186 | ] 187 | } 188 | ] 189 | } 190 | -------------------------------------------------------------------------------- /log.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Complete log of OBD messages 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 |
21 | 22 | 23 | 24 |
25 |
26 | 27 | 28 |
29 |

30 |     
31 | 32 | 33 | 34 | 35 | 36 | 39 | 40 | -------------------------------------------------------------------------------- /sdk/basic.js: -------------------------------------------------------------------------------- 1 | // basic.js 2 | // Basic Lightning Network Operations 3 | 4 | 5 | /** 6 | * Type -100032 Protocol is used to request to create a channel with someone else(Bob). 7 | * @param myUserID The user id of logged in 8 | * @param nodeID peer id of the obd node where the fundee logged in. 9 | * @param userID the user id of the fundee. 10 | * @param info 11 | */ 12 | function openChannel(myUserID, nodeID, userID, info) { 13 | return new Promise((resolve, reject) => { 14 | obdApi.openChannel(nodeID, userID, info, function(e) { 15 | // console.info('SDK: -100032 openChannel = ' + JSON.stringify(e)); 16 | 17 | let channel_id = e.temporary_channel_id; 18 | saveCounterparty(myUserID, channel_id, nodeID, userID); 19 | saveChannelStatus(myUserID, channel_id, true, kStatusOpenChannel); 20 | 21 | let privkey = getPrivKeyFromPubKey(myUserID, info.funding_pubkey); 22 | saveFundingPrivKey(myUserID, channel_id, privkey); 23 | resolve(e); 24 | }); 25 | }) 26 | } 27 | 28 | /** 29 | * Type -100033 Bob replies to accept, his OBD completes his message and 30 | * routes it back to Alice's OBD. Then Alice sees the response of acceptance. 31 | * 32 | * @param myUserID The user id of logged in 33 | * @param nodeID peer id of the obd node where the fundee logged in. 34 | * @param userID the user id of the fundee. 35 | * @param info 36 | */ 37 | function acceptChannel(myUserID, nodeID, userID, info) { 38 | return new Promise((resolve, reject) => { 39 | obdApi.acceptChannel(nodeID, userID, info, function(e) { 40 | // console.info('SDK: -100033 acceptChannel = ' + JSON.stringify(e)); 41 | 42 | let channel_id = e.temporary_channel_id; 43 | let privkey = getPrivKeyFromPubKey(myUserID, info.funding_pubkey); 44 | saveFundingPrivKey(myUserID, channel_id, privkey); 45 | saveChannelStatus(myUserID, channel_id, false, kStatusAcceptChannel); 46 | saveChannelAddr(channel_id, e.channel_address); 47 | resolve(e); 48 | }); 49 | }) 50 | } 51 | 52 | /** 53 | * Type 102109 Protocol is used for depositing bitcoin into a channel. 54 | * Since the basic Omnilayer protocal uses BTC as miner fee in 55 | * constructing transactions, this message 102109 is mandatory 56 | * for depositing a little BTC into a channel as miner fee. 57 | * 58 | * @param myUserID The user id of logged in 59 | * @param info 60 | */ 61 | function fundingBitcoin(myUserID, info) { 62 | return new Promise((resolve, reject) => { 63 | obdApi.fundingBitcoin(info, async function(e) { 64 | // console.info('SDK: -102109 fundingBitcoin = ' + JSON.stringify(e)); 65 | 66 | let channel_id = await getChannelIDFromAddr(info.to_address); 67 | let status = await getChannelStatus(channel_id, true); 68 | // console.info('fundingBitcoin status = ' + status); 69 | switch (Number(status)) { 70 | case kStatusAcceptChannel: 71 | saveChannelStatus(myUserID, channel_id, true, kStatusFirstFundingBitcoin); 72 | break; 73 | case kStatusFirstBitcoinFundingSigned: 74 | saveChannelStatus(myUserID, channel_id, true, kStatusSecondFundingBitcoin); 75 | break; 76 | case kStatusSecondBitcoinFundingSigned: 77 | saveChannelStatus(myUserID, channel_id, true, kStatusThirdFundingBitcoin); 78 | break; 79 | } 80 | 81 | // Sign the tx on client 82 | let privkey = getPrivKeyFromAddress(info.from_address); 83 | let signed_hex = signP2PKH(e.hex, privkey, e.inputs); 84 | 85 | info.from_address_private_key = privkey; 86 | saveFundingBtcData(myUserID, channel_id, info); 87 | saveTempData(myUserID, channel_id, signed_hex); 88 | resolve(e); 89 | }); 90 | }) 91 | } 92 | 93 | /** 94 | * Type -100340 Protocol is used to notify the success of 95 | * funding BTC to the counterpart of the channel. 96 | * 97 | * @param myUserID The user id of logged in 98 | * @param nodeID peer id of the obd node where the fundee logged in. 99 | * @param userID the user id of the fundee. 100 | * @param info 101 | */ 102 | function bitcoinFundingCreated(myUserID, nodeID, userID, info) { 103 | return new Promise((resolve, reject) => { 104 | obdApi.bitcoinFundingCreated(nodeID, userID, info, async function(e) { 105 | // console.info('SDK: -100340 bitcoinFundingCreated = ' + JSON.stringify(e)); 106 | 107 | let channel_id = e.temporary_channel_id; 108 | let status = await getChannelStatus(channel_id, true); 109 | // console.info('bitcoinFundingCreated status = ' + status); 110 | switch (Number(status)) { 111 | case kStatusFirstFundingBitcoin: 112 | saveChannelStatus(myUserID, channel_id, true, kStatusFirstBitcoinFundingCreated); 113 | break; 114 | case kStatusSecondFundingBitcoin: 115 | saveChannelStatus(myUserID, channel_id, true, kStatusSecondBitcoinFundingCreated); 116 | break; 117 | case kStatusThirdFundingBitcoin: 118 | saveChannelStatus(myUserID, channel_id, true, kStatusThirdBitcoinFundingCreated); 119 | break; 120 | } 121 | 122 | // Sign tx 123 | if (e.hex) { 124 | // Alice sign the tx on client 125 | let privkey = await getFundingPrivKey(myUserID, channel_id); 126 | let signed_hex = signP2SH(true, e.hex, e.pub_key_a, 127 | e.pub_key_b, privkey, e.inputs); 128 | 129 | await sendSignedHex100341(nodeID, userID, signed_hex); 130 | resolve(signed_hex); 131 | } 132 | 133 | resolve(true); 134 | }); 135 | }) 136 | } 137 | 138 | /** 139 | * Type -100341 Protocol send signed_hex that Alice signed in 100340 to OBD. 140 | * 141 | * @param nodeID peer id of the obd node where the fundee logged in. 142 | * @param userID the user id of the fundee. 143 | * @param signed_hex 144 | */ 145 | function sendSignedHex100341(nodeID, userID, signed_hex) { 146 | return new Promise((resolve, reject) => { 147 | obdApi.sendSignedHex100341(nodeID, userID, signed_hex, function(e) { 148 | // console.info('SDK: -100341 sendSignedHex100341 = ' + JSON.stringify(e)); 149 | resolve(true); 150 | }); 151 | }) 152 | } 153 | 154 | /** 155 | * Type -100350 Protocol is used to Bob tells his OBD to reply Alice 156 | * that he knows the BTC funding by message -100350. 157 | * 158 | * @param myUserID The user id of logged in 159 | * @param nodeID peer id of the obd node where the fundee logged in. 160 | * @param userID the user id of the fundee. 161 | * @param info 162 | */ 163 | function bitcoinFundingSigned(myUserID, nodeID, userID, info) { 164 | return new Promise((resolve, reject) => { 165 | obdApi.bitcoinFundingSigned(nodeID, userID, info, async function(e) { 166 | // console.info('SDK: -100350 bitcoinFundingSigned = ' + JSON.stringify(e)); 167 | 168 | let channel_id = e.temporary_channel_id; 169 | let status = await getChannelStatus(channel_id, false); 170 | // console.info('bitcoinFundingSigned status = ' + status); 171 | switch (Number(status)) { 172 | case kStatusFirstBitcoinFundingCreated: 173 | saveChannelStatus(myUserID, channel_id, false, kStatusFirstBitcoinFundingSigned); 174 | break; 175 | case kStatusSecondBitcoinFundingCreated: 176 | saveChannelStatus(myUserID, channel_id, false, kStatusSecondBitcoinFundingSigned); 177 | break; 178 | case kStatusThirdBitcoinFundingCreated: 179 | saveChannelStatus(myUserID, channel_id, false, kStatusThirdBitcoinFundingSigned); 180 | break; 181 | } 182 | 183 | resolve(true); 184 | }); 185 | }) 186 | } 187 | 188 | /** 189 | * Type -102120 Protocol is used to Alice starts to deposit omni assets to 190 | * the channel. This is quite similar to the the btc funding procedure. 191 | * 192 | * @param myUserID The user id of logged in 193 | * @param info 194 | */ 195 | function fundingAsset(myUserID, info) { 196 | return new Promise((resolve, reject) => { 197 | obdApi.fundingAsset(info, async function(e) { 198 | // console.info('SDK: -102120 fundingAsset = ' + JSON.stringify(e)); 199 | 200 | // Sign the tx on client 201 | let privkey = getPrivKeyFromAddress(info.from_address); 202 | let signed_hex = signP2PKH(e.hex, privkey, e.inputs); 203 | 204 | let channel_id = await getChannelIDFromAddr(info.to_address); 205 | saveChannelStatus(myUserID, channel_id, true, kStatusFundingAsset); 206 | saveTempData(myUserID, channel_id, signed_hex); 207 | resolve(true); 208 | }); 209 | }) 210 | } 211 | 212 | /** 213 | * Type -100034 Protocol is used to notify the success of omni asset 214 | * funding transaction to the counterparty of the channel. 215 | * 216 | * @param myUserID The user id of logged in 217 | * @param nodeID peer id of the obd node where the fundee logged in. 218 | * @param userID the user id of the fundee. 219 | * @param info 220 | * @param tempKey temp_address_private_key 221 | */ 222 | function assetFundingCreated(myUserID, nodeID, userID, info, tempKey) { 223 | return new Promise((resolve, reject) => { 224 | obdApi.assetFundingCreated(nodeID, userID, info, async function(e) { 225 | // console.info('SDK: -100034 - assetFundingCreated = ' + JSON.stringify(e)); 226 | let channel_id = info.temporary_channel_id; 227 | 228 | // Alice sign the tx on client 229 | let privkey = await getFundingPrivKey(myUserID, channel_id); 230 | let signed_hex = signP2SH(true, e.hex, e.pub_key_a, 231 | e.pub_key_b, privkey, e.inputs); 232 | 233 | await sendSignedHex101034(nodeID, userID, signed_hex); 234 | 235 | // Save temporary private key to local storage 236 | saveTempPrivKey(myUserID, kTempPrivKey, channel_id, tempKey); 237 | saveChannelStatus(myUserID, channel_id, true, kStatusAssetFundingCreated); 238 | resolve(signed_hex); 239 | }); 240 | }) 241 | } 242 | 243 | /** 244 | * Type -101034 Protocol send signed_hex that Alice signed in 100034 to OBD. 245 | * 246 | * @param nodeID peer id of the obd node where the fundee logged in. 247 | * @param userID the user id of the fundee. 248 | * @param signed_hex 249 | */ 250 | function sendSignedHex101034(nodeID, userID, signed_hex) { 251 | return new Promise((resolve, reject) => { 252 | obdApi.sendSignedHex101034(nodeID, userID, signed_hex, function(e) { 253 | // console.info('sendSignedHex101034 = ' + JSON.stringify(e)); 254 | resolve(true); 255 | }); 256 | }) 257 | } 258 | 259 | /** 260 | * Type -101134 Protocol send signed_hex that Alice signed in 110035 to OBD. 261 | * @param info SignedInfo101134 262 | */ 263 | function sendSignedHex101134(info) { 264 | return new Promise((resolve, reject) => { 265 | obdApi.sendSignedHex101134(info, function(e) { 266 | // console.info('sendSignedHex101134 = ' + JSON.stringify(e)); 267 | resolve(e); 268 | }); 269 | }) 270 | } 271 | 272 | /** 273 | * Type -100035 Protocol is used to Bob tells his OBD to reply Alice 274 | * that he knows the asset funding transaction by message -100035, 275 | * and Alice's OBD will creat commitment transactions (C1a & RD1a). 276 | * 277 | * @param myUserID The user id of logged in 278 | * @param nodeID peer id of the obd node where the fundee logged in. 279 | * @param userID the user id of the fundee. 280 | * @param info 281 | */ 282 | function assetFundingSigned(myUserID, nodeID, userID, info) { 283 | return new Promise((resolve, reject) => { 284 | obdApi.assetFundingSigned(nodeID, userID, info, async function(e) { 285 | // console.info('SDK: -100035 - assetFundingSigned = ' + JSON.stringify(e)); 286 | 287 | let channel_id = info.temporary_channel_id; 288 | 289 | // Bob sign the tx on client side 290 | // NO.1 alice_br_sign_data 291 | let br = e.alice_br_sign_data; 292 | let inputs = br.inputs; 293 | let privkey = await getFundingPrivKey(myUserID, channel_id); 294 | let br_hex = signP2SH(true, br.hex, br.pub_key_a, br.pub_key_b, 295 | privkey, inputs); 296 | 297 | // NO.2 alice_rd_sign_data 298 | let rd = e.alice_rd_sign_data; 299 | inputs = rd.inputs; 300 | let rd_hex = signP2SH(true, rd.hex, rd.pub_key_a, rd.pub_key_b, 301 | privkey, inputs); 302 | 303 | // will send 101035 304 | let signedInfo = new SignedInfo101035(); 305 | signedInfo.temporary_channel_id = channel_id; 306 | signedInfo.br_signed_hex = br_hex; 307 | signedInfo.rd_signed_hex = rd_hex; 308 | signedInfo.br_id = br.br_id; 309 | 310 | let resp = await sendSignedHex101035(nodeID, userID, signedInfo, 311 | myUserID, channel_id, privkey); 312 | 313 | let returnData = { 314 | info1035: signedInfo, 315 | resp1035: resp 316 | }; 317 | resolve(returnData); 318 | }); 319 | }) 320 | } 321 | 322 | /** 323 | * Type -101035 Protocol send signed info that Bob signed in 100035 to OBD. 324 | * 325 | * @param nodeID peer id of the obd node where the fundee logged in. 326 | * @param userID the user id of the fundee. 327 | * @param signedInfo 328 | * @param myUserID The user id of logged in 329 | * @param tempCID temporary_channel_id 330 | * @param priv_key channel_address_private_key 331 | */ 332 | function sendSignedHex101035(nodeID, userID, signedInfo, myUserID, tempCID, priv_key) { 333 | return new Promise((resolve, reject) => { 334 | obdApi.sendSignedHex101035(nodeID, userID, signedInfo, async function(e) { 335 | // console.info('sendSignedHex101035 = ' + JSON.stringify(e)); 336 | 337 | // Once sent -100035 AssetFundingSigned , the final channel_id has generated. 338 | // So need update the local saved data of funding private key and channel_id. 339 | 340 | let channel_id = e.channel_id; 341 | let channel_addr = await getChannelAddr(tempCID); 342 | 343 | saveFundingPrivKey(myUserID, channel_id, priv_key); 344 | 345 | // 346 | delChannelAddr(tempCID); 347 | saveChannelAddr(channel_id, channel_addr); 348 | 349 | // 350 | delChannelStatus(tempCID, false); 351 | saveChannelStatus(myUserID, channel_id, false, kStatusAssetFundingSigned); 352 | 353 | // 354 | delCounterparty(myUserID, tempCID); 355 | saveCounterparty(myUserID, channel_id, nodeID, userID); 356 | 357 | resolve(e); 358 | }); 359 | }) 360 | } 361 | 362 | /** 363 | * Type -100351 Protocol is used for paying omni assets by 364 | * Revocable Sequence Maturity Contract(RSMC) within a channel. 365 | * 366 | * @param myUserID The user id of logged in 367 | * @param nodeID peer id of the obd node where the fundee logged in. 368 | * @param userID the user id of the fundee. 369 | * @param info 370 | * @param isFunder 371 | * @param tempKey curr_temp_address_private_key 372 | */ 373 | function commitmentTransactionCreated(myUserID, nodeID, userID, info, isFunder, tempKey) { 374 | return new Promise((resolve, reject) => { 375 | obdApi.commitmentTransactionCreated(nodeID, userID, info, async function(e) { 376 | // console.info('SDK: -100351 commitmentTransactionCreated = ' + JSON.stringify(e)); 377 | 378 | // Sender sign the tx on client side 379 | // NO.1 counterparty_raw_data 380 | let cr = e.counterparty_raw_data; 381 | let inputs = cr.inputs; 382 | 383 | console.info('START = ' + new Date().getTime()); 384 | let privkey = await getFundingPrivKey(myUserID, e.channel_id); 385 | console.info('END READ DB = ' + new Date().getTime()); 386 | 387 | let cr_hex = signP2SH(true, cr.hex, cr.pub_key_a, cr.pub_key_b, 388 | privkey, inputs); 389 | console.info('END SIGN = ' + new Date().getTime()); 390 | 391 | // NO.2 rsmc_raw_data 392 | let rr = e.rsmc_raw_data; 393 | inputs = rr.inputs; 394 | let rr_hex = signP2SH(true, rr.hex, rr.pub_key_a, rr.pub_key_b, 395 | privkey, inputs); 396 | 397 | // will send 100360 398 | let signedInfo = new SignedInfo100360(); 399 | signedInfo.channel_id = e.channel_id; 400 | signedInfo.counterparty_signed_hex = cr_hex; 401 | signedInfo.rsmc_signed_hex = rr_hex; 402 | 403 | await sendSignedHex100360(nodeID, userID, signedInfo); 404 | 405 | // save some data 406 | saveTempPrivKey(myUserID, kTempPrivKey, e.channel_id, tempKey); 407 | saveChannelStatus(myUserID, e.channel_id, isFunder, kStatusCommitmentTransactionCreated); 408 | saveCounterparty(myUserID, e.channel_id, nodeID, userID); 409 | saveSenderRole(kIsSender); 410 | 411 | resolve(signedInfo); 412 | }); 413 | }) 414 | } 415 | 416 | /** 417 | * Type -100360 Protocol send signed info that Sender signed in 100351 to OBD. 418 | * 419 | * @param nodeID peer id of the obd node where the fundee logged in. 420 | * @param userID the user id of the fundee. 421 | * @param signedInfo 422 | */ 423 | function sendSignedHex100360(nodeID, userID, signedInfo) { 424 | return new Promise((resolve, reject) => { 425 | obdApi.sendSignedHex100360(nodeID, userID, signedInfo, function(e) { 426 | // console.info('sendSignedHex100360 = ' + JSON.stringify(e)); 427 | resolve(e); 428 | }); 429 | }) 430 | } 431 | 432 | /** 433 | * Type -100352 Protocol is used to Receiver revokes the previous 434 | * commitment transaction and ackonwledge the new transaction. 435 | * 436 | * @param myUserID The user id of logged in 437 | * @param nodeID peer id of the obd node where the fundee logged in. 438 | * @param userID the user id of the fundee. 439 | * @param info 440 | * @param isFunder 441 | * @param tempKey curr_temp_address_private_key 442 | */ 443 | function commitmentTransactionAccepted(myUserID, nodeID, userID, info, isFunder, tempKey) { 444 | return new Promise((resolve, reject) => { 445 | obdApi.commitmentTransactionAccepted(nodeID, userID, info, async function(e) { 446 | // console.info('SDK: -100352 commitmentTransactionAccepted = ' + JSON.stringify(e)); 447 | 448 | // Receiver sign the tx on client side 449 | // NO.1 c2a_br_raw_data 450 | let ab = e.c2a_br_raw_data; 451 | let inputs = ab.inputs; 452 | let privkey = await getFundingPrivKey(myUserID, e.channel_id); 453 | let ab_hex = signP2SH(true, ab.hex, ab.pub_key_a, ab.pub_key_b, privkey, inputs); 454 | 455 | // NO.2 c2a_rd_raw_data 456 | let ar = e.c2a_rd_raw_data; 457 | inputs = ar.inputs; 458 | let ar_hex = signP2SH(true, ar.hex, ar.pub_key_a, ar.pub_key_b, privkey, inputs); 459 | 460 | // NO.3 c2b_counterparty_raw_data 461 | let bc = e.c2b_counterparty_raw_data; 462 | inputs = bc.inputs; 463 | let bc_hex = signP2SH(true, bc.hex, bc.pub_key_a, bc.pub_key_b, privkey, inputs); 464 | 465 | // NO.4 c2b_rsmc_raw_data 466 | let br = e.c2b_rsmc_raw_data; 467 | inputs = br.inputs; 468 | let br_hex = signP2SH(true, br.hex, br.pub_key_a, br.pub_key_b, privkey, inputs); 469 | 470 | // will send 100361 471 | let signedInfo = new SignedInfo100361(); 472 | signedInfo.channel_id = e.channel_id; 473 | signedInfo.c2b_rsmc_signed_hex = br_hex; 474 | signedInfo.c2b_counterparty_signed_hex = bc_hex; 475 | signedInfo.c2a_rd_signed_hex = ar_hex; 476 | signedInfo.c2a_br_signed_hex = ab_hex; 477 | signedInfo.c2a_br_id = ab.br_id; 478 | 479 | await sendSignedHex100361(nodeID, userID, signedInfo); 480 | saveTempPrivKey(myUserID, kTempPrivKey, e.channel_id, tempKey); 481 | saveChannelStatus(myUserID, e.channel_id, isFunder, kStatusCommitmentTransactionAccepted); 482 | saveCounterparty(myUserID, e.channel_id, nodeID, userID); 483 | resolve(signedInfo); 484 | }); 485 | }) 486 | } 487 | 488 | /** 489 | * Type -100361 Protocol send signed info that Receiver signed in 100352 to OBD. 490 | * 491 | * @param nodeID peer id of the obd node where the fundee logged in. 492 | * @param userID the user id of the fundee. 493 | * @param signedInfo 494 | */ 495 | function sendSignedHex100361(nodeID, userID, signedInfo) { 496 | return new Promise((resolve, reject) => { 497 | obdApi.sendSignedHex100361(nodeID, userID, signedInfo, function(e) { 498 | // console.info('sendSignedHex100361 = ' + JSON.stringify(e)); 499 | resolve(e); 500 | }); 501 | }) 502 | } 503 | 504 | /** 505 | * Type -100362 Protocol send signed info that Receiver signed in 110352 to OBD. 506 | * 507 | * @param myUserID The user id of logged in 508 | * @param nodeID peer id of the obd node where the fundee logged in. 509 | * @param userID the user id of the fundee. 510 | * @param signedInfo 511 | */ 512 | function sendSignedHex100362(myUserID, nodeID, userID, signedInfo) { 513 | return new Promise((resolve, reject) => { 514 | obdApi.sendSignedHex100362(nodeID, userID, signedInfo, async function(e) { 515 | // console.info('sendSignedHex100362 = ' + JSON.stringify(e)); 516 | 517 | // Receiver sign the tx on client side 518 | // NO.1 c2b_br_raw_data 519 | let br = e.c2b_br_raw_data; 520 | let inputs = br.inputs; 521 | let privkey = await getFundingPrivKey(myUserID, e.channel_id); 522 | let br_hex = signP2SH(true, br.hex, br.pub_key_a, br.pub_key_b, privkey, inputs); 523 | 524 | // NO.2 c2b_rd_raw_data 525 | let rd = e.c2b_rd_raw_data; 526 | inputs = rd.inputs; 527 | let rd_hex = signP2SH(true, rd.hex, rd.pub_key_a, rd.pub_key_b, privkey, inputs); 528 | 529 | // will send 100363 530 | let signedInfo = new SignedInfo100363(); 531 | signedInfo.channel_id = e.channel_id; 532 | signedInfo.c2b_rd_signed_hex = rd_hex; 533 | signedInfo.c2b_br_signed_hex = br_hex; 534 | signedInfo.c2b_br_id = br.br_id; 535 | 536 | await sendSignedHex100363(nodeID, userID, signedInfo); 537 | resolve(signedInfo); 538 | }); 539 | }) 540 | } 541 | 542 | /** 543 | * Type -100363 Protocol send signed info that Receiver signed in 100362 to OBD. 544 | * 545 | * @param nodeID peer id of the obd node where the fundee logged in. 546 | * @param userID the user id of the fundee. 547 | * @param signedInfo 548 | */ 549 | function sendSignedHex100363(nodeID, userID, signedInfo) { 550 | return new Promise((resolve, reject) => { 551 | obdApi.sendSignedHex100363(nodeID, userID, signedInfo, function(e) { 552 | // console.info('sendSignedHex100363 = ' + JSON.stringify(e)); 553 | resolve(e); 554 | }); 555 | }) 556 | } 557 | 558 | /** 559 | * Type -100364 Protocol send signed info that Receiver signed in 110353 to OBD. 560 | * @param signedInfo 561 | */ 562 | function sendSignedHex100364(signedInfo) { 563 | return new Promise((resolve, reject) => { 564 | obdApi.sendSignedHex100364(signedInfo, function(e) { 565 | // console.info('sendSignedHex100364 = ' + JSON.stringify(e)); 566 | resolve(e); 567 | }); 568 | }) 569 | } 570 | 571 | /** 572 | * Type -100038 Protocol is used to close a channel. 573 | * 574 | * @param myUserID The user id of logged in 575 | * @param nodeID peer id of the obd node where the fundee logged in. 576 | * @param userID the user id of the fundee. 577 | * @param channel_id 578 | * @param isFunder 579 | */ 580 | function closeChannel(myUserID, nodeID, userID, channel_id, isFunder) { 581 | return new Promise((resolve, reject) => { 582 | obdApi.closeChannel(nodeID, userID, channel_id, function(e) { 583 | // console.info('SDK: -100038 closeChannel = ' + JSON.stringify(e)); 584 | saveChannelStatus(myUserID, channel_id, isFunder, kStatusCloseChannel); 585 | saveSenderRole(kIsSender); 586 | resolve(true); 587 | }); 588 | }) 589 | } 590 | 591 | /** 592 | * Type -100039 Protocol is used to response the close channel request. 593 | * 594 | * @param myUserID The user id of logged in 595 | * @param nodeID peer id of the obd node where the fundee logged in. 596 | * @param userID the user id of the fundee. 597 | * @param info 598 | * @param isFunder 599 | */ 600 | function closeChannelSigned(myUserID, nodeID, userID, info, isFunder) { 601 | return new Promise((resolve, reject) => { 602 | obdApi.closeChannelSigned(nodeID, userID, info, function(e) { 603 | // console.info('SDK: -100039 closeChannelSigned = ' + JSON.stringify(e)); 604 | saveChannelStatus(myUserID, e.channel_id, isFunder, kStatusCloseChannelSigned); 605 | resolve(true); 606 | }); 607 | }) 608 | } 609 | -------------------------------------------------------------------------------- /sdk/content_tips.js: -------------------------------------------------------------------------------- 1 | // content_tips.js 2 | // Const for Tips 3 | 4 | 5 | /** 6 | * Tips for the fist time you open the page. 7 | */ 8 | const kTipsInit = 'You should firstly connect to an OBD node.'; 9 | 10 | /** 11 | * Tips for after connect to an OBD node 12 | */ 13 | const kTipsAfterConnectOBD = 'Next you need to log in.'; 14 | 15 | /** 16 | * Tips for openning a channel. 17 | */ 18 | const kTipsAfterLogin = 'You have logged in. Next you can create a channel with a remote peer using openChannel interface.'; 19 | 20 | /** 21 | * Tips for waiting for response. 22 | */ 23 | const kTipsAfterOpenChannel = 'You requested to open channel. Wait for response from your counterparty, who will accept using acceptChannel(...) .'; 24 | 25 | /** 26 | * Tips for waiting funding. 27 | */ 28 | const kTipsAfterAcceptChannel = 'You accepted the request to open a channel. Wait for funding bitcoin by your counterparty.'; 29 | 30 | /** 31 | * Tips for funding btc. 32 | */ 33 | const kTipsAfterFundingBitcoin = 'Funding bitcoin is finished successfully and you should notify your counterparty now.'; 34 | 35 | /** 36 | * Tips for 37 | */ 38 | const kTipsAfterBitcoinFundingCreated = 'Funding bitcoin notification is sent. Wait for the response from your counterparty (bitcoinFundingSigned) .'; 39 | 40 | /** 41 | * Tips for 42 | */ 43 | const kTipsFirstAfterBitcoinFundingSigned = 'You have signed the first bitcoin funding message. Wait for the second bitcoin funding message from your counterparty.'; 44 | 45 | /** 46 | * Tips for 47 | */ 48 | const kTipsSecondAfterBitcoinFundingSigned = 'You have signed the second bitcoin funding message. Wait for the third bitcoin funding message from your counterparty.'; 49 | 50 | /** 51 | * Tips for 52 | */ 53 | const kTipsThirdAfterBitcoinFundingSigned = 'You have signed the third bitcoin funding message. Wait for the asset funding message from your counterparty.'; 54 | 55 | /** 56 | * Tips for 57 | */ 58 | const kTipsAfterFundingAsset = 'Funding asset is finished successfully and you should notify the counterparty now.'; 59 | 60 | /** 61 | * Tips for 62 | */ 63 | const kTipsAfterAssetFundingCreated = 'Funding asset notification is sent. Wait for the response from your counterparty (assetFundingSigned) .'; 64 | 65 | /** 66 | * Tips for 67 | */ 68 | const kTipsAfterAssetFundingSigned = 'You have signed asset funding message. The channel has been created and funded successfully.'; 69 | 70 | /** 71 | * Tips for 72 | */ 73 | const kTipsAfterCommitmentTransactionCreated = 'You have sent a RSMC. Wait for the response from your counterparty.'; 74 | 75 | /** 76 | * Tips for 77 | */ 78 | const kTipsAfterCommitmentTransactionAccepted = 'You have accepted a RSMC, check your balance and see the payment successfully recorded.'; 79 | 80 | /** 81 | * Tips for 82 | */ 83 | const kTipsAfterHTLCFindPath = 'You found a HTLC payment path successfully, the next operation is AddHTLC.'; 84 | 85 | /** 86 | * Tips for 87 | */ 88 | const kTipsAfterAddHTLC = 'You have requested to add HTLC. Wait for the response from your counterparty.'; 89 | 90 | /** 91 | * Tips for 92 | */ 93 | const kTipsAfterHTLCSigned = 'You have accepted the request to add an HTLC. Now, you should forward the secret key R to your counterparty.'; 94 | 95 | /** 96 | * Tips for 97 | */ 98 | const kTipsAfterForwardR = 'You have forwarded R. Wait for the response from your counterparty.'; 99 | 100 | /** 101 | * Tips for 102 | */ 103 | const kTipsAfterSignR = 'You have signed the R. This HTLC has completed and you can request to close it.'; 104 | 105 | /** 106 | * Tips for 107 | */ 108 | const kTipsAfterCloseHTLC = 'You have requested to close the HTLC. Wait for response from counterparty.'; 109 | 110 | /** 111 | * Tips for 112 | */ 113 | const kTipsAfterCloseHTLCSigned = 'You have confirmed to close the HTLC, and released the resource of this channel it occupied. The life cycle of this HTLC is over. The channel now is available for other operations.'; 114 | 115 | /** 116 | * Tips for 117 | */ 118 | const kTipsAfterCloseChannel = 'You requested to close the channel. Wait for response from counterparty.'; 119 | 120 | /** 121 | * Tips for 122 | */ 123 | const kTipsAfterCloseChannelSigned = 'You confirmed to close the channel. You may want to create a new channel with someone else.'; 124 | 125 | /** 126 | * Tips for 127 | */ 128 | const kTipsAfterAtomicSwap = 'You requested to send an atomic swap. Wait for the response from your counterparty.'; 129 | 130 | /** 131 | * Tips for 132 | */ 133 | const kTipsAfterAcceptSwap = 'You accepted an atomic swap. '; 134 | 135 | /** 136 | * Tips for 137 | */ 138 | const kTips110032 = 'You received a request to open a channel.'; 139 | 140 | /** 141 | * Tips for 142 | */ 143 | const kTips110033 = 'Your counterparty accepted to open channel, you should start to fund bitcoin.'; 144 | 145 | /** 146 | * Tips for 147 | */ 148 | const kTipsFirst110340 = 'You received a notification, please confirm the first bitcoin funding.'; 149 | 150 | /** 151 | * Tips for 152 | */ 153 | const kTipsSecond110340 = 'You received a notification, please confirm the second bitcoin funding.'; 154 | 155 | /** 156 | * Tips for 157 | */ 158 | const kTipsThird110340 = 'You received a notification, please confirm the third bitcoin funding.'; 159 | 160 | /** 161 | * Tips for 162 | */ 163 | const kTipsFirst110350 = 'Counterparty confirmed bitcoin funding, you can start the second bitcoin funding.'; 164 | 165 | /** 166 | * Tips for 167 | */ 168 | const kTipsSecond110350 = 'Counterparty confirmed funding bitcoin, you can start the third bitcoin funding.'; 169 | 170 | /** 171 | * Tips for 172 | */ 173 | const kTipsThird110350 = 'Counterparty confirmed funding bitcoin. Now, you should fund asset.'; 174 | 175 | /** 176 | * Tips for 177 | */ 178 | const kTips110034 = 'You received a notification, please confirm asset funding.'; 179 | 180 | /** 181 | * Tips for 182 | */ 183 | const kTips110035 = 'Counterparty confirmed asset funding. Now, the channel has been successfully created and funded.'; 184 | 185 | /** 186 | * Tips for 187 | */ 188 | const kTips110351 = 'You received a notification, please confirm the RSMC.'; 189 | 190 | /** 191 | * Tips for 192 | */ 193 | const kTips110352 = 'Counterparty confirmed the RSMC. Your balance is changed. You can start another RSMC.'; 194 | 195 | /** 196 | * Tips for 197 | */ 198 | const kTips110040 = 'You received a request to add HTLC.'; 199 | 200 | /** 201 | * Tips for 202 | */ 203 | const kTips110041 = 'Counterparty accepted the HTLC. Wait for secret R from counterparty.'; 204 | 205 | /** 206 | * Tips for 207 | */ 208 | const kTips110045 = 'You received the secret R from counterparty and you can sign the R.'; 209 | 210 | /** 211 | * Tips for 212 | */ 213 | const kTips110046 = 'Counterparty has signed the R. The HTLC is completed and you can request to terminate it.'; 214 | 215 | /** 216 | * Tips for 217 | */ 218 | const kTips110049 = 'You received a request to close current HTLC.'; 219 | 220 | /** 221 | * Tips for 222 | */ 223 | const kTips110050 = 'Counterparty has accepted to close HTLC. Next you can continue to use the channel.'; 224 | 225 | /** 226 | * Tips for 227 | */ 228 | const kTips110080 = 'You received a request to start an atomic swap'; 229 | 230 | /** 231 | * Tips for 232 | */ 233 | const kTips110081 = 'Counterparty has accepted the atomic swap. Next you can continue to use the channel.'; 234 | 235 | /** 236 | * Tips for 237 | */ 238 | const kTips110038 = 'You received a request to close the channel.'; 239 | 240 | /** 241 | * Tips for 242 | */ 243 | const kTips110039 = 'Counterparty has accepted to close the channel. This channel is closed.'; 244 | 245 | /** 246 | * Tips for 247 | */ 248 | const kTipsNoLocalData = 'The channel you selected has no locally stored data.'; 249 | 250 | 251 | //---------------------------------------------------------------- 252 | // Others 253 | 254 | /** 255 | * The path found is not for the current channel, please change to another channel 256 | */ 257 | const k100401 = 'The path found is not for the current channel, and will switch to another.'; 258 | 259 | /** 260 | * You did not confirm to switch the channel, the next operation may be wrong 261 | */ 262 | const k100401_ClickCancel = 'You did not confirm to switch the channel, the next operation may be wrong.'; 263 | 264 | /** 265 | * Pay Invoice is processing 266 | */ 267 | const kPayInvoice = 'Pay Invoice is processing ... Wait for response from counterparty.'; 268 | 269 | /** 270 | * Display Processing... 271 | */ 272 | const kProcessing = 'Processing...'; 273 | 274 | /** 275 | * Not Found the R 276 | */ 277 | const kNotFoundR = 'Multi-hop is processing...'; 278 | 279 | /** 280 | * 281 | */ 282 | const kMultiHopContinue = 'Counterparty has accepted to close HTLC. Multi-hop continues ...'; 283 | 284 | //---------------------------------------------------------------- 285 | // Status of a channel 286 | 287 | /** 288 | * openChannel done 289 | */ 290 | const kStatusOpenChannel = 1; 291 | 292 | /** 293 | * acceptChannel done 294 | */ 295 | const kStatusAcceptChannel = 2; 296 | 297 | /** 298 | * first fundingBitcoin done 299 | */ 300 | const kStatusFirstFundingBitcoin = 3; 301 | 302 | /** 303 | * first bitcoinFundingCreated done 304 | */ 305 | const kStatusFirstBitcoinFundingCreated = 4; 306 | 307 | /** 308 | * first bitcoinFundingSigned done 309 | */ 310 | const kStatusFirstBitcoinFundingSigned = 5; 311 | 312 | /** 313 | * second fundingBitcoin done 314 | */ 315 | const kStatusSecondFundingBitcoin = 6; 316 | 317 | /** 318 | * second bitcoinFundingCreated done 319 | */ 320 | const kStatusSecondBitcoinFundingCreated = 7; 321 | 322 | /** 323 | * second bitcoinFundingSigned done 324 | */ 325 | const kStatusSecondBitcoinFundingSigned = 8; 326 | 327 | /** 328 | * third fundingBitcoin done 329 | */ 330 | const kStatusThirdFundingBitcoin = 9; 331 | 332 | /** 333 | * third bitcoinFundingCreated done 334 | */ 335 | const kStatusThirdBitcoinFundingCreated = 10; 336 | 337 | /** 338 | * third bitcoinFundingSigned done 339 | */ 340 | const kStatusThirdBitcoinFundingSigned = 11; 341 | 342 | /** 343 | * fundingAsset done 344 | */ 345 | const kStatusFundingAsset = 12; 346 | 347 | /** 348 | * assetFundingCreated done 349 | */ 350 | const kStatusAssetFundingCreated = 13; 351 | 352 | /** 353 | * assetFundingSigned done 354 | */ 355 | const kStatusAssetFundingSigned = 14; 356 | 357 | /** 358 | * commitmentTransactionCreated done 359 | */ 360 | const kStatusCommitmentTransactionCreated = 15; 361 | 362 | /** 363 | * commitmentTransactionAccepted done 364 | */ 365 | const kStatusCommitmentTransactionAccepted = 16; 366 | 367 | /** 368 | * payInvoice done 369 | */ 370 | const kStatusPayInvoice = 17; 371 | 372 | /** 373 | * addHTLC done 374 | */ 375 | const kStatusAddHTLC = 18; 376 | 377 | /** 378 | * HTLCSigned done 379 | */ 380 | const kStatusHTLCSigned = 19; 381 | 382 | /** 383 | * forwardR done 384 | */ 385 | const kStatusForwardR = 20; 386 | 387 | /** 388 | * signR done 389 | */ 390 | const kStatusSignR = 21; 391 | 392 | /** 393 | * closeHTLC done 394 | */ 395 | const kStatusCloseHTLC = 22; 396 | 397 | /** 398 | * closeHTLCSigned done 399 | */ 400 | const kStatusCloseHTLCSigned = 23; 401 | 402 | /** 403 | * closeChannel done 404 | */ 405 | const kStatusCloseChannel = 24; 406 | 407 | /** 408 | * closeChannelSigned done 409 | */ 410 | const kStatusCloseChannelSigned = 0; 411 | 412 | /** 413 | * atomicSwap done 414 | */ 415 | const kStatusAtomicSwap = 26; 416 | 417 | /** 418 | * acceptSwap done 419 | */ 420 | const kStatusAcceptSwap = 27; 421 | 422 | //---------------------------------------------------------------- 423 | // Const 424 | 425 | /** 426 | * page_size 427 | */ 428 | const kPageSize = 5; 429 | 430 | /** 431 | * page_index 432 | */ 433 | const kPageIndex = 1; 434 | 435 | /** 436 | * 437 | */ 438 | const kIsSender = '0'; 439 | 440 | /** 441 | * 442 | */ 443 | const kIsReceiver = '1'; 444 | -------------------------------------------------------------------------------- /sdk/contracts.js: -------------------------------------------------------------------------------- 1 | // contracts.js 2 | // Contracts for Omni BOLT 3 | 4 | /** 5 | * Type -80 message notifies the counterparty an atomic swap is created. 6 | * The background and process of atomic swap can be found here in chapter 5 7 | * of the OmniBOLT specification, 8 | * 9 | * @param myUserID user id of currently loged in. 10 | * @param nodeID peer id of the obd node where the fundee logged in. 11 | * @param userID the user id of the fundee. 12 | * @param info 13 | * @param isFunder 14 | */ 15 | function atomicSwap(myUserID, nodeID, userID, info, isFunder) { 16 | return new Promise((resolve, reject) => { 17 | obdApi.atomicSwap(nodeID, userID, info, function(e) { 18 | console.info('SDK: -100080 atomicSwap = ' + JSON.stringify(e)); 19 | saveChannelStatus(myUserID, e.channel_id, isFunder, kStatusAtomicSwap); 20 | saveSenderRole(kIsSender); 21 | resolve(true); 22 | }); 23 | }) 24 | } 25 | 26 | /** 27 | * Type -81 Protocol accepts or rejects a swap. 28 | * 29 | * @param myUserID user id of currently loged in. 30 | * @param nodeID peer id of the obd node where the fundee logged in. 31 | * @param userID the user id of the fundee. 32 | * @param info 33 | * @param isFunder 34 | */ 35 | function acceptSwap(myUserID, nodeID, userID, info, isFunder) { 36 | return new Promise((resolve, reject) => { 37 | obdApi.atomicSwapAccepted(nodeID, userID, info, function(e) { 38 | console.info('SDK: -100081 atomicSwapAccepted = ' + JSON.stringify(e)); 39 | saveChannelStatus(myUserID, e.channel_id, isFunder, kStatusAcceptSwap); 40 | resolve(true); 41 | }); 42 | }) 43 | } -------------------------------------------------------------------------------- /sdk/htlc.js: -------------------------------------------------------------------------------- 1 | // htlc.js 2 | // HTLC Payment 3 | 4 | 5 | /** 6 | * create an invoice. 7 | * @param info 8 | * @param callback 9 | */ 10 | function addInvoice(info, callback) { 11 | obdApi.addInvoice(info, callback); 12 | } 13 | 14 | /** 15 | * automatically transfer asset to counterparty 16 | * @param myUserID The user id of logged in 17 | * @param channel_id 18 | * @param invoice 19 | */ 20 | function payInvoice(myUserID, channel_id, invoice) { 21 | return new Promise(async function(resolve, reject) { 22 | // Step 1: HTLCFindPath 23 | let info = new HTLCFindPathInfo(); 24 | info.invoice = invoice; 25 | info.is_inv_pay = true;// Is invoice payment 26 | 27 | let e = await HTLCFindPath(info); 28 | let path = e.routing_packet.split(','); 29 | if (channel_id != path[0]) { 30 | // Using new channel to process htlc. 31 | channel_id = path[0]; 32 | } 33 | 34 | savePayInvoiceCase('Yes'); 35 | 36 | // Step 2: addHTLC 37 | let resp = await payInvoiceStep2(e, myUserID, channel_id); 38 | 39 | let returnData = { 40 | nodeID: resp.nodeID, 41 | userID: resp.userID, 42 | info40: resp.info40, 43 | info100: resp.info100, 44 | privkey: resp.privkey, 45 | channel_id: channel_id, 46 | }; 47 | 48 | resolve(returnData); 49 | }) 50 | } 51 | 52 | /** 53 | * This protocol is the first step of a payment, 54 | * which seeks a full path of nodes, decide which path is the 55 | * optimistic one, in terms of hops, node's histroy service quility, and fees. 56 | * 57 | * @param info 58 | */ 59 | function HTLCFindPath(info) { 60 | return new Promise((resolve, reject) => { 61 | obdApi.HTLCFindPath(info, function(e) { 62 | // console.info('SDK: -100401 - HTLCFindPath = ' + JSON.stringify(e)); 63 | saveHTLCPathData(e); 64 | saveRoutingPacket(e.routing_packet); 65 | 66 | // Calculate how much htlc fee the sender should pay 67 | let htlcFee = getFeeOfEveryHop(e.amount); // fee of every hop 68 | let routs = e.routing_packet.split(','); 69 | let payFee = times(routs.length - 1, htlcFee); // should pay 70 | 71 | console.info('HTLCFindPath payFee = ' + payFee); 72 | savePayHtlcFee(payFee); 73 | resolve(e); 74 | }); 75 | }) 76 | } 77 | 78 | /** 79 | * Add an HTLC. 80 | * @param myUserID The user id of logged in 81 | * @param nodeID peer id of the obd node where the fundee logged in. 82 | * @param userID the user id of the fundee. 83 | * @param info 84 | * @param isFunder 85 | */ 86 | function addHTLC(myUserID, nodeID, userID, info, isFunder) { 87 | return new Promise((resolve, reject) => { 88 | obdApi.addHTLC(nodeID, userID, info, async function(e) { 89 | // console.info('SDK: -100040 addHTLC = ' + JSON.stringify(e)); 90 | 91 | // Sender sign the tx on client side 92 | // NO.1 93 | let cr = e.c3a_counterparty_raw_data; 94 | let inputs = cr.inputs; 95 | let privkey = await getFundingPrivKey(myUserID, e.channel_id); 96 | let cr_hex = signP2SH(true, cr.hex, cr.pub_key_a, cr.pub_key_b, 97 | privkey, inputs); 98 | 99 | // NO.2 100 | let hr = e.c3a_htlc_raw_data; 101 | inputs = hr.inputs; 102 | let hr_hex = signP2SH(true, hr.hex, hr.pub_key_a, hr.pub_key_b, 103 | privkey, inputs); 104 | 105 | // NO.3 106 | let rr = e.c3a_rsmc_raw_data; 107 | inputs = rr.inputs; 108 | let rr_hex = signP2SH(true, rr.hex, rr.pub_key_a, rr.pub_key_b, 109 | privkey, inputs); 110 | 111 | // will send 100100 112 | let signedInfo = new SignedInfo100100(); 113 | signedInfo.channel_id = e.channel_id; 114 | signedInfo.c3a_counterparty_partial_signed_hex = cr_hex; 115 | signedInfo.c3a_htlc_partial_signed_hex = hr_hex; 116 | signedInfo.c3a_rsmc_partial_signed_hex = rr_hex; 117 | 118 | await sendSignedHex100100(nodeID, userID, signedInfo); 119 | 120 | // save 3 privkeys 121 | saveTempPrivKey(myUserID, kRsmcTempPrivKey, e.channel_id, 122 | getPrivKeyFromPubKey(myUserID, info.curr_rsmc_temp_address_pub_key)); 123 | saveTempPrivKey(myUserID, kHtlcTempPrivKey, e.channel_id, 124 | getPrivKeyFromPubKey(myUserID, info.curr_htlc_temp_address_pub_key)); 125 | saveTempPrivKey(myUserID, kHtlcHtnxTempPrivKey, e.channel_id, 126 | getPrivKeyFromPubKey(myUserID, info.curr_htlc_temp_address_for_ht1a_pub_key)); 127 | 128 | // 129 | saveChannelStatus(myUserID, e.channel_id, isFunder, kStatusAddHTLC); 130 | saveCounterparty(myUserID, e.channel_id, nodeID, userID); 131 | saveSenderRole(kIsSender); 132 | 133 | resolve(signedInfo); 134 | }); 135 | }) 136 | } 137 | 138 | /** 139 | * Type -100100 Protocol send signed info that signed in 100040 to OBD. 140 | * @param nodeID peer id of the obd node where the fundee logged in. 141 | * @param userID the user id of the fundee. 142 | * @param signedInfo 143 | */ 144 | function sendSignedHex100100(nodeID, userID, signedInfo) { 145 | return new Promise((resolve, reject) => { 146 | obdApi.sendSignedHex100100(nodeID, userID, signedInfo, function(e) { 147 | // console.info('sendSignedHex100100 = ' + JSON.stringify(e)); 148 | resolve(true); 149 | }); 150 | }) 151 | } 152 | 153 | /** 154 | * Type -100041 Protocol is used to response an incoming HTLC. 155 | * @param myUserID The user id of logged in 156 | * @param nodeID peer id of the obd node where the fundee logged in. 157 | * @param userID the user id of the fundee. 158 | * @param info 159 | */ 160 | function HTLCSigned(myUserID, nodeID, userID, info) { 161 | return new Promise((resolve, reject) => { 162 | obdApi.htlcSigned(nodeID, userID, info, async function(e) { 163 | // console.info('SDK: -100041 htlcSigned = ' + JSON.stringify(e)); 164 | 165 | let channel_id = e.channel_id; 166 | 167 | // Sign the tx on client side 168 | // NO.1 169 | let ahb = e.c3a_htlc_br_raw_data; 170 | let inputs = ahb.inputs; 171 | let privkey = await getFundingPrivKey(myUserID, channel_id); 172 | let ahb_hex = signP2SH(true, ahb.hex, ahb.pub_key_a, ahb.pub_key_b, privkey, inputs); 173 | 174 | // NO.2 175 | let ahl = e.c3a_htlc_hlock_raw_data; 176 | inputs = ahl.inputs; 177 | let ahl_hex = signP2SH(true, ahl.hex, ahl.pub_key_a, ahl.pub_key_b, privkey, inputs); 178 | 179 | // NO.3 180 | let ahh = e.c3a_htlc_ht_raw_data; 181 | inputs = ahh.inputs; 182 | let ahh_hex = signP2SH(true, ahh.hex, ahh.pub_key_a, ahh.pub_key_b, privkey, inputs); 183 | 184 | // NO.4 185 | let arb = e.c3a_rsmc_br_raw_data; 186 | inputs = arb.inputs; 187 | let arb_hex = signP2SH(true, arb.hex, arb.pub_key_a, arb.pub_key_b, privkey, inputs); 188 | 189 | // NO.5 190 | let arr = e.c3a_rsmc_rd_raw_data; 191 | inputs = arr.inputs; 192 | let arr_hex = signP2SH(true, arr.hex, arr.pub_key_a, arr.pub_key_b, privkey, inputs); 193 | 194 | // NO.6 195 | let bc = e.c3b_counterparty_raw_data; 196 | inputs = bc.inputs; 197 | let bc_hex = signP2SH(true, bc.hex, bc.pub_key_a, bc.pub_key_b, privkey, inputs); 198 | 199 | // NO.7 200 | let bh = e.c3b_htlc_raw_data; 201 | inputs = bh.inputs; 202 | let bh_hex = signP2SH(true, bh.hex, bh.pub_key_a, bh.pub_key_b, privkey, inputs); 203 | 204 | // NO.8 205 | let br = e.c3b_rsmc_raw_data; 206 | inputs = br.inputs; 207 | let br_hex = signP2SH(true, br.hex, br.pub_key_a, br.pub_key_b, privkey, inputs); 208 | 209 | // will send 100101 210 | let signedInfo = new SignedInfo100101(); 211 | signedInfo.channel_id = channel_id; 212 | signedInfo.c3a_rsmc_rd_partial_signed_hex = arr_hex; 213 | signedInfo.c3a_rsmc_br_partial_signed_hex = arb_hex; 214 | signedInfo.c3a_htlc_ht_partial_signed_hex = ahh_hex; 215 | signedInfo.c3a_htlc_hlock_partial_signed_hex = ahl_hex; 216 | signedInfo.c3a_htlc_br_partial_signed_hex = ahb_hex; 217 | signedInfo.c3b_rsmc_partial_signed_hex = br_hex; 218 | signedInfo.c3b_counterparty_partial_signed_hex = bc_hex; 219 | signedInfo.c3b_htlc_partial_signed_hex = bh_hex; 220 | 221 | await sendSignedHex100101(nodeID, userID, signedInfo); 222 | 223 | // save some data 224 | let privkey1 = getPrivKeyFromPubKey(myUserID, info.curr_rsmc_temp_address_pub_key); 225 | let privkey2 = getPrivKeyFromPubKey(myUserID, info.curr_htlc_temp_address_pub_key); 226 | saveTempPrivKey(myUserID, kRsmcTempPrivKey, channel_id, privkey1); 227 | saveTempPrivKey(myUserID, kHtlcTempPrivKey, channel_id, privkey2); 228 | saveCounterparty(myUserID, channel_id, nodeID, userID); 229 | resolve(signedInfo); 230 | }); 231 | }) 232 | } 233 | 234 | /** 235 | * Type -100101 Protocol send signed info that signed in 100041 to OBD. 236 | * @param nodeID peer id of the obd node where the fundee logged in. 237 | * @param userID the user id of the fundee. 238 | * @param signedInfo 239 | */ 240 | function sendSignedHex100101(nodeID, userID, signedInfo) { 241 | return new Promise((resolve, reject) => { 242 | obdApi.sendSignedHex100101(nodeID, userID, signedInfo, function(e) { 243 | // console.info('sendSignedHex100101 = ' + JSON.stringify(e)); 244 | resolve(true); 245 | }); 246 | }) 247 | } 248 | 249 | /** 250 | * Type -100102 Protocol send signed info that signed in 110041 to OBD. 251 | * @param myUserID user id of currently loged in. 252 | * @param signedInfo 253 | */ 254 | function sendSignedHex100102(myUserID, signedInfo) { 255 | return new Promise((resolve, reject) => { 256 | obdApi.sendSignedHex100102(signedInfo, async function(e) { 257 | // console.info('sendSignedHex100102 = ' + JSON.stringify(e)); 258 | 259 | let nodeID = e.payee_node_address; 260 | let userID = e.payee_peer_id; 261 | let channel_id = e.channel_id; 262 | 263 | // Sign the tx on client side 264 | // NO.1 265 | let ahh = e.c3a_htlc_htrd_raw_data; 266 | let inputs = ahh.inputs; 267 | let temp3 = getTempPrivKey(myUserID, kHtlcHtnxTempPrivKey, channel_id); 268 | let ahh_hex = signP2SH(true, ahh.hex, ahh.pub_key_a, ahh.pub_key_b, temp3, inputs); 269 | 270 | // NO.2 271 | let brb = e.c3b_rsmc_br_raw_data; 272 | inputs = brb.inputs; 273 | let privkey = await getFundingPrivKey(myUserID, channel_id); 274 | let brb_hex = signP2SH(true, brb.hex, brb.pub_key_a, brb.pub_key_b, privkey, inputs); 275 | 276 | // NO.3 277 | let brr = e.c3b_rsmc_rd_raw_data; 278 | inputs = brr.inputs; 279 | let brr_hex = signP2SH(true, brr.hex, brr.pub_key_a, brr.pub_key_b, privkey, inputs); 280 | 281 | // NO.4 282 | let bhb = e.c3b_htlc_br_raw_data; 283 | inputs = bhb.inputs; 284 | let bhb_hex = signP2SH(true, bhb.hex, bhb.pub_key_a, bhb.pub_key_b, privkey, inputs); 285 | 286 | // NO.5 287 | let bhl = e.c3b_htlc_hlock_raw_data; 288 | inputs = bhl.inputs; 289 | let bhl_hex = signP2SH(true, bhl.hex, bhl.pub_key_a, bhl.pub_key_b, privkey, inputs); 290 | 291 | // NO.6 292 | let bhh = e.c3b_htlc_htd_raw_data; 293 | inputs = bhh.inputs; 294 | let bhh_hex = signP2SH(true, bhh.hex, bhh.pub_key_a, bhh.pub_key_b, privkey, inputs); 295 | 296 | // will send 100103 297 | let signedInfo = new SignedInfo100103(); 298 | signedInfo.channel_id = channel_id; 299 | signedInfo.c3a_htlc_htrd_partial_signed_hex = ahh_hex; 300 | signedInfo.c3b_rsmc_rd_partial_signed_hex = brr_hex; 301 | signedInfo.c3b_rsmc_br_partial_signed_hex = brb_hex; 302 | signedInfo.c3b_htlc_htd_partial_signed_hex = bhh_hex; 303 | signedInfo.c3b_htlc_hlock_partial_signed_hex = bhl_hex; 304 | signedInfo.c3b_htlc_br_partial_signed_hex = bhb_hex; 305 | 306 | await sendSignedHex100103(nodeID, userID, signedInfo); 307 | 308 | let returnData = { 309 | nodeID: nodeID, 310 | userID: userID, 311 | signedInfo: signedInfo 312 | }; 313 | 314 | resolve(returnData); 315 | }); 316 | }) 317 | } 318 | 319 | /** 320 | * Type -100103 Protocol send signed info that signed in 100040 to OBD. 321 | * @param nodeID peer id of the obd node where the fundee logged in. 322 | * @param userID the user id of the fundee. 323 | * @param signedInfo 324 | */ 325 | function sendSignedHex100103(nodeID, userID, signedInfo) { 326 | return new Promise((resolve, reject) => { 327 | obdApi.sendSignedHex100103(nodeID, userID, signedInfo, function(e) { 328 | // console.info('sendSignedHex100103 = ' + JSON.stringify(e)); 329 | resolve(true); 330 | }); 331 | }) 332 | } 333 | 334 | /** 335 | * Type -100104 Protocol send signed info that signed in 110042 to OBD. 336 | * @param myUserID user id of currently loged in. 337 | * @param signedInfo 338 | */ 339 | function sendSignedHex100104(myUserID, signedInfo) { 340 | return new Promise((resolve, reject) => { 341 | obdApi.sendSignedHex100104(signedInfo, async function(e) { 342 | // console.info('sendSignedHex100104 = ' + JSON.stringify(e)); 343 | 344 | let nodeID = e.payer_node_address; 345 | let userID = e.payer_peer_id; 346 | let channel_id = e.channel_id; 347 | 348 | // Sign the tx on client side 349 | // NO.1 350 | let tx = e.c3b_htlc_hlock_he_raw_data; 351 | let inputs = tx.inputs; 352 | let privkey = await getFundingPrivKey(myUserID, channel_id); 353 | let hex = signP2SH(true, tx.hex, tx.pub_key_a, tx.pub_key_b, privkey, inputs); 354 | 355 | // will send 100105 356 | let signedInfo = new SignedInfo100105(); 357 | signedInfo.channel_id = channel_id; 358 | signedInfo.c3b_htlc_hlock_he_partial_signed_hex = hex; 359 | 360 | let resp = await sendSignedHex100105(myUserID, nodeID, userID, signedInfo, channel_id); 361 | 362 | let returnData; 363 | if (resp.status === false) { 364 | returnData = { 365 | status: false, 366 | nodeID: nodeID, 367 | userID: userID, 368 | info105: signedInfo, 369 | infoStep2: resp.infoStep2, 370 | }; 371 | 372 | } else { 373 | returnData = { 374 | status: true, 375 | nodeID: nodeID, 376 | userID: userID, 377 | info105: signedInfo, 378 | info45: resp.info45, 379 | info106: resp.info106, 380 | }; 381 | } 382 | 383 | resolve(returnData); 384 | }); 385 | }) 386 | } 387 | 388 | /** 389 | * Type -100105 Protocol send signed info that signed in 100104 to OBD. 390 | * @param myUserID user id of currently loged in. 391 | * @param nodeID peer id of the obd node where the fundee logged in. 392 | * @param userID the user id of the fundee. 393 | * @param signedInfo 394 | * @param channel_id 395 | */ 396 | function sendSignedHex100105(myUserID, nodeID, userID, signedInfo, channel_id) { 397 | return new Promise((resolve, reject) => { 398 | obdApi.sendSignedHex100105(nodeID, userID, signedInfo, async function(e) { 399 | // console.info('sendSignedHex100105 = ' + JSON.stringify(e)); 400 | 401 | let isFunder = await getIsFunder(myUserID, channel_id); 402 | saveChannelStatus(myUserID, channel_id, isFunder, kStatusHTLCSigned); 403 | 404 | //------------------------------------------ 405 | // If Bob has R, will send -100045 forwardR 406 | let resp = await payInvoiceStep4(myUserID, nodeID, userID, channel_id, e); 407 | 408 | if (resp.status === false) { // A multi-hop 409 | let returnData = { 410 | status: false, 411 | infoStep2: resp.infoStep2, 412 | }; 413 | resolve(returnData); 414 | } else { 415 | let returnData = { 416 | status: true, 417 | info45: resp.info45, 418 | info106: resp.info106, 419 | }; 420 | resolve(returnData); 421 | } 422 | }); 423 | }) 424 | } 425 | 426 | /** 427 | * Type -100045 Protocol is used to forward R to a user. 428 | * @param myUserID The user id of logged in 429 | * @param nodeID peer id of the obd node where the fundee logged in. 430 | * @param userID the user id of the fundee. 431 | * @param info 432 | * @param isFunder 433 | */ 434 | function forwardR(myUserID, nodeID, userID, info, isFunder) { 435 | return new Promise((resolve, reject) => { 436 | obdApi.forwardR(nodeID, userID, info, async function(e) { 437 | // console.info('SDK: -100045 forwardR = ' + JSON.stringify(e)); 438 | 439 | let channel_id = e.channel_id; 440 | 441 | // Sign the tx on client side 442 | // NO.1 443 | let tx = e.c3b_htlc_herd_raw_data; 444 | let inputs = tx.inputs; 445 | let temp3 = getTempPrivKey(myUserID, kHtlcHtnxTempPrivKey, channel_id); 446 | let hex = signP2SH(true, tx.hex, tx.pub_key_a, tx.pub_key_b, temp3, inputs); 447 | 448 | // will send 100106 449 | let signedInfo = new SignedInfo100106(); 450 | signedInfo.channel_id = channel_id; 451 | signedInfo.c3b_htlc_herd_partial_signed_hex = hex; 452 | 453 | await sendSignedHex100106(nodeID, userID, signedInfo); 454 | saveChannelStatus(myUserID, channel_id, isFunder, kStatusForwardR); 455 | resolve(signedInfo); 456 | }); 457 | }) 458 | } 459 | 460 | /** 461 | * Type -100106 Protocol send signed info that signed in 100045 to OBD. 462 | * @param nodeID peer id of the obd node where the fundee logged in. 463 | * @param userID the user id of the fundee. 464 | * @param signedInfo 465 | */ 466 | function sendSignedHex100106(nodeID, userID, signedInfo) { 467 | return new Promise((resolve, reject) => { 468 | obdApi.sendSignedHex100106(nodeID, userID, signedInfo, function(e) { 469 | // console.info('sendSignedHex100106 = ' + JSON.stringify(e)); 470 | resolve(true); 471 | }); 472 | }) 473 | } 474 | 475 | /** 476 | * Type -100110 Protocol send signed info that signed in 100049 to OBD. 477 | * @param nodeID peer id of the obd node where the fundee logged in. 478 | * @param userID the user id of the fundee. 479 | * @param signedInfo 480 | */ 481 | function sendSignedHex100110(nodeID, userID, signedInfo) { 482 | return new Promise((resolve, reject) => { 483 | obdApi.sendSignedHex100110(nodeID, userID, signedInfo, function(e) { 484 | // console.info('sendSignedHex100110 = ' + JSON.stringify(e)); 485 | resolve(true); 486 | }); 487 | }) 488 | } 489 | 490 | /** 491 | * Type -100111 Protocol send signed info that signed in 100050 to OBD. 492 | * @param nodeID peer id of the obd node where the fundee logged in. 493 | * @param userID the user id of the fundee. 494 | * @param signedInfo 495 | */ 496 | function sendSignedHex100111(nodeID, userID, signedInfo) { 497 | return new Promise((resolve, reject) => { 498 | obdApi.sendSignedHex100111(nodeID, userID, signedInfo, function(e) { 499 | // console.info('sendSignedHex100111 = ' + JSON.stringify(e)); 500 | resolve(true); 501 | }); 502 | }) 503 | } 504 | 505 | /** 506 | * Type -100112 Protocol send signed info that signed in 110050 to OBD. 507 | * @param myUserID The user id of logged in 508 | * @param signedInfo 509 | */ 510 | function sendSignedHex100112(myUserID, signedInfo) { 511 | return new Promise((resolve, reject) => { 512 | obdApi.sendSignedHex100112(signedInfo, async function(e) { 513 | // console.info('sendSignedHex100112 = ' + JSON.stringify(e)); 514 | 515 | let nodeID = e.sendee_node_address; 516 | let userID = e.sendee_peer_id; 517 | let channel_id = e.channel_id; 518 | 519 | // Sign the tx on client side 520 | // NO.1 521 | let br = e.c4b_br_raw_data; 522 | let inputs = br.inputs; 523 | let privkey = await getFundingPrivKey(myUserID, channel_id); 524 | let br_hex = signP2SH(true, br.hex, br.pub_key_a, br.pub_key_b, privkey, inputs); 525 | 526 | // NO.2 527 | let rd = e.c4b_rd_raw_data; 528 | inputs = rd.inputs; 529 | let rd_hex = signP2SH(true, rd.hex, rd.pub_key_a, rd.pub_key_b, privkey, inputs); 530 | 531 | // will send 100113 532 | let signedInfo = new SignedInfo100113(); 533 | signedInfo.channel_id = channel_id; 534 | signedInfo.c4b_rd_partial_signed_hex = rd_hex; 535 | signedInfo.c4b_br_partial_signed_hex = br_hex; 536 | signedInfo.c4b_br_id = br.br_id; 537 | 538 | let resp = await sendSignedHex100113(myUserID, nodeID, userID, signedInfo); 539 | 540 | if (resp === true) { 541 | let returnData = { 542 | status: true, 543 | nodeID: nodeID, 544 | userID: userID, 545 | info113: signedInfo, 546 | }; 547 | 548 | resolve(returnData); 549 | 550 | } else { 551 | let returnData = { 552 | status: false, 553 | nodeID: nodeID, 554 | userID: userID, 555 | info113: signedInfo, 556 | nodeID2: resp.nodeID, 557 | userID2: resp.userID, 558 | info45: resp.info45, 559 | info106: resp.info106, 560 | }; 561 | 562 | resolve(returnData); 563 | } 564 | }); 565 | }) 566 | } 567 | 568 | /** 569 | * Type -100113 Protocol send signed info that signed in 100112 to OBD. 570 | * 571 | * @param myUserID The user id of logged in 572 | * @param nodeID peer id of the obd node where the fundee logged in. 573 | * @param userID the user id of the fundee. 574 | * @param signedInfo 575 | */ 576 | function sendSignedHex100113(myUserID, nodeID, userID, signedInfo) { 577 | return new Promise((resolve, reject) => { 578 | obdApi.sendSignedHex100113(nodeID, userID, signedInfo, async function(e) { 579 | // console.info('sendSignedHex100113 = ' + JSON.stringify(e)); 580 | 581 | let channel_id = e.channel_id; 582 | 583 | // save some data 584 | let isFunder = await getIsFunder(myUserID, channel_id); 585 | saveChannelStatus(myUserID, channel_id, isFunder, kStatusCloseHTLCSigned); 586 | savePayInvoiceCase('No'); 587 | 588 | // Find previous channel_id in htlc_routing_packet 589 | let resp = await continueForwardR(myUserID, channel_id); 590 | saveRoutingPacket(''); 591 | resolve(resp); 592 | }); 593 | }) 594 | } 595 | 596 | /** 597 | * Type -100114 Protocol send signed info that signed in 110051 to OBD. 598 | * @param myUserID The user id of logged in 599 | * @param channel_id 600 | */ 601 | function continueForwardR(myUserID, channel_id) { 602 | return new Promise(async function(resolve, reject) { 603 | 604 | // Find previous channel_id in htlc_routing_packet 605 | let prevStep; 606 | let path = getRoutingPacket(); 607 | if (path === null || path === '') { 608 | // console.info('RoutingPacket IS NULL'); 609 | resolve(true); 610 | return; 611 | } 612 | 613 | let routs = path.split(','); 614 | for (let i = 0; i < routs.length; i++) { 615 | if (routs[i] === channel_id) { 616 | prevStep = i - 1; 617 | break; 618 | } 619 | } 620 | // console.info('previous channel_id = ' + prevStep); 621 | 622 | // This is a multi-hop 623 | if (prevStep >= 0) { 624 | // Get channel_id of between middleman and previous node 625 | let prev_channel_id = routs[prevStep]; 626 | 627 | // Middleman send -100045 forwardR to previous node. 628 | let info = new ForwardRInfo(); 629 | info.channel_id = prev_channel_id; 630 | info.r = getInvoiceR(); 631 | 632 | // console.info('continueForwardR ForwardRInfo = ' + JSON.stringify(info)); 633 | 634 | let isFunder = await getIsFunder(myUserID, prev_channel_id); 635 | let cp = await getCounterparty(myUserID, prev_channel_id); 636 | let resp = await forwardR(myUserID, cp.toNodeID, cp.toUserID, info, isFunder); 637 | 638 | let returnData = { 639 | nodeID: cp.toNodeID, 640 | userID: cp.toUserID, 641 | info45: info, 642 | info106: resp, 643 | }; 644 | 645 | resolve(returnData); 646 | 647 | } else { 648 | resolve(true); 649 | } 650 | }) 651 | } 652 | 653 | /** 654 | * Type -100114 Protocol send signed info that signed in 110051 to OBD. 655 | * @param myUserID The user id of logged in 656 | * @param channel_id 657 | * @param signedInfo 658 | */ 659 | function sendSignedHex100114(myUserID, channel_id, signedInfo) { 660 | return new Promise((resolve, reject) => { 661 | obdApi.sendSignedHex100114(signedInfo, async function(e) { 662 | // console.info('sendSignedHex100114 = ' + JSON.stringify(e)); 663 | // Reset some data at Bob side 664 | saveInvoiceH(''); 665 | savePayInvoiceCase('No'); 666 | 667 | // Find previous channel_id in htlc_routing_packet 668 | let resp = await continueForwardR(myUserID, channel_id); 669 | saveRoutingPacket(''); 670 | resolve(resp); 671 | }); 672 | }) 673 | } 674 | 675 | /** 676 | * Type -100046 Protocol is used to recieve reverify R. 677 | * If correct, then creates rest HTLC commitment transactions. 678 | * 679 | * @param myUserID The user id of logged in 680 | * @param nodeID peer id of the obd node where the fundee logged in. 681 | * @param userID the user id of the fundee. 682 | * @param info 683 | * @param isFunder 684 | */ 685 | function signR(myUserID, nodeID, userID, info, isFunder) { 686 | return new Promise((resolve, reject) => { 687 | obdApi.signR(nodeID, userID, info, function(e) { 688 | // console.info('SDK: -100046 signR = ' + JSON.stringify(e)); 689 | saveChannelStatus(myUserID, e.channel_id, isFunder, kStatusSignR); 690 | resolve(true); 691 | }); 692 | }) 693 | } 694 | 695 | /** 696 | * Type -100049 message is used to close a HTLC. 697 | * 698 | * @param myUserID The user id of logged in 699 | * @param nodeID peer id of the obd node where the fundee logged in. 700 | * @param userID the user id of the fundee. 701 | * @param info 702 | * @param isFunder 703 | */ 704 | function closeHTLC(myUserID, nodeID, userID, info, isFunder) { 705 | return new Promise((resolve, reject) => { 706 | obdApi.closeHTLC(nodeID, userID, info, async function(e) { 707 | // console.info('SDK: -100049 closeHTLC = ' + JSON.stringify(e)); 708 | 709 | let channel_id = e.channel_id; 710 | 711 | // Sign the tx on client side 712 | // NO.1 713 | let cr = e.c4a_counterparty_raw_data; 714 | let inputs = cr.inputs; 715 | let privkey = await getFundingPrivKey(myUserID, channel_id); 716 | let cr_hex = signP2SH(true, cr.hex, cr.pub_key_a, cr.pub_key_b, privkey, inputs); 717 | 718 | // NO.2 719 | let rr = e.c4a_rsmc_raw_data; 720 | inputs = rr.inputs; 721 | let rr_hex = signP2SH(true, rr.hex, rr.pub_key_a, rr.pub_key_b, privkey, inputs); 722 | 723 | // will send 100110 724 | let signedInfo = new SignedInfo100110(); 725 | signedInfo.channel_id = channel_id; 726 | signedInfo.counterparty_partial_signed_hex = cr_hex; 727 | signedInfo.rsmc_partial_signed_hex = rr_hex; 728 | 729 | await sendSignedHex100110(nodeID, userID, signedInfo); 730 | 731 | // save some data 732 | let tempkey = getPrivKeyFromPubKey(myUserID, info.curr_temp_address_pub_key); 733 | saveTempPrivKey(myUserID, kTempPrivKey, channel_id, tempkey); 734 | saveChannelStatus(myUserID, channel_id, isFunder, kStatusCloseHTLC); 735 | saveSenderRole(kIsSender); 736 | 737 | resolve(signedInfo); 738 | }); 739 | }) 740 | } 741 | 742 | /** 743 | * Type -100050 Protocol is used to response the request of close HTLC . 744 | * 745 | * @param myUserID The user id of logged in 746 | * @param nodeID peer id of the obd node where the fundee logged in. 747 | * @param userID the user id of the fundee. 748 | * @param info 749 | * @param isFunder 750 | */ 751 | function closeHTLCSigned(myUserID, nodeID, userID, info, isFunder) { 752 | return new Promise((resolve, reject) => { 753 | obdApi.closeHTLCSigned(nodeID, userID, info, async function(e) { 754 | // console.info('SDK: -100050 closeHTLCSigned = ' + JSON.stringify(e)); 755 | 756 | let channel_id = e.channel_id; 757 | 758 | // Sign the tx on client side 759 | // NO.1 760 | let abr = e.c4a_br_raw_data; 761 | let inputs = abr.inputs; 762 | let privkey = await getFundingPrivKey(myUserID, channel_id); 763 | let abr_hex = signP2SH(true, abr.hex, abr.pub_key_a, abr.pub_key_b, privkey, inputs); 764 | 765 | // NO.2 766 | let ard = e.c4a_rd_raw_data; 767 | inputs = ard.inputs; 768 | let ard_hex = signP2SH(true, ard.hex, ard.pub_key_a, ard.pub_key_b, privkey, inputs); 769 | 770 | // NO.3 771 | let bcr = e.c4b_counterparty_raw_data; 772 | inputs = bcr.inputs; 773 | let bcr_hex = signP2SH(true, bcr.hex, bcr.pub_key_a, bcr.pub_key_b, privkey, inputs); 774 | 775 | // NO.4 776 | let brr = e.c4b_rsmc_raw_data; 777 | inputs = brr.inputs; 778 | let brr_hex = signP2SH(true, brr.hex, brr.pub_key_a, brr.pub_key_b, privkey, inputs); 779 | 780 | // will send 100111 781 | let signedInfo = new SignedInfo100111(); 782 | signedInfo.channel_id = channel_id; 783 | signedInfo.c4a_rd_signed_hex = ard_hex; 784 | signedInfo.c4a_br_signed_hex = abr_hex; 785 | signedInfo.c4a_br_id = abr.br_id; 786 | signedInfo.c4b_rsmc_signed_hex = brr_hex; 787 | signedInfo.c4b_counterparty_signed_hex = bcr_hex; 788 | 789 | await sendSignedHex100111(nodeID, userID, signedInfo); 790 | 791 | // save some data 792 | let tempkey = getPrivKeyFromPubKey(myUserID, info.curr_temp_address_pub_key); 793 | saveTempPrivKey(myUserID, kTempPrivKey, channel_id, tempkey); 794 | saveChannelStatus(myUserID, channel_id, isFunder, kStatusCloseHTLCSigned); 795 | 796 | resolve(signedInfo); 797 | }); 798 | }) 799 | } 800 | -------------------------------------------------------------------------------- /sdk/manage_asset.js: -------------------------------------------------------------------------------- 1 | // manage_asset.js 2 | // Manage assets on Omni Layer platform 3 | 4 | /** 5 | * Type -102113 Protocol is used to create new tokens with fixed amount supply. 6 | * @param info 7 | */ 8 | function issueFixedAmount(info) { 9 | obdApi.issueFixedAmount(info, function(e) { 10 | console.info('SDK: -102113 issueFixedAmount = ' + JSON.stringify(e)); 11 | }); 12 | } 13 | 14 | /** 15 | * Type -102114 Protocol is used to create new tokens with manageable amount supply. 16 | * 17 | * NOTE: Record the txid returned by the OBD, and then you can use the 18 | * getTransaction (type-102118) API to get the property ID of the 19 | * manageable asset you issued. 20 | * 21 | * @param info 22 | */ 23 | function issueManagedAmout(info) { 24 | obdApi.issueManagedAmout(info, function(e) { 25 | console.info('SDK: -102114 issueManagedAmout = ' + JSON.stringify(e)); 26 | }); 27 | } 28 | 29 | /** 30 | * Type -102115 Protocol is used to issue or grant new units of managed tokens. 31 | * @param info 32 | */ 33 | function sendGrant(info) { 34 | obdApi.sendGrant(info, function(e) { 35 | console.info('SDK: -102115 sendGrant = ' + JSON.stringify(e)); 36 | }); 37 | } 38 | 39 | /** 40 | * Type -102116 Protocol is used to revoke units of managed tokens. 41 | * @param info 42 | */ 43 | function sendRevoke(info) { 44 | obdApi.sendRevoke(info, function(e) { 45 | console.info('SDK: -102116 sendRevoke = ' + JSON.stringify(e)); 46 | }); 47 | } 48 | -------------------------------------------------------------------------------- /sdk/number_precision.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @desc Solve the problem of floating point arithmetic, 3 | * avoid multiple digits after the decimal point and 4 | * loss of calculation accuracy. 5 | * Examples:2.3 + 2.4 = 4.699999999999999,1.0 - 0.9 = 0.09999999999999998 6 | */ 7 | /** 8 | * Convert wrong data into correct 9 | * strip(0.09999999999999998)=0.1 10 | */ 11 | function strip(num, precision = 15) { 12 | return +parseFloat(Number(num).toPrecision(precision)); 13 | } 14 | /** 15 | * Return digits length of a number 16 | * @param {*number} num Input number 17 | */ 18 | function digitLength(num) { 19 | // Get digit length of e 20 | const eSplit = num.toString().split(/[eE]/); 21 | const len = (eSplit[0].split('.')[1] || '').length - +(eSplit[1] || 0); 22 | return len > 0 ? len : 0; 23 | } 24 | /** 25 | * Convert decimals to integers and support scientific notation. 26 | * If it is a decimal, it is enlarged to an integer 27 | * @param {*number} num Input number 28 | */ 29 | function float2Fixed(num) { 30 | if (num.toString().indexOf('e') === -1) { 31 | return Number(num.toString().replace('.', '')); 32 | } 33 | const dLen = digitLength(num); 34 | return dLen > 0 ? strip(Number(num) * Math.pow(10, dLen)) : Number(num); 35 | } 36 | /** 37 | * Check whether the number is out of range, and give a prompt if it is out of range 38 | * @param {*number} num Input number 39 | */ 40 | function checkBoundary(num) { 41 | if (_boundaryCheckingState) { 42 | if (num > Number.MAX_SAFE_INTEGER || num < Number.MIN_SAFE_INTEGER) { 43 | console.warn(`${num} is beyond boundary when transfer to integer, the results may not be accurate`); 44 | } 45 | } 46 | } 47 | /** 48 | * Exact multiplication 49 | */ 50 | function times(num1, num2, ...others) { 51 | if (others.length > 0) { 52 | return times(times(num1, num2), others[0], ...others.slice(1)); 53 | } 54 | const num1Changed = float2Fixed(num1); 55 | const num2Changed = float2Fixed(num2); 56 | const baseNum = digitLength(num1) + digitLength(num2); 57 | const leftValue = num1Changed * num2Changed; 58 | checkBoundary(leftValue); 59 | return leftValue / Math.pow(10, baseNum); 60 | } 61 | /** 62 | * Exact addition 63 | */ 64 | function plus(num1, num2, ...others) { 65 | if (others.length > 0) { 66 | return plus(plus(num1, num2), others[0], ...others.slice(1)); 67 | } 68 | const baseNum = Math.pow(10, Math.max(digitLength(num1), digitLength(num2))); 69 | return (times(num1, baseNum) + times(num2, baseNum)) / baseNum; 70 | } 71 | /** 72 | * Exact subtraction 73 | */ 74 | function minus(num1, num2, ...others) { 75 | if (others.length > 0) { 76 | return minus(minus(num1, num2), others[0], ...others.slice(1)); 77 | } 78 | const baseNum = Math.pow(10, Math.max(digitLength(num1), digitLength(num2))); 79 | return (times(num1, baseNum) - times(num2, baseNum)) / baseNum; 80 | } 81 | /** 82 | * Exact division 83 | */ 84 | function divide(num1, num2, ...others) { 85 | if (others.length > 0) { 86 | return divide(divide(num1, num2), others[0], ...others.slice(1)); 87 | } 88 | const num1Changed = float2Fixed(num1); 89 | const num2Changed = float2Fixed(num2); 90 | checkBoundary(num1Changed); 91 | checkBoundary(num2Changed); 92 | // fix: like 10 ** -4 为 0.00009999999999999999,strip fix it. 93 | return times(num1Changed / num2Changed, strip(Math.pow(10, digitLength(num2) - digitLength(num1)))); 94 | } 95 | /** 96 | * rounding 97 | */ 98 | function round(num, ratio) { 99 | const base = Math.pow(10, ratio); 100 | return divide(Math.round(times(num, base)), base); 101 | } 102 | let _boundaryCheckingState = true; 103 | /** 104 | * Whether to perform boundary check, enabled by default 105 | * @param flag true is on, false is off, default is true 106 | */ 107 | function enableBoundaryChecking(flag = true) { 108 | _boundaryCheckingState = flag; 109 | } 110 | -------------------------------------------------------------------------------- /sdk/pojo.js: -------------------------------------------------------------------------------- 1 | class Message { 2 | constructor() { 3 | this.data = new Object(); 4 | this.recipient_user_peer_id = ""; 5 | this.recipient_node_peer_id = ""; 6 | } 7 | } 8 | class BtcFundingInfo { 9 | constructor() { 10 | this.from_address = ""; 11 | this.from_address_private_key = ""; 12 | this.to_address = ""; 13 | this.amount = 0.0; 14 | this.miner_fee = 0.0; 15 | } 16 | } 17 | class FundingBtcCreated { 18 | constructor() { 19 | this.temporary_channel_id = ""; 20 | this.funding_tx_hex = ""; 21 | } 22 | } 23 | class FundingBtcSigned { 24 | constructor() { 25 | this.temporary_channel_id = ""; 26 | this.funding_txid = ""; 27 | this.signed_miner_redeem_transaction_hex = ""; 28 | this.approval = false; 29 | } 30 | } 31 | class OmniFundingAssetInfo { 32 | constructor() { 33 | this.from_address = ""; 34 | this.to_address = ""; 35 | this.property_id = 0; 36 | this.amount = 0; 37 | this.miner_fee = 0.0; 38 | } 39 | } 40 | class OmniSendAssetInfo { 41 | constructor() { 42 | this.from_address = ""; 43 | this.to_address = ""; 44 | this.property_id = 0; 45 | this.amount = 0; 46 | } 47 | } 48 | class OpenChannelInfo { 49 | constructor() { 50 | this.funding_pubkey = ""; 51 | this.funder_address_index = 0; 52 | this.is_private = false; 53 | } 54 | } 55 | class AcceptChannelInfo { 56 | constructor() { 57 | this.temporary_channel_id = ""; 58 | this.funding_pubkey = ""; 59 | this.fundee_address_index = 0; 60 | this.approval = false; 61 | } 62 | } 63 | class AssetFundingCreatedInfo { 64 | constructor() { 65 | this.temporary_channel_id = ""; 66 | this.funding_tx_hex = ""; 67 | this.temp_address_pub_key = ""; 68 | this.temp_address_index = 0; 69 | // temp_address_private_key: string = ""; 70 | // channel_address_private_key: string = ""; 71 | } 72 | } 73 | class AssetFundingSignedInfo { 74 | constructor() { 75 | this.temporary_channel_id = ""; 76 | this.signed_alice_rsmc_hex = ""; 77 | } 78 | } 79 | class SignedInfo101035 { 80 | constructor() { 81 | this.temporary_channel_id = ""; 82 | this.rd_signed_hex = ""; 83 | this.br_signed_hex = ""; 84 | this.br_id = 0; 85 | } 86 | } 87 | class SignedInfo101134 { 88 | constructor() { 89 | this.channel_id = ""; 90 | this.rd_signed_hex = ""; 91 | } 92 | } 93 | class SignedInfo100360 { 94 | constructor() { 95 | this.channel_id = ""; 96 | this.rsmc_signed_hex = ""; 97 | this.counterparty_signed_hex = ""; 98 | } 99 | } 100 | class SignedInfo100361 { 101 | constructor() { 102 | this.channel_id = ""; 103 | this.c2b_rsmc_signed_hex = ""; 104 | this.c2b_counterparty_signed_hex = ""; 105 | this.c2a_rd_signed_hex = ""; 106 | this.c2a_br_signed_hex = ""; 107 | this.c2a_br_id = 0; 108 | } 109 | } 110 | class SignedInfo100362 { 111 | constructor() { 112 | this.channel_id = ""; 113 | this.c2b_rsmc_signed_hex = ""; 114 | this.c2b_counterparty_signed_hex = ""; 115 | this.c2a_rd_signed_hex = ""; 116 | } 117 | } 118 | class SignedInfo100363 { 119 | constructor() { 120 | this.channel_id = ""; 121 | this.c2b_rd_signed_hex = ""; 122 | this.c2b_br_signed_hex = ""; 123 | this.c2b_br_id = 0; 124 | } 125 | } 126 | class SignedInfo100364 { 127 | constructor() { 128 | this.channel_id = ""; 129 | this.c2b_rd_signed_hex = ""; 130 | } 131 | } 132 | class SignedInfo100100 { 133 | constructor() { 134 | this.channel_id = ""; 135 | this.c3a_counterparty_partial_signed_hex = ""; 136 | this.c3a_htlc_partial_signed_hex = ""; 137 | this.c3a_rsmc_partial_signed_hex = ""; 138 | } 139 | } 140 | class SignedInfo100101 { 141 | constructor() { 142 | this.channel_id = ""; 143 | this.c3a_rsmc_rd_partial_signed_hex = ""; 144 | this.c3a_rsmc_br_partial_signed_hex = ""; 145 | this.c3a_htlc_ht_partial_signed_hex = ""; 146 | this.c3a_htlc_hlock_partial_signed_hex = ""; 147 | this.c3a_htlc_br_partial_signed_hex = ""; 148 | this.c3b_rsmc_partial_signed_hex = ""; 149 | this.c3b_counterparty_partial_signed_hex = ""; 150 | this.c3b_htlc_partial_signed_hex = ""; 151 | } 152 | } 153 | class SignedInfo100102 { 154 | constructor() { 155 | this.channel_id = ""; 156 | this.c3a_rsmc_rd_complete_signed_hex = ""; 157 | this.c3a_htlc_ht_complete_signed_hex = ""; 158 | this.c3a_htlc_hlock_complete_signed_hex = ""; 159 | this.c3b_rsmc_complete_signed_hex = ""; 160 | this.c3b_counterparty_complete_signed_hex = ""; 161 | this.c3b_htlc_complete_signed_hex = ""; 162 | } 163 | } 164 | class SignedInfo100103 { 165 | constructor() { 166 | this.channel_id = ""; 167 | this.c3a_htlc_htrd_partial_signed_hex = ""; 168 | this.c3b_rsmc_rd_partial_signed_hex = ""; 169 | this.c3b_rsmc_br_partial_signed_hex = ""; 170 | this.c3b_htlc_htd_partial_signed_hex = ""; 171 | this.c3b_htlc_hlock_partial_signed_hex = ""; 172 | this.c3b_htlc_br_partial_signed_hex = ""; 173 | } 174 | } 175 | class SignedInfo100104 { 176 | constructor() { 177 | this.channel_id = ""; 178 | this.curr_htlc_temp_address_for_he_pub_key = ""; 179 | this.curr_htlc_temp_address_for_he_index = 0; 180 | this.c3a_htlc_htrd_complete_signed_hex = ""; 181 | this.c3a_htlc_htbr_partial_signed_hex = ""; 182 | this.c3a_htlc_hed_partial_signed_hex = ""; 183 | this.c3b_rsmc_rd_complete_signed_hex = ""; 184 | this.c3b_htlc_htd_complete_signed_hex = ""; 185 | this.c3b_htlc_hlock_complete_signed_hex = ""; 186 | } 187 | } 188 | class SignedInfo100105 { 189 | constructor() { 190 | this.channel_id = ""; 191 | this.c3b_htlc_hlock_he_partial_signed_hex = ""; 192 | } 193 | } 194 | class SignedInfo100106 { 195 | constructor() { 196 | this.channel_id = ""; 197 | this.c3b_htlc_herd_partial_signed_hex = ""; 198 | } 199 | } 200 | class SignedInfo100110 { 201 | constructor() { 202 | this.channel_id = ""; 203 | this.counterparty_partial_signed_hex = ""; 204 | this.rsmc_partial_signed_hex = ""; 205 | } 206 | } 207 | class SignedInfo100111 { 208 | constructor() { 209 | this.channel_id = ""; 210 | this.c4a_rd_signed_hex = ""; 211 | this.c4a_br_signed_hex = ""; 212 | this.c4a_br_id = ""; 213 | this.c4b_rsmc_signed_hex = ""; 214 | this.c4b_counterparty_signed_hex = ""; 215 | } 216 | } 217 | class SignedInfo100112 { 218 | constructor() { 219 | this.channel_id = ""; 220 | this.c4a_rd_complete_signed_hex = ""; 221 | this.c4b_rsmc_complete_signed_hex = ""; 222 | this.c4b_counterparty_complete_signed_hex = ""; 223 | } 224 | } 225 | class SignedInfo100113 { 226 | constructor() { 227 | this.channel_id = ""; 228 | this.c4b_rd_partial_signed_hex = ""; 229 | this.c4b_br_partial_signed_hex = ""; 230 | this.c4b_br_id = ""; 231 | } 232 | } 233 | class SignedInfo100114 { 234 | constructor() { 235 | this.channel_id = ""; 236 | this.c4b_rd_complete_signed_hex = ""; 237 | } 238 | } 239 | class CommitmentTx { 240 | constructor() { 241 | this.channel_id = ""; 242 | this.amount = 0; 243 | this.curr_temp_address_pub_key = ""; 244 | this.curr_temp_address_index = 0; 245 | this.last_temp_address_private_key = ""; 246 | } 247 | } 248 | class CommitmentTxSigned { 249 | constructor() { 250 | this.channel_id = ""; 251 | this.msg_hash = ""; 252 | this.c2a_rsmc_signed_hex = ""; 253 | this.c2a_counterparty_signed_hex = ""; 254 | this.curr_temp_address_pub_key = ""; 255 | this.curr_temp_address_index = 0; 256 | this.last_temp_address_private_key = ""; 257 | this.approval = false; 258 | } 259 | } 260 | class InvoiceInfo { 261 | constructor() { 262 | this.property_id = 0; 263 | this.amount = 0; 264 | this.h = ""; 265 | this.expiry_time = ""; 266 | this.description = ""; 267 | this.is_private = false; 268 | } 269 | } 270 | class HTLCFindPathInfo extends InvoiceInfo { 271 | constructor() { 272 | super(...arguments); 273 | this.invoice = ""; 274 | this.recipient_node_peer_id = ""; 275 | this.recipient_user_peer_id = ""; 276 | this.is_inv_pay = false; 277 | } 278 | } 279 | class addHTLCInfo { 280 | constructor() { 281 | this.is_pay_invoice = false; 282 | this.recipient_user_peer_id = ""; 283 | // property_id: number = 0; 284 | this.amount = 0; 285 | this.amount_to_payee = 0; 286 | this.memo = ""; 287 | this.h = ""; 288 | this.routing_packet = ""; 289 | this.cltv_expiry = 0; 290 | // channel_address_private_key: string = ""; 291 | this.last_temp_address_private_key = ""; 292 | this.curr_rsmc_temp_address_pub_key = ""; 293 | // curr_rsmc_temp_address_private_key: string = ""; 294 | this.curr_rsmc_temp_address_index = 0; 295 | this.curr_htlc_temp_address_pub_key = ""; 296 | // curr_htlc_temp_address_private_key: string = ""; 297 | this.curr_htlc_temp_address_index = 0; 298 | this.curr_htlc_temp_address_for_ht1a_pub_key = ""; 299 | // curr_htlc_temp_address_for_ht1a_private_key: string = ""; 300 | this.curr_htlc_temp_address_for_ht1a_index = 0; 301 | } 302 | } 303 | class HtlcSignedInfo { 304 | constructor() { 305 | this.payer_commitment_tx_hash = ""; 306 | this.curr_rsmc_temp_address_pub_key = ""; 307 | this.curr_rsmc_temp_address_index = 0; 308 | this.curr_htlc_temp_address_pub_key = ""; 309 | this.curr_htlc_temp_address_index = 0; 310 | this.last_temp_address_private_key = ""; 311 | this.c3a_complete_signed_rsmc_hex = ""; 312 | this.c3a_complete_signed_counterparty_hex = ""; 313 | this.c3a_complete_signed_htlc_hex = ""; 314 | // channel_address_private_key: string = ""; 315 | // curr_rsmc_temp_address_private_key: string = ""; 316 | // curr_htlc_temp_address_private_key: string = ""; 317 | // approval: boolean = false; 318 | } 319 | } 320 | class SignGetHInfo { 321 | constructor() { 322 | this.request_hash = ""; 323 | this.channel_address_private_key = ""; 324 | this.last_temp_address_private_key = ""; 325 | this.curr_rsmc_temp_address_pub_key = ""; 326 | this.curr_rsmc_temp_address_private_key = ""; 327 | this.curr_htlc_temp_address_pub_key = ""; 328 | this.curr_htlc_temp_address_private_key = ""; 329 | this.approval = false; 330 | } 331 | } 332 | class HtlcRequestOpen { 333 | constructor() { 334 | this.request_hash = ""; 335 | this.channel_address_private_key = ""; 336 | this.last_temp_address_private_key = ""; 337 | this.curr_rsmc_temp_address_pub_key = ""; 338 | this.curr_rsmc_temp_address_private_key = ""; 339 | this.curr_htlc_temp_address_pub_key = ""; 340 | this.curr_htlc_temp_address_private_key = ""; 341 | this.curr_htlc_temp_address_for_ht1a_pub_key = ""; 342 | this.curr_htlc_temp_address_for_ht1a_private_key = ""; 343 | } 344 | } 345 | class ForwardRInfo { 346 | constructor() { 347 | this.channel_id = ""; 348 | this.r = ""; 349 | } 350 | } 351 | class SignRInfo { 352 | constructor() { 353 | this.channel_id = ""; 354 | this.c3b_htlc_herd_complete_signed_hex = ""; 355 | this.c3b_htlc_hebr_partial_signed_hex = ""; 356 | // msg_hash: string = ""; 357 | // r: string = ""; 358 | // channel_address_private_key: string = ""; 359 | } 360 | } 361 | class CloseHtlcTxInfo { 362 | constructor() { 363 | this.channel_id = ""; 364 | this.last_rsmc_temp_address_private_key = ""; 365 | this.last_htlc_temp_address_private_key = ""; 366 | this.last_htlc_temp_address_for_htnx_private_key = ""; 367 | this.curr_temp_address_pub_key = ""; 368 | this.curr_temp_address_index = 0; 369 | } 370 | } 371 | class CloseHtlcTxInfoSigned { 372 | constructor() { 373 | this.msg_hash = ""; 374 | this.last_rsmc_temp_address_private_key = ""; 375 | this.last_htlc_temp_address_private_key = ""; 376 | this.last_htlc_temp_address_for_htnx_private_key = ""; 377 | this.curr_temp_address_pub_key = ""; 378 | this.curr_temp_address_index = 0; 379 | } 380 | } 381 | class IssueManagedAmoutInfo { 382 | constructor() { 383 | this.from_address = ""; 384 | this.name = ""; 385 | this.ecosystem = 0; 386 | this.divisible_type = 0; 387 | this.data = ""; 388 | } 389 | } 390 | class IssueFixedAmountInfo extends IssueManagedAmoutInfo { 391 | constructor() { 392 | super(...arguments); 393 | this.amount = 0; 394 | } 395 | } 396 | class OmniSendGrant { 397 | constructor() { 398 | this.from_address = ""; 399 | this.property_id = 0; 400 | this.amount = 0; 401 | this.memo = ""; 402 | } 403 | } 404 | class OmniSendRevoke extends OmniSendGrant { 405 | } 406 | class CloseChannelSign { 407 | constructor() { 408 | this.channel_id = ""; 409 | this.request_close_channel_hash = ""; 410 | this.approval = false; 411 | } 412 | } 413 | /** 414 | * -80 415 | */ 416 | class AtomicSwapRequest { 417 | constructor() { 418 | this.channel_id_from = ""; 419 | this.channel_id_to = ""; 420 | this.recipient_user_peer_id = ""; 421 | this.property_sent = 0; 422 | this.amount = 0; 423 | this.exchange_rate = 0; 424 | this.property_received = 0; 425 | this.transaction_id = ""; 426 | this.time_locker = 0; 427 | } 428 | } 429 | /** 430 | * -81 431 | */ 432 | class AtomicSwapAccepted extends AtomicSwapRequest { 433 | constructor() { 434 | super(...arguments); 435 | this.target_transaction_id = ""; 436 | } 437 | } 438 | /** 439 | * MsgType_p2p_ConnectPeer_2003 440 | */ 441 | class P2PPeer { 442 | constructor() { 443 | this.remote_node_address = ""; 444 | } 445 | } 446 | class MessageType { 447 | constructor() { 448 | this.MsgType_Error_0 = 0; 449 | // type id of functions in JS SDK 450 | this.MsgType_JS_SDK_100 = 100; 451 | this.MsgType_JS_SDK_101 = 101; 452 | this.MsgType_JS_SDK_102 = 102; 453 | this.MsgType_UserLogin_2001 = -102001; 454 | this.MsgType_UserLogout_2002 = -102002; 455 | this.MsgType_p2p_ConnectPeer_2003 = -102003; 456 | this.MsgType_GetMnemonic_2004 = -102004; 457 | this.MsgType_GetMiniBtcFundAmount_2006 = -102006; 458 | this.MsgType_Core_GetNewAddress_2101 = -102101; 459 | this.MsgType_Core_GetMiningInfo_2102 = -102102; 460 | this.MsgType_Core_GetNetworkInfo_2103 = -102103; 461 | this.MsgType_Core_SignMessageWithPrivKey_2104 = -102104; 462 | this.MsgType_Core_VerifyMessage_2105 = -102105; 463 | this.MsgType_Core_DumpPrivKey_2106 = -102106; 464 | this.MsgType_Core_ListUnspent_2107 = -102107; 465 | this.MsgType_Core_BalanceByAddress_2108 = -102108; 466 | this.MsgType_Core_FundingBTC_2109 = -102109; 467 | this.MsgType_Core_BtcCreateMultiSig_2110 = -102110; 468 | this.MsgType_Core_Btc_ImportPrivKey_2111 = -102111; 469 | this.MsgType_Core_Omni_Getbalance_2112 = -102112; 470 | this.MsgType_Core_Omni_CreateNewTokenFixed_2113 = -102113; 471 | this.MsgType_Core_Omni_CreateNewTokenManaged_2114 = -102114; 472 | this.MsgType_Core_Omni_GrantNewUnitsOfManagedToken_2115 = -102115; 473 | this.MsgType_Core_Omni_RevokeUnitsOfManagedToken_2116 = -102116; 474 | this.MsgType_Core_Omni_ListProperties_2117 = -102117; 475 | this.MsgType_Core_Omni_GetTransaction_2118 = -102118; 476 | this.MsgType_Core_Omni_GetProperty_2119 = -102119; 477 | this.MsgType_Core_Omni_FundingAsset_2120 = -102120; 478 | this.MsgType_Core_Omni_Send_2121 = -102121; 479 | this.MsgType_Mnemonic_CreateAddress_3000 = -103000; 480 | this.MsgType_Mnemonic_GetAddressByIndex_3001 = -103001; 481 | this.MsgType_FundingCreate_Asset_AllItem_3100 = -103100; 482 | this.MsgType_FundingCreate_Asset_ItemById_3101 = -103101; 483 | this.MsgType_FundingCreate_Asset_ItemByChannelId_3102 = -103102; 484 | this.MsgType_FundingCreate_Asset_Count_3103 = -103103; 485 | this.MsgType_SendChannelOpen_32 = -100032; 486 | this.MsgType_RecvChannelOpen_32 = -110032; 487 | this.MsgType_SendChannelAccept_33 = -100033; 488 | this.MsgType_RecvChannelAccept_33 = -110033; 489 | this.MsgType_FundingCreate_SendAssetFundingCreated_34 = -100034; 490 | this.MsgType_FundingCreate_RecvAssetFundingCreated_34 = -110034; 491 | this.MsgType_FundingSign_SendAssetFundingSigned_35 = -100035; 492 | this.MsgType_FundingSign_RecvAssetFundingSigned_35 = -110035; 493 | this.MsgType_ClientSign_AssetFunding_AliceSignC1a_1034 = -101034; 494 | this.MsgType_ClientSign_AssetFunding_AliceSignRD_1134 = -101134; 495 | this.MsgType_ClientSign_Duplex_AssetFunding_RdAndBr_1035 = -101035; 496 | this.MsgType_FundingCreate_SendBtcFundingCreated_340 = -100340; 497 | this.MsgType_FundingCreate_BtcFundingMinerRDTxToClient_341 = -100341; 498 | this.MsgType_FundingCreate_RecvBtcFundingCreated_340 = -110340; 499 | this.MsgType_FundingSign_SendBtcSign_350 = -100350; 500 | this.MsgType_FundingSign_RecvBtcSign_350 = -110350; 501 | this.MsgType_CommitmentTx_SendCommitmentTransactionCreated_351 = -100351; 502 | this.MsgType_CommitmentTx_RecvCommitmentTransactionCreated_351 = -110351; 503 | this.MsgType_CommitmentTxSigned_SendRevokeAndAcknowledgeCommitmentTransaction_352 = -100352; 504 | this.MsgType_CommitmentTxSigned_RecvRevokeAndAcknowledgeCommitmentTransaction_352 = -110352; 505 | this.MsgType_ClientSign_BobC2b_Rd_353 = -110353; 506 | this.MsgType_ClientSign_CommitmentTx_AliceSignC2a_360 = -100360; 507 | this.MsgType_ClientSign_CommitmentTx_BobSignC2b_361 = -100361; 508 | this.MsgType_ClientSign_CommitmentTx_AliceSignC2b_362 = -100362; 509 | this.MsgType_ClientSign_CommitmentTx_AliceSignC2b_Rd_363 = -100363; 510 | this.MsgType_ClientSign_CommitmentTx_BobSignC2b_Rd_364 = -100364; 511 | this.MsgType_ChannelOpen_AllItem_3150 = -103150; 512 | this.MsgType_ChannelOpen_ItemByTempId_3151 = -103151; 513 | this.MsgType_ChannelOpen_Count_3152 = -103152; 514 | this.MsgType_ChannelOpen_DelItemByTempId_3153 = -103153; 515 | this.MsgType_GetChannelInfoByChannelId_3154 = -103154; 516 | this.MsgType_GetChannelInfoByDbId_3155 = -103155; 517 | this.MsgType_CheckChannelAddessExist_3156 = -103156; 518 | this.MsgType_CommitmentTx_ItemsByChanId_3200 = -103200; 519 | this.MsgType_CommitmentTx_ItemById_3201 = -103201; 520 | this.MsgType_CommitmentTx_Count_3202 = -103202; 521 | this.MsgType_CommitmentTx_LatestCommitmentTxByChanId_3203 = -103203; 522 | this.MsgType_CommitmentTx_LatestRDByChanId_3204 = -103204; 523 | this.MsgType_CommitmentTx_LatestBRByChanId_3205 = -103205; 524 | this.MsgType_CommitmentTx_SendSomeCommitmentById_3206 = -103206; 525 | this.MsgType_CommitmentTx_AllRDByChanId_3207 = -103207; 526 | this.MsgType_CommitmentTx_AllBRByChanId_3208 = -103208; 527 | this.MsgType_SendCloseChannelRequest_38 = -100038; 528 | this.MsgType_RecvCloseChannelRequest_38 = -110038; 529 | this.MsgType_SendCloseChannelSign_39 = -100039; 530 | this.MsgType_RecvCloseChannelSign_39 = -110039; 531 | this.MsgType_HTLC_FindPath_401 = -100401; 532 | this.MsgType_HTLC_Invoice_402 = -100402; 533 | this.MsgType_HTLC_SendAddHTLC_40 = -100040; 534 | this.MsgType_HTLC_RecvAddHTLC_40 = -110040; 535 | this.MsgType_HTLC_SendAddHTLCSigned_41 = -100041; 536 | this.MsgType_HTLC_RecvAddHTLCSigned_41 = -110041; 537 | this.MsgType_HTLC_BobSignC3bSubTx_42 = -110042; 538 | this.MsgType_HTLC_FinishTransferH_43 = -110043; 539 | this.MsgType_HTLC_SendVerifyR_45 = -100045; 540 | this.MsgType_HTLC_RecvVerifyR_45 = -110045; 541 | this.MsgType_HTLC_SendSignVerifyR_46 = -100046; 542 | this.MsgType_HTLC_RecvSignVerifyR_46 = -110046; 543 | this.MsgType_HTLC_SendRequestCloseCurrTx_49 = -100049; 544 | this.MsgType_HTLC_RecvRequestCloseCurrTx_49 = -110049; 545 | this.MsgType_HTLC_SendCloseSigned_50 = -100050; 546 | this.MsgType_HTLC_RecvCloseSigned_50 = -110050; 547 | this.MsgType_HTLC_Close_ClientSign_Bob_C4bSub_51 = -110051; 548 | this.MsgType_HTLC_ClientSign_Alice_C3a_100 = -100100; 549 | this.MsgType_HTLC_ClientSign_Bob_C3b_101 = -100101; 550 | this.MsgType_HTLC_ClientSign_Alice_C3b_102 = -100102; 551 | this.MsgType_HTLC_ClientSign_Alice_C3bSub_103 = -100103; 552 | this.MsgType_HTLC_ClientSign_Bob_C3bSub_104 = -100104; 553 | this.MsgType_HTLC_ClientSign_Alice_He_105 = -100105; 554 | this.MsgType_HTLC_ClientSign_Bob_HeSub_106 = -100106; 555 | this.MsgType_HTLC_ClientSign_Alice_HeSub_107 = -100107; 556 | this.MsgType_HTLC_Close_ClientSign_Alice_C4a_110 = -100110; 557 | this.MsgType_HTLC_Close_ClientSign_Bob_C4b_111 = -100111; 558 | this.MsgType_HTLC_Close_ClientSign_Alice_C4b_112 = -100112; 559 | this.MsgType_HTLC_Close_ClientSign_Alice_C4bSub_113 = -100113; 560 | this.MsgType_HTLC_Close_ClientSign_Bob_C4bSubResult_114 = -100114; 561 | this.MsgType_Atomic_SendSwap_80 = -100080; 562 | this.MsgType_Atomic_RecvSwap_80 = -110080; 563 | this.MsgType_Atomic_SendSwapAccept_81 = -100081; 564 | this.MsgType_Atomic_RecvSwapAccept_81 = -110081; 565 | } 566 | } 567 | -------------------------------------------------------------------------------- /sdk/query.js: -------------------------------------------------------------------------------- 1 | // query.js 2 | // Query functions 3 | 4 | /** 5 | * Type -102006 Protocol is used to get the amount of btc 6 | * that needs to be recharged in the channel 7 | * 8 | * @param callback 9 | */ 10 | function getAmountOfRechargeBTC(callback) { 11 | obdApi.getAmountOfRechargeBTC(callback); 12 | } 13 | 14 | /** 15 | * Type -103150 Protocol is used to get get all of channels. 16 | */ 17 | function getMyChannels() { 18 | obdApi.getMyChannels(function(e) { 19 | console.info('SDK: -103150 getMyChannels = ' + JSON.stringify(e)); 20 | }); 21 | } 22 | 23 | /** 24 | * Type -103154 Protocol is used to get detail data of a channel from a channel ID. 25 | * @param channel_id 26 | */ 27 | function getChannelDetailFromChannelID(channel_id) { 28 | obdApi.getChannelDetailFromChannelID(channel_id, function(e) { 29 | console.info('SDK: -103154 getChannelDetailFromChannelID = ' + JSON.stringify(e)); 30 | }); 31 | } 32 | 33 | /** 34 | * Type -103155 Protocol is used to get detail data of a channel from a database ID. 35 | * @param id number 36 | */ 37 | function getChannelDetailFromDatabaseID(id) { 38 | obdApi.getChannelDetailFromDatabaseID(Number(id), function(e) { 39 | console.info('SDK: -103155 getChannelDetailFromDatabaseID = ' + JSON.stringify(e)); 40 | }); 41 | } 42 | 43 | /** 44 | * Type -103200 Protocol is used to get a list of commitment transactions in one channel. 45 | * @param channel_id 46 | */ 47 | function getAllCommitmentTransactions(channel_id) { 48 | obdApi.getItemsByChannelId(channel_id, function(e) { 49 | console.info('SDK: -103200 GetAllCommitmentTransactions = ' + JSON.stringify(e)); 50 | }); 51 | } 52 | 53 | /** 54 | * Type -103203 Protocol is used to get a latest commitment transaction. 55 | * @param channel_id 56 | */ 57 | function getLatestCommitmentTransaction(channel_id) { 58 | obdApi.getLatestCommitmentTransaction(channel_id, function(e) { 59 | console.info('SDK: -103203 getLatestCommitmentTransaction = ' + JSON.stringify(e)); 60 | }); 61 | } 62 | 63 | /** 64 | * Type -103204 Protocol is used to get a latest Revockable Delivery transaction. 65 | * @param channel_id 66 | */ 67 | function getLatestRevockableDeliveryTransaction(channel_id) { 68 | obdApi.getLatestRevockableDeliveryTransaction(channel_id, function(e) { 69 | console.info('SDK: -103204 getLatestRevockableDeliveryTransaction = ' + JSON.stringify(e)); 70 | }); 71 | } 72 | 73 | /** 74 | * Type -103205 Protocol is used to get a latest Breach Remedy transaction. 75 | * @param channel_id 76 | */ 77 | function getLatestBreachRemedyTransaction(channel_id) { 78 | obdApi.getLatestBreachRemedyTransaction(channel_id, function(e) { 79 | console.info('SDK: -103205 getLatestBreachRemedyTransaction = ' + JSON.stringify(e)); 80 | }); 81 | } 82 | 83 | /** 84 | * Type -103207 Protocol is used to get all of Revockable Delivery transactions. 85 | * @param channel_id 86 | */ 87 | function getAllRevockableDeliveryTransactions(channel_id) { 88 | obdApi.getAllRevockableDeliveryTransactions(channel_id, function(e) { 89 | console.info('SDK: -103207 getAllRevockableDeliveryTransactions = ' + JSON.stringify(e)); 90 | }); 91 | } 92 | 93 | /** 94 | * Type -103208 Protocol is used to get all of Breach Remedy transactions. 95 | * @param channel_id 96 | */ 97 | function getAllBreachRemedyTransactions(channel_id) { 98 | obdApi.getAllBreachRemedyTransactions(channel_id, function(e) { 99 | console.info('SDK: -103208 getAllBreachRemedyTransactions = ' + JSON.stringify(e)); 100 | }); 101 | } 102 | 103 | /** 104 | * getAddressInfo is used to get detail info of a address generated by mnemonic words. 105 | * @param mnemonic 106 | * @param index 107 | * @param netType true: testnet false: mainnet 108 | */ 109 | function getAddressInfo(mnemonic, index, netType) { 110 | let result; 111 | try { 112 | // True: testnet False: mainnet 113 | result = btctool.generateWalletInfo(mnemonic, index, netType); 114 | console.info('SDK: getAddressInfo = ' + JSON.stringify(result)); 115 | } catch (error) { 116 | // alert('Please input a valid index of address.'); 117 | return ''; 118 | } 119 | 120 | if (!result.status) { // status = false 121 | // alert('Please input a valid index of address.'); 122 | return ''; 123 | } 124 | 125 | return result; 126 | } 127 | 128 | /** 129 | * Type -102112 Protocol is used to get all omni assets details of an address. 130 | * @param address 131 | */ 132 | function getAllBalancesForAddress(address) { 133 | obdApi.getAllBalancesForAddress(address, function(e) { 134 | console.info('SDK: -102112 getAllBalancesForAddress = ' + JSON.stringify(e)); 135 | }); 136 | } 137 | 138 | /** 139 | * Type -102117 Protocol is used to list all tokens or smart properties. 140 | * This call may take a long time, it may return a large amount of data, 141 | * please use it with caution. 142 | */ 143 | function listProperties() { 144 | obdApi.listProperties(function(e) { 145 | console.info('SDK: -102117 listProperties = ' + JSON.stringify(e)); 146 | }); 147 | } 148 | 149 | /** 150 | * Type -102118 Protocol is used to get detailed information about an Omni transaction. 151 | * @param txid 152 | */ 153 | function getTransaction(txid) { 154 | obdApi.getTransaction(txid, function(e) { 155 | console.info('SDK: -102118 getTransaction = ' + JSON.stringify(e)); 156 | }); 157 | } 158 | 159 | /** 160 | * Type -102119 Protocol is used to get omni asset details by asset id (Property Id) . 161 | * @param propertyId 162 | */ 163 | function getProperty(propertyId) { 164 | obdApi.getProperty(propertyId, function(e) { 165 | console.info('SDK: -102119 getProperty = ' + JSON.stringify(e)); 166 | }); 167 | } 168 | -------------------------------------------------------------------------------- /sdk/wallet.js: -------------------------------------------------------------------------------- 1 | var obdApi = new ObdApi(); 2 | 3 | /** 4 | * Connect to a OBD 5 | * @param nodeAddress 6 | * @param callback 7 | * @param globalCallback 8 | */ 9 | function connectToServer(nodeAddress, callback, globalCallback) { 10 | obdApi.connectToServer(nodeAddress, callback, globalCallback); 11 | } 12 | 13 | /** 14 | * connect to a remote counterparty's OBD server. 15 | * @param info remote_node_address 16 | * @param callback 17 | */ 18 | function connectPeer(info, callback) { 19 | obdApi.connectPeer(info, callback); 20 | } 21 | 22 | /** 23 | * Mode 1 local OBD: 24 | * 25 | * Type -102004 Protocol is used to sign up a new user by 26 | * hirarchecal deterministic wallet system integrated in 27 | * the local client. Client generates mnemonic words and 28 | * the hash of the mnemonic words as the UserID. 29 | */ 30 | function genMnemonic() { 31 | let mnemonic = btctool.generateMnemonic(128); 32 | // console.info('SDK: - genMnemonic = ' + mnemonic); 33 | return mnemonic; 34 | } 35 | 36 | /** 37 | * Type -103000 Protocol generates a new address from mnemonic words. 38 | * This message requires to generate address on local device from 39 | * mnemonic words using BIP32. Clients interacting with obd, e.g wallets, 40 | * shall implement this HD mechanism for security guarantees. Mnemonic words 41 | * shall be kept in a safe place, and never be shared with any obd instances. 42 | * 43 | * @param mnemonic 44 | * @param index 45 | * @param netType true: testnet false: mainnet 46 | */ 47 | function genAddressFromMnemonic(mnemonic, index, netType) { 48 | let result = btctool.generateWalletInfo(mnemonic, index, netType); 49 | // console.info('SDK: - genAddressFromMnemonic = ' + JSON.stringify(result)); 50 | return result; 51 | } 52 | 53 | /** 54 | * Type -102001 Protocol is used to login to OBD. 55 | * @param mnemonic 56 | * @param callback 57 | */ 58 | function logIn(mnemonic) { 59 | return new Promise((resolve, reject) => { 60 | obdApi.logIn(mnemonic, function(e) { 61 | // console.info('SDK: -102001 logIn = ' + JSON.stringify(e)); 62 | saveMnemonic(e.userPeerId, mnemonic); 63 | saveHtlcFeeRate(e.htlcFeeRate); 64 | saveHtlcMaxFee(e.htlcMaxFee); 65 | saveRoutingPacket(''); 66 | resolve(e); 67 | }); 68 | }) 69 | } 70 | -------------------------------------------------------------------------------- /ts/go.bat: -------------------------------------------------------------------------------- 1 | tsc -w -------------------------------------------------------------------------------- /ts/number_precision.ts: -------------------------------------------------------------------------------- 1 | type numType = number | string; 2 | /** 3 | * @desc Solve the problem of floating point arithmetic, 4 | * avoid multiple digits after the decimal point and 5 | * loss of calculation accuracy. 6 | * Examples:2.3 + 2.4 = 4.699999999999999,1.0 - 0.9 = 0.09999999999999998 7 | */ 8 | 9 | /** 10 | * Convert wrong data into correct 11 | * strip(0.09999999999999998)=0.1 12 | */ 13 | function strip(num: numType, precision = 15): number { 14 | return +parseFloat(Number(num).toPrecision(precision)); 15 | } 16 | 17 | /** 18 | * Return digits length of a number 19 | * @param {*number} num Input number 20 | */ 21 | function digitLength(num: numType): number { 22 | // Get digit length of e 23 | const eSplit = num.toString().split(/[eE]/); 24 | const len = (eSplit[0].split('.')[1] || '').length - +(eSplit[1] || 0); 25 | return len > 0 ? len : 0; 26 | } 27 | 28 | /** 29 | * Convert decimals to integers and support scientific notation. 30 | * If it is a decimal, it is enlarged to an integer 31 | * @param {*number} num Input number 32 | */ 33 | function float2Fixed(num: numType): number { 34 | if (num.toString().indexOf('e') === -1) { 35 | return Number(num.toString().replace('.', '')); 36 | } 37 | const dLen = digitLength(num); 38 | return dLen > 0 ? strip(Number(num) * Math.pow(10, dLen)) : Number(num); 39 | } 40 | 41 | /** 42 | * Check whether the number is out of range, and give a prompt if it is out of range 43 | * @param {*number} num Input number 44 | */ 45 | function checkBoundary(num: number) { 46 | if (_boundaryCheckingState) { 47 | if (num > Number.MAX_SAFE_INTEGER || num < Number.MIN_SAFE_INTEGER) { 48 | console.warn(`${num} is beyond boundary when transfer to integer, the results may not be accurate`); 49 | } 50 | } 51 | } 52 | 53 | /** 54 | * Exact multiplication 55 | */ 56 | function times(num1: numType, num2: numType, ...others: numType[]): number { 57 | if (others.length > 0) { 58 | return times(times(num1, num2), others[0], ...others.slice(1)); 59 | } 60 | const num1Changed = float2Fixed(num1); 61 | const num2Changed = float2Fixed(num2); 62 | const baseNum = digitLength(num1) + digitLength(num2); 63 | const leftValue = num1Changed * num2Changed; 64 | 65 | checkBoundary(leftValue); 66 | 67 | return leftValue / Math.pow(10, baseNum); 68 | } 69 | 70 | /** 71 | * Exact addition 72 | */ 73 | function plus(num1: numType, num2: numType, ...others: numType[]): number { 74 | if (others.length > 0) { 75 | return plus(plus(num1, num2), others[0], ...others.slice(1)); 76 | } 77 | const baseNum = Math.pow(10, Math.max(digitLength(num1), digitLength(num2))); 78 | return (times(num1, baseNum) + times(num2, baseNum)) / baseNum; 79 | } 80 | 81 | /** 82 | * Exact subtraction 83 | */ 84 | function minus(num1: numType, num2: numType, ...others: numType[]): number { 85 | if (others.length > 0) { 86 | return minus(minus(num1, num2), others[0], ...others.slice(1)); 87 | } 88 | const baseNum = Math.pow(10, Math.max(digitLength(num1), digitLength(num2))); 89 | return (times(num1, baseNum) - times(num2, baseNum)) / baseNum; 90 | } 91 | 92 | /** 93 | * Exact division 94 | */ 95 | function divide(num1: numType, num2: numType, ...others: numType[]): number { 96 | if (others.length > 0) { 97 | return divide(divide(num1, num2), others[0], ...others.slice(1)); 98 | } 99 | const num1Changed = float2Fixed(num1); 100 | const num2Changed = float2Fixed(num2); 101 | checkBoundary(num1Changed); 102 | checkBoundary(num2Changed); 103 | // fix: like 10 ** -4 为 0.00009999999999999999,strip fix it. 104 | return times(num1Changed / num2Changed, strip(Math.pow(10, digitLength(num2) - digitLength(num1)))); 105 | } 106 | 107 | /** 108 | * rounding 109 | */ 110 | function round(num: numType, ratio: number): number { 111 | const base = Math.pow(10, ratio); 112 | return divide(Math.round(times(num, base)), base); 113 | } 114 | 115 | let _boundaryCheckingState = true; 116 | /** 117 | * Whether to perform boundary check, enabled by default 118 | * @param flag true is on, false is off, default is true 119 | */ 120 | function enableBoundaryChecking(flag = true) { 121 | _boundaryCheckingState = flag; 122 | } -------------------------------------------------------------------------------- /ts/pojo.ts: -------------------------------------------------------------------------------- 1 | class Message { 2 | type: number; 3 | data: Object = new Object(); 4 | recipient_user_peer_id: string = ""; 5 | recipient_node_peer_id: string = ""; 6 | } 7 | 8 | class BtcFundingInfo { 9 | from_address: string = ""; 10 | from_address_private_key: string = ""; 11 | to_address: string = ""; 12 | amount: number = 0.0; 13 | miner_fee: number = 0.0; 14 | } 15 | 16 | class FundingBtcCreated { 17 | temporary_channel_id: string = ""; 18 | funding_tx_hex: string = ""; 19 | } 20 | class FundingBtcSigned { 21 | temporary_channel_id: string = ""; 22 | funding_txid: string = ""; 23 | signed_miner_redeem_transaction_hex: string = ""; 24 | approval: boolean = false; 25 | } 26 | 27 | class OmniFundingAssetInfo { 28 | from_address: string = ""; 29 | to_address: string = ""; 30 | property_id: number = 0; 31 | amount: number = 0; 32 | miner_fee: number = 0.0; 33 | } 34 | 35 | class OmniSendAssetInfo { 36 | from_address: string = ""; 37 | to_address: string = ""; 38 | property_id: number = 0; 39 | amount: number = 0; 40 | } 41 | 42 | class OpenChannelInfo { 43 | funding_pubkey: string = ""; 44 | funder_address_index: number = 0; 45 | is_private: boolean = false; 46 | } 47 | 48 | class AcceptChannelInfo { 49 | temporary_channel_id: string = ""; 50 | funding_pubkey: string = ""; 51 | fundee_address_index: number = 0; 52 | approval: boolean = false; 53 | } 54 | 55 | class AssetFundingCreatedInfo { 56 | temporary_channel_id: string = ""; 57 | funding_tx_hex: string = ""; 58 | temp_address_pub_key: string = ""; 59 | temp_address_index: number = 0; 60 | // temp_address_private_key: string = ""; 61 | // channel_address_private_key: string = ""; 62 | } 63 | 64 | class AssetFundingSignedInfo { 65 | temporary_channel_id: string = ""; 66 | signed_alice_rsmc_hex: string = ""; 67 | } 68 | 69 | class SignedInfo101035 { 70 | temporary_channel_id: string = ""; 71 | rd_signed_hex: string = ""; 72 | br_signed_hex: string = ""; 73 | br_id: number = 0; 74 | } 75 | 76 | class SignedInfo101134 { 77 | channel_id: string = ""; 78 | rd_signed_hex: string = ""; 79 | } 80 | 81 | class SignedInfo100360 { 82 | channel_id: string = ""; 83 | rsmc_signed_hex: string = ""; 84 | counterparty_signed_hex: string = ""; 85 | } 86 | 87 | class SignedInfo100361 { 88 | channel_id: string = ""; 89 | c2b_rsmc_signed_hex: string = ""; 90 | c2b_counterparty_signed_hex: string = ""; 91 | c2a_rd_signed_hex: string = ""; 92 | c2a_br_signed_hex: string = ""; 93 | c2a_br_id: number = 0; 94 | } 95 | 96 | class SignedInfo100362 { 97 | channel_id: string = ""; 98 | c2b_rsmc_signed_hex: string = ""; 99 | c2b_counterparty_signed_hex: string = ""; 100 | c2a_rd_signed_hex: string = ""; 101 | } 102 | 103 | class SignedInfo100363 { 104 | channel_id: string = ""; 105 | c2b_rd_signed_hex: string = ""; 106 | c2b_br_signed_hex: string = ""; 107 | c2b_br_id: number = 0; 108 | } 109 | 110 | class SignedInfo100364 { 111 | channel_id: string = ""; 112 | c2b_rd_signed_hex: string = ""; 113 | } 114 | 115 | class SignedInfo100100 { 116 | channel_id: string = ""; 117 | c3a_counterparty_partial_signed_hex: string = ""; 118 | c3a_htlc_partial_signed_hex: string = ""; 119 | c3a_rsmc_partial_signed_hex: string = ""; 120 | } 121 | 122 | class SignedInfo100101 { 123 | channel_id: string = ""; 124 | c3a_rsmc_rd_partial_signed_hex: string = ""; 125 | c3a_rsmc_br_partial_signed_hex: string = ""; 126 | c3a_htlc_ht_partial_signed_hex: string = ""; 127 | c3a_htlc_hlock_partial_signed_hex: string = ""; 128 | c3a_htlc_br_partial_signed_hex: string = ""; 129 | c3b_rsmc_partial_signed_hex: string = ""; 130 | c3b_counterparty_partial_signed_hex: string = ""; 131 | c3b_htlc_partial_signed_hex: string = ""; 132 | } 133 | 134 | class SignedInfo100102 { 135 | channel_id: string = ""; 136 | c3a_rsmc_rd_complete_signed_hex: string = ""; 137 | c3a_htlc_ht_complete_signed_hex: string = ""; 138 | c3a_htlc_hlock_complete_signed_hex: string = ""; 139 | c3b_rsmc_complete_signed_hex: string = ""; 140 | c3b_counterparty_complete_signed_hex: string = ""; 141 | c3b_htlc_complete_signed_hex: string = ""; 142 | } 143 | 144 | class SignedInfo100103 { 145 | channel_id: string = ""; 146 | c3a_htlc_htrd_partial_signed_hex: string = ""; 147 | c3b_rsmc_rd_partial_signed_hex: string = ""; 148 | c3b_rsmc_br_partial_signed_hex: string = ""; 149 | c3b_htlc_htd_partial_signed_hex: string = ""; 150 | c3b_htlc_hlock_partial_signed_hex: string = ""; 151 | c3b_htlc_br_partial_signed_hex: string = ""; 152 | } 153 | 154 | class SignedInfo100104 { 155 | channel_id: string = ""; 156 | curr_htlc_temp_address_for_he_pub_key: string = ""; 157 | curr_htlc_temp_address_for_he_index: number = 0; 158 | c3a_htlc_htrd_complete_signed_hex: string = ""; 159 | c3a_htlc_htbr_partial_signed_hex: string = ""; 160 | c3a_htlc_hed_partial_signed_hex: string = ""; 161 | c3b_rsmc_rd_complete_signed_hex: string = ""; 162 | c3b_htlc_htd_complete_signed_hex: string = ""; 163 | c3b_htlc_hlock_complete_signed_hex: string = ""; 164 | } 165 | 166 | class SignedInfo100105 { 167 | channel_id: string = ""; 168 | c3b_htlc_hlock_he_partial_signed_hex: string = ""; 169 | } 170 | 171 | class SignedInfo100106 { 172 | channel_id: string = ""; 173 | c3b_htlc_herd_partial_signed_hex: string = ""; 174 | } 175 | 176 | class SignedInfo100110 { 177 | channel_id: string = ""; 178 | counterparty_partial_signed_hex: string = ""; 179 | rsmc_partial_signed_hex: string = ""; 180 | } 181 | 182 | class SignedInfo100111 { 183 | channel_id: string = ""; 184 | c4a_rd_signed_hex: string = ""; 185 | c4a_br_signed_hex: string = ""; 186 | c4a_br_id: string = ""; 187 | c4b_rsmc_signed_hex: string = ""; 188 | c4b_counterparty_signed_hex: string = ""; 189 | } 190 | 191 | class SignedInfo100112 { 192 | channel_id: string = ""; 193 | c4a_rd_complete_signed_hex: string = ""; 194 | c4b_rsmc_complete_signed_hex: string = ""; 195 | c4b_counterparty_complete_signed_hex: string = ""; 196 | } 197 | 198 | class SignedInfo100113 { 199 | channel_id: string = ""; 200 | c4b_rd_partial_signed_hex: string = ""; 201 | c4b_br_partial_signed_hex: string = ""; 202 | c4b_br_id: string = ""; 203 | } 204 | 205 | class SignedInfo100114 { 206 | channel_id: string = ""; 207 | c4b_rd_complete_signed_hex: string = ""; 208 | } 209 | 210 | class CommitmentTx { 211 | channel_id: string = ""; 212 | amount: number = 0; 213 | curr_temp_address_pub_key: string = ""; 214 | curr_temp_address_index: number = 0; 215 | last_temp_address_private_key: string = ""; 216 | } 217 | 218 | class CommitmentTxSigned { 219 | channel_id: string = ""; 220 | msg_hash: string = ""; 221 | c2a_rsmc_signed_hex: string = ""; 222 | c2a_counterparty_signed_hex: string = ""; 223 | curr_temp_address_pub_key: string = ""; 224 | curr_temp_address_index: number = 0; 225 | last_temp_address_private_key: string = ""; 226 | approval: boolean = false; 227 | } 228 | 229 | class InvoiceInfo { 230 | property_id: number = 0; 231 | amount: number = 0; 232 | h: string = ""; 233 | expiry_time: string = ""; 234 | description: string = ""; 235 | is_private: boolean = false; 236 | } 237 | 238 | class HTLCFindPathInfo extends InvoiceInfo { 239 | invoice: string = ""; 240 | recipient_node_peer_id: string = ""; 241 | recipient_user_peer_id: string = ""; 242 | is_inv_pay: boolean = false; 243 | } 244 | 245 | class addHTLCInfo { 246 | is_pay_invoice: boolean = false; 247 | recipient_user_peer_id: string = ""; 248 | // property_id: number = 0; 249 | amount: number = 0; 250 | amount_to_payee: number = 0; 251 | memo: string = ""; 252 | h: string = ""; 253 | routing_packet: string = ""; 254 | cltv_expiry: number = 0; 255 | // channel_address_private_key: string = ""; 256 | last_temp_address_private_key: string = ""; 257 | curr_rsmc_temp_address_pub_key: string = ""; 258 | // curr_rsmc_temp_address_private_key: string = ""; 259 | curr_rsmc_temp_address_index: number = 0; 260 | curr_htlc_temp_address_pub_key: string = ""; 261 | // curr_htlc_temp_address_private_key: string = ""; 262 | curr_htlc_temp_address_index: number = 0; 263 | curr_htlc_temp_address_for_ht1a_pub_key: string = ""; 264 | // curr_htlc_temp_address_for_ht1a_private_key: string = ""; 265 | curr_htlc_temp_address_for_ht1a_index: number = 0; 266 | } 267 | 268 | class HtlcSignedInfo { 269 | payer_commitment_tx_hash: string = ""; 270 | curr_rsmc_temp_address_pub_key: string = ""; 271 | curr_rsmc_temp_address_index: number = 0; 272 | curr_htlc_temp_address_pub_key: string = ""; 273 | curr_htlc_temp_address_index: number = 0; 274 | last_temp_address_private_key: string = ""; 275 | 276 | c3a_complete_signed_rsmc_hex: string = ""; 277 | c3a_complete_signed_counterparty_hex: string = ""; 278 | c3a_complete_signed_htlc_hex: string = ""; 279 | // channel_address_private_key: string = ""; 280 | // curr_rsmc_temp_address_private_key: string = ""; 281 | // curr_htlc_temp_address_private_key: string = ""; 282 | // approval: boolean = false; 283 | } 284 | 285 | class SignGetHInfo { 286 | request_hash: string = ""; 287 | channel_address_private_key: string = ""; 288 | last_temp_address_private_key: string = ""; 289 | curr_rsmc_temp_address_pub_key: string = ""; 290 | curr_rsmc_temp_address_private_key: string = ""; 291 | curr_htlc_temp_address_pub_key: string = ""; 292 | curr_htlc_temp_address_private_key: string = ""; 293 | approval: boolean = false; 294 | } 295 | 296 | class HtlcRequestOpen { 297 | request_hash: string = ""; 298 | channel_address_private_key: string = ""; 299 | last_temp_address_private_key: string = ""; 300 | curr_rsmc_temp_address_pub_key: string = ""; 301 | curr_rsmc_temp_address_private_key: string = ""; 302 | curr_htlc_temp_address_pub_key: string = ""; 303 | curr_htlc_temp_address_private_key: string = ""; 304 | curr_htlc_temp_address_for_ht1a_pub_key: string = ""; 305 | curr_htlc_temp_address_for_ht1a_private_key: string = ""; 306 | } 307 | 308 | class ForwardRInfo { 309 | channel_id: string = ""; 310 | r: string = ""; 311 | } 312 | 313 | class SignRInfo { 314 | channel_id: string = ""; 315 | c3b_htlc_herd_complete_signed_hex: string = ""; 316 | c3b_htlc_hebr_partial_signed_hex: string = ""; 317 | // msg_hash: string = ""; 318 | // r: string = ""; 319 | // channel_address_private_key: string = ""; 320 | } 321 | 322 | class CloseHtlcTxInfo { 323 | channel_id: string = ""; 324 | last_rsmc_temp_address_private_key: string = ""; 325 | last_htlc_temp_address_private_key: string = ""; 326 | last_htlc_temp_address_for_htnx_private_key: string = ""; 327 | curr_temp_address_pub_key: string = ""; 328 | curr_temp_address_index: number = 0; 329 | } 330 | 331 | class CloseHtlcTxInfoSigned { 332 | msg_hash: string = ""; 333 | last_rsmc_temp_address_private_key: string = ""; 334 | last_htlc_temp_address_private_key: string = ""; 335 | last_htlc_temp_address_for_htnx_private_key: string = ""; 336 | curr_temp_address_pub_key: string = ""; 337 | curr_temp_address_index: number = 0; 338 | } 339 | 340 | class IssueManagedAmoutInfo { 341 | from_address: string = ""; 342 | name: string = ""; 343 | ecosystem: number = 0; 344 | divisible_type: number = 0; 345 | data: string = ""; 346 | } 347 | 348 | class IssueFixedAmountInfo extends IssueManagedAmoutInfo { 349 | amount: number = 0; 350 | } 351 | 352 | class OmniSendGrant { 353 | from_address: string = ""; 354 | property_id: number = 0; 355 | amount: number = 0; 356 | memo: string = ""; 357 | } 358 | class OmniSendRevoke extends OmniSendGrant {} 359 | 360 | class CloseChannelSign { 361 | channel_id: string = ""; 362 | request_close_channel_hash: string = ""; 363 | approval: boolean = false; 364 | } 365 | 366 | /** 367 | * -80 368 | */ 369 | class AtomicSwapRequest{ 370 | channel_id_from: string = ""; 371 | channel_id_to: string = ""; 372 | recipient_user_peer_id: string = ""; 373 | property_sent: number = 0; 374 | amount: number = 0; 375 | exchange_rate: number = 0; 376 | property_received: number = 0; 377 | transaction_id: string = ""; 378 | time_locker: number = 0; 379 | } 380 | 381 | /** 382 | * -81 383 | */ 384 | class AtomicSwapAccepted extends AtomicSwapRequest { 385 | target_transaction_id: string = ""; 386 | } 387 | 388 | /** 389 | * MsgType_p2p_ConnectPeer_2003 390 | */ 391 | class P2PPeer { 392 | remote_node_address: string = ""; 393 | } 394 | 395 | class MessageType { 396 | MsgType_Error_0 = 0; 397 | 398 | // type id of functions in JS SDK 399 | MsgType_JS_SDK_100 = 100; 400 | MsgType_JS_SDK_101 = 101; 401 | MsgType_JS_SDK_102 = 102; 402 | 403 | MsgType_UserLogin_2001 = -102001; 404 | MsgType_UserLogout_2002 = -102002; 405 | MsgType_p2p_ConnectPeer_2003 = -102003; 406 | MsgType_GetMnemonic_2004 = -102004; 407 | 408 | MsgType_GetMiniBtcFundAmount_2006 = -102006; 409 | 410 | MsgType_Core_GetNewAddress_2101 = -102101; 411 | MsgType_Core_GetMiningInfo_2102 = -102102; 412 | MsgType_Core_GetNetworkInfo_2103 = -102103; 413 | MsgType_Core_SignMessageWithPrivKey_2104 = -102104; 414 | MsgType_Core_VerifyMessage_2105 = -102105; 415 | MsgType_Core_DumpPrivKey_2106 = -102106; 416 | MsgType_Core_ListUnspent_2107 = -102107; 417 | MsgType_Core_BalanceByAddress_2108 = -102108; 418 | MsgType_Core_FundingBTC_2109 = -102109; 419 | MsgType_Core_BtcCreateMultiSig_2110 = -102110; 420 | MsgType_Core_Btc_ImportPrivKey_2111 = -102111; 421 | MsgType_Core_Omni_Getbalance_2112 = -102112; 422 | MsgType_Core_Omni_CreateNewTokenFixed_2113 = -102113; 423 | MsgType_Core_Omni_CreateNewTokenManaged_2114 = -102114; 424 | MsgType_Core_Omni_GrantNewUnitsOfManagedToken_2115 = -102115; 425 | MsgType_Core_Omni_RevokeUnitsOfManagedToken_2116 = -102116; 426 | MsgType_Core_Omni_ListProperties_2117 = -102117; 427 | MsgType_Core_Omni_GetTransaction_2118 = -102118; 428 | MsgType_Core_Omni_GetProperty_2119 = -102119; 429 | MsgType_Core_Omni_FundingAsset_2120 = -102120; 430 | MsgType_Core_Omni_Send_2121 = -102121; 431 | 432 | MsgType_Mnemonic_CreateAddress_3000 = -103000; 433 | MsgType_Mnemonic_GetAddressByIndex_3001 = -103001; 434 | MsgType_FundingCreate_Asset_AllItem_3100 = -103100; 435 | MsgType_FundingCreate_Asset_ItemById_3101 = -103101; 436 | MsgType_FundingCreate_Asset_ItemByChannelId_3102 = -103102; 437 | MsgType_FundingCreate_Asset_Count_3103 = -103103; 438 | 439 | MsgType_SendChannelOpen_32 = -100032; 440 | MsgType_RecvChannelOpen_32 = -110032; 441 | MsgType_SendChannelAccept_33 = -100033; 442 | MsgType_RecvChannelAccept_33 = -110033; 443 | 444 | MsgType_FundingCreate_SendAssetFundingCreated_34 = -100034; 445 | MsgType_FundingCreate_RecvAssetFundingCreated_34 = -110034; 446 | MsgType_FundingSign_SendAssetFundingSigned_35 = -100035; 447 | MsgType_FundingSign_RecvAssetFundingSigned_35 = -110035; 448 | 449 | MsgType_ClientSign_AssetFunding_AliceSignC1a_1034 = -101034; 450 | MsgType_ClientSign_AssetFunding_AliceSignRD_1134 = -101134; 451 | MsgType_ClientSign_Duplex_AssetFunding_RdAndBr_1035 = -101035; 452 | 453 | MsgType_FundingCreate_SendBtcFundingCreated_340 = -100340; 454 | MsgType_FundingCreate_BtcFundingMinerRDTxToClient_341 = -100341; 455 | MsgType_FundingCreate_RecvBtcFundingCreated_340 = -110340; 456 | MsgType_FundingSign_SendBtcSign_350 = -100350; 457 | MsgType_FundingSign_RecvBtcSign_350 = -110350; 458 | 459 | MsgType_CommitmentTx_SendCommitmentTransactionCreated_351 = -100351; 460 | MsgType_CommitmentTx_RecvCommitmentTransactionCreated_351 = -110351; 461 | MsgType_CommitmentTxSigned_SendRevokeAndAcknowledgeCommitmentTransaction_352 = -100352; 462 | MsgType_CommitmentTxSigned_RecvRevokeAndAcknowledgeCommitmentTransaction_352 = -110352; 463 | 464 | MsgType_ClientSign_BobC2b_Rd_353 = -110353; 465 | MsgType_ClientSign_CommitmentTx_AliceSignC2a_360 = -100360; 466 | MsgType_ClientSign_CommitmentTx_BobSignC2b_361 = -100361; 467 | MsgType_ClientSign_CommitmentTx_AliceSignC2b_362 = -100362; 468 | MsgType_ClientSign_CommitmentTx_AliceSignC2b_Rd_363 = -100363; 469 | MsgType_ClientSign_CommitmentTx_BobSignC2b_Rd_364 = -100364; 470 | 471 | MsgType_ChannelOpen_AllItem_3150 = -103150; 472 | MsgType_ChannelOpen_ItemByTempId_3151 = -103151; 473 | MsgType_ChannelOpen_Count_3152 = -103152; 474 | MsgType_ChannelOpen_DelItemByTempId_3153 = -103153; 475 | MsgType_GetChannelInfoByChannelId_3154 = -103154; 476 | MsgType_GetChannelInfoByDbId_3155 = -103155; 477 | MsgType_CheckChannelAddessExist_3156 = -103156; 478 | 479 | MsgType_CommitmentTx_ItemsByChanId_3200 = -103200; 480 | MsgType_CommitmentTx_ItemById_3201 = -103201; 481 | MsgType_CommitmentTx_Count_3202 = -103202; 482 | MsgType_CommitmentTx_LatestCommitmentTxByChanId_3203 = -103203; 483 | MsgType_CommitmentTx_LatestRDByChanId_3204 = -103204; 484 | MsgType_CommitmentTx_LatestBRByChanId_3205 = -103205; 485 | MsgType_CommitmentTx_SendSomeCommitmentById_3206 = -103206; 486 | MsgType_CommitmentTx_AllRDByChanId_3207 = -103207; 487 | MsgType_CommitmentTx_AllBRByChanId_3208 = -103208; 488 | 489 | MsgType_SendCloseChannelRequest_38 = -100038; 490 | MsgType_RecvCloseChannelRequest_38 = -110038; 491 | MsgType_SendCloseChannelSign_39 = -100039; 492 | MsgType_RecvCloseChannelSign_39 = -110039; 493 | 494 | MsgType_HTLC_FindPath_401 = -100401; 495 | MsgType_HTLC_Invoice_402 = -100402; 496 | MsgType_HTLC_SendAddHTLC_40 = -100040; 497 | MsgType_HTLC_RecvAddHTLC_40 = -110040; 498 | MsgType_HTLC_SendAddHTLCSigned_41 = -100041; 499 | MsgType_HTLC_RecvAddHTLCSigned_41 = -110041; 500 | MsgType_HTLC_BobSignC3bSubTx_42 = -110042; 501 | MsgType_HTLC_FinishTransferH_43 = -110043; 502 | MsgType_HTLC_SendVerifyR_45 = -100045; 503 | MsgType_HTLC_RecvVerifyR_45 = -110045; 504 | MsgType_HTLC_SendSignVerifyR_46 = -100046; 505 | MsgType_HTLC_RecvSignVerifyR_46 = -110046; 506 | MsgType_HTLC_SendRequestCloseCurrTx_49 = -100049; 507 | MsgType_HTLC_RecvRequestCloseCurrTx_49 = -110049; 508 | MsgType_HTLC_SendCloseSigned_50 = -100050; 509 | MsgType_HTLC_RecvCloseSigned_50 = -110050; 510 | MsgType_HTLC_Close_ClientSign_Bob_C4bSub_51 = -110051; 511 | 512 | MsgType_HTLC_ClientSign_Alice_C3a_100 = -100100; 513 | MsgType_HTLC_ClientSign_Bob_C3b_101 = -100101; 514 | MsgType_HTLC_ClientSign_Alice_C3b_102 = -100102; 515 | MsgType_HTLC_ClientSign_Alice_C3bSub_103 = -100103; 516 | MsgType_HTLC_ClientSign_Bob_C3bSub_104 = -100104; 517 | MsgType_HTLC_ClientSign_Alice_He_105 = -100105; 518 | MsgType_HTLC_ClientSign_Bob_HeSub_106 = -100106; 519 | MsgType_HTLC_ClientSign_Alice_HeSub_107 = -100107; 520 | 521 | MsgType_HTLC_Close_ClientSign_Alice_C4a_110 = -100110; 522 | MsgType_HTLC_Close_ClientSign_Bob_C4b_111 = -100111; 523 | MsgType_HTLC_Close_ClientSign_Alice_C4b_112 = -100112; 524 | MsgType_HTLC_Close_ClientSign_Alice_C4bSub_113 = -100113; 525 | MsgType_HTLC_Close_ClientSign_Bob_C4bSubResult_114 = -100114; 526 | 527 | MsgType_Atomic_SendSwap_80 = -100080; 528 | MsgType_Atomic_RecvSwap_80 = -110080; 529 | MsgType_Atomic_SendSwapAccept_81 = -100081; 530 | MsgType_Atomic_RecvSwapAccept_81 = -110081; 531 | } 532 | -------------------------------------------------------------------------------- /ts/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | /* Basic Options */ 4 | // "incremental": true, /* Enable incremental compilation */ 5 | "target": "es2015", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019' or 'ESNEXT'. */ 6 | //"module": "commonjs", /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'. */ 7 | // "lib": [], /* Specify library files to be included in the compilation. */ 8 | // "allowJs": true, /* Allow javascript files to be compiled. */ 9 | // "checkJs": true, /* Report errors in .js files. */ 10 | // "jsx": "preserve", /* Specify JSX code generation: 'preserve', 'react-native', or 'react'. */ 11 | // "declaration": true, /* Generates corresponding '.d.ts' file. */ 12 | // "declarationMap": true, /* Generates a sourcemap for each corresponding '.d.ts' file. */ 13 | // "sourceMap": true, /* Generates corresponding '.map' file. */ 14 | // "outFile": "./", /* Concatenate and emit output to single file. */ 15 | "outDir": "../sdk", /* Redirect output structure to the directory. */ 16 | "rootDir": ".", /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */ 17 | // "composite": true, /* Enable project compilation */ 18 | // "tsBuildInfoFile": "./", /* Specify file to store incremental compilation information */ 19 | // "removeComments": true, /* Do not emit comments to output. */ 20 | // "noEmit": true, /* Do not emit outputs. */ 21 | // "importHelpers": true, /* Import emit helpers from 'tslib'. */ 22 | // "downlevelIteration": true, /* Provide full support for iterables in 'for-of', spread, and destructuring when targeting 'ES5' or 'ES3'. */ 23 | // "isolatedModules": true, /* Transpile each file as a separate module (similar to 'ts.transpileModule'). */ 24 | 25 | /* Strict Type-Checking Options */ 26 | //"strict": true, /* Enable all strict type-checking options. */ 27 | // "noImplicitAny": true, /* Raise error on expressions and declarations with an implied 'any' type. */ 28 | // "strictNullChecks": true, /* Enable strict null checks. */ 29 | // "strictFunctionTypes": true, /* Enable strict checking of function types. */ 30 | // "strictBindCallApply": true, /* Enable strict 'bind', 'call', and 'apply' methods on functions. */ 31 | // "strictPropertyInitialization": true, /* Enable strict checking of property initialization in classes. */ 32 | // "noImplicitThis": true, /* Raise error on 'this' expressions with an implied 'any' type. */ 33 | // "alwaysStrict": true, /* Parse in strict mode and emit "use strict" for each source file. */ 34 | 35 | /* Additional Checks */ 36 | // "noUnusedLocals": true, /* Report errors on unused locals. */ 37 | // "noUnusedParameters": true, /* Report errors on unused parameters. */ 38 | // "noImplicitReturns": true, /* Report error when not all code paths in function return a value. */ 39 | // "noFallthroughCasesInSwitch": true, /* Report errors for fallthrough cases in switch statement. */ 40 | 41 | /* Module Resolution Options */ 42 | // "moduleResolution": "node", /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */ 43 | // "baseUrl": "./", /* Base directory to resolve non-absolute module names. */ 44 | // "paths": {}, /* A series of entries which re-map imports to lookup locations relative to the 'baseUrl'. */ 45 | // "rootDirs": [], /* List of root folders whose combined content represents the structure of the project at runtime. */ 46 | // "typeRoots": [], /* List of folders to include type definitions from. */ 47 | // "types": [], /* Type declaration files to be included in compilation. */ 48 | // "allowSyntheticDefaultImports": true, /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */ 49 | //"esModuleInterop": true, /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */ 50 | // "preserveSymlinks": true, /* Do not resolve the real path of symlinks. */ 51 | // "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */ 52 | 53 | /* Source Map Options */ 54 | // "sourceRoot": "", /* Specify the location where debugger should locate TypeScript files instead of source locations. */ 55 | // "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */ 56 | // "inlineSourceMap": true, /* Emit a single file with source maps instead of having a separate file. */ 57 | // "inlineSources": true, /* Emit the source alongside the sourcemaps within a single file; requires '--inlineSourceMap' or '--sourceMap' to be set. */ 58 | 59 | /* Experimental Options */ 60 | // "experimentalDecorators": true, /* Enables experimental support for ES7 decorators. */ 61 | // "emitDecoratorMetadata": true, /* Enables experimental support for emitting type metadata for decorators. */ 62 | 63 | /* Advanced Options */ 64 | "forceConsistentCasingInFileNames": true /* Disallow inconsistently-cased references to the same file. */ 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /userData.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | User Data 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 |
24 | 25 |
26 |
27 |
28 |
29 | 30 | 31 | 47 | 48 | --------------------------------------------------------------------------------