cryptoadvance-specter 2.1.2__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (523) hide show
  1. cryptoadvance/specter/__init__.py +0 -0
  2. cryptoadvance/specter/__main__.py +7 -0
  3. cryptoadvance/specter/_version.py +34 -0
  4. cryptoadvance/specter/api/__init__.py +18 -0
  5. cryptoadvance/specter/api/rest/__init__.py +0 -0
  6. cryptoadvance/specter/api/rest/api.py +83 -0
  7. cryptoadvance/specter/api/rest/base.py +92 -0
  8. cryptoadvance/specter/api/rest/resource_healthz.py +42 -0
  9. cryptoadvance/specter/api/rest/resource_jwt.py +135 -0
  10. cryptoadvance/specter/api/rest/resource_psbt.py +53 -0
  11. cryptoadvance/specter/api/rest/resource_specter.py +46 -0
  12. cryptoadvance/specter/api/rest/resource_txlist.py +34 -0
  13. cryptoadvance/specter/api/security.py +73 -0
  14. cryptoadvance/specter/api/templates/api.html +18 -0
  15. cryptoadvance/specter/api/views.py +11 -0
  16. cryptoadvance/specter/cli/__init__.py +36 -0
  17. cryptoadvance/specter/cli/cli_ext.py +193 -0
  18. cryptoadvance/specter/cli/cli_gunicorn.py +61 -0
  19. cryptoadvance/specter/cli/cli_noded.py +425 -0
  20. cryptoadvance/specter/cli/cli_server.py +279 -0
  21. cryptoadvance/specter/cli/utils.py +65 -0
  22. cryptoadvance/specter/commands/psbt_creator.py +360 -0
  23. cryptoadvance/specter/commands/utxo_scanner.py +250 -0
  24. cryptoadvance/specter/config.py +298 -0
  25. cryptoadvance/specter/device.py +208 -0
  26. cryptoadvance/specter/devices/__init__.py +34 -0
  27. cryptoadvance/specter/devices/bitbox02.py +20 -0
  28. cryptoadvance/specter/devices/bitcoin_core.py +314 -0
  29. cryptoadvance/specter/devices/cobo.py +68 -0
  30. cryptoadvance/specter/devices/coldcard.py +63 -0
  31. cryptoadvance/specter/devices/elements_core.py +59 -0
  32. cryptoadvance/specter/devices/generic.py +19 -0
  33. cryptoadvance/specter/devices/hwi/__init__.py +4 -0
  34. cryptoadvance/specter/devices/hwi/jade.py +766 -0
  35. cryptoadvance/specter/devices/hwi/jadepy/__init__.py +4 -0
  36. cryptoadvance/specter/devices/hwi/jadepy/jade.py +2195 -0
  37. cryptoadvance/specter/devices/hwi/jadepy/jade_error.py +31 -0
  38. cryptoadvance/specter/devices/hwi/jadepy/jade_serial.py +85 -0
  39. cryptoadvance/specter/devices/hwi/jadepy/jade_tcp.py +65 -0
  40. cryptoadvance/specter/devices/hwi/keepkey.py +219 -0
  41. cryptoadvance/specter/devices/hwi/specter_diy.py +416 -0
  42. cryptoadvance/specter/devices/hwi_device.py +21 -0
  43. cryptoadvance/specter/devices/jade.py +100 -0
  44. cryptoadvance/specter/devices/keepkey.py +15 -0
  45. cryptoadvance/specter/devices/keystone.py +54 -0
  46. cryptoadvance/specter/devices/ledger.py +10 -0
  47. cryptoadvance/specter/devices/passport.py +7 -0
  48. cryptoadvance/specter/devices/sd_card_device.py +12 -0
  49. cryptoadvance/specter/devices/seedsigner.py +22 -0
  50. cryptoadvance/specter/devices/specter.py +172 -0
  51. cryptoadvance/specter/devices/trezor.py +15 -0
  52. cryptoadvance/specter/gunicorn.py +33 -0
  53. cryptoadvance/specter/helpers.py +350 -0
  54. cryptoadvance/specter/htmlsafebabel.py +34 -0
  55. cryptoadvance/specter/hwi_rpc.py +596 -0
  56. cryptoadvance/specter/hwi_server.py +117 -0
  57. cryptoadvance/specter/internal_node.py +268 -0
  58. cryptoadvance/specter/key.py +209 -0
  59. cryptoadvance/specter/liquid/__init__.py +0 -0
  60. cryptoadvance/specter/liquid/addresslist.py +63 -0
  61. cryptoadvance/specter/liquid/rpc.py +519 -0
  62. cryptoadvance/specter/liquid/txlist.py +219 -0
  63. cryptoadvance/specter/liquid/util/__init__.py +0 -0
  64. cryptoadvance/specter/liquid/util/pset.py +200 -0
  65. cryptoadvance/specter/liquid/wallet.py +305 -0
  66. cryptoadvance/specter/managers/config_manager.py +341 -0
  67. cryptoadvance/specter/managers/device_manager.py +143 -0
  68. cryptoadvance/specter/managers/genericdata_manager.py +88 -0
  69. cryptoadvance/specter/managers/node_manager.py +288 -0
  70. cryptoadvance/specter/managers/otp_manager.py +49 -0
  71. cryptoadvance/specter/managers/service_manager/__init__.py +5 -0
  72. cryptoadvance/specter/managers/service_manager/callback_executor.py +160 -0
  73. cryptoadvance/specter/managers/service_manager/service_manager.py +606 -0
  74. cryptoadvance/specter/managers/user_manager.py +108 -0
  75. cryptoadvance/specter/managers/wallet_manager.py +527 -0
  76. cryptoadvance/specter/node.py +783 -0
  77. cryptoadvance/specter/persistence.py +305 -0
  78. cryptoadvance/specter/process_controller/__init__.py +0 -0
  79. cryptoadvance/specter/process_controller/bitcoind_controller.py +87 -0
  80. cryptoadvance/specter/process_controller/elementsd_controller.py +93 -0
  81. cryptoadvance/specter/process_controller/node_controller.py +593 -0
  82. cryptoadvance/specter/rpc.py +543 -0
  83. cryptoadvance/specter/server.py +375 -0
  84. cryptoadvance/specter/server_endpoints/__init__.py +18 -0
  85. cryptoadvance/specter/server_endpoints/auth.py +272 -0
  86. cryptoadvance/specter/server_endpoints/controller.py +307 -0
  87. cryptoadvance/specter/server_endpoints/devices.py +541 -0
  88. cryptoadvance/specter/server_endpoints/filters.py +160 -0
  89. cryptoadvance/specter/server_endpoints/nodes.py +576 -0
  90. cryptoadvance/specter/server_endpoints/price.py +51 -0
  91. cryptoadvance/specter/server_endpoints/settings.py +756 -0
  92. cryptoadvance/specter/server_endpoints/setup.py +216 -0
  93. cryptoadvance/specter/server_endpoints/wallets/__init__.py +1 -0
  94. cryptoadvance/specter/server_endpoints/wallets/wallets.py +987 -0
  95. cryptoadvance/specter/server_endpoints/wallets/wallets_api.py +1163 -0
  96. cryptoadvance/specter/server_endpoints/wallets/wallets_vm.py +16 -0
  97. cryptoadvance/specter/server_endpoints/welcome/__init__.py +1 -0
  98. cryptoadvance/specter/server_endpoints/welcome/welcome.py +129 -0
  99. cryptoadvance/specter/server_endpoints/welcome/welcome_vm.py +17 -0
  100. cryptoadvance/specter/services/__init__.py +5 -0
  101. cryptoadvance/specter/services/callbacks.py +126 -0
  102. cryptoadvance/specter/services/controller.py +91 -0
  103. cryptoadvance/specter/services/extension_gen.py +239 -0
  104. cryptoadvance/specter/services/service.py +255 -0
  105. cryptoadvance/specter/services/service_annotations_storage.py +72 -0
  106. cryptoadvance/specter/services/service_encrypted_storage.py +217 -0
  107. cryptoadvance/specter/services/templates/components/menu_item.jinja +19 -0
  108. cryptoadvance/specter/services/templates/includes/services-data.html +15 -0
  109. cryptoadvance/specter/services/templates/services/associate_addr.jinja +20 -0
  110. cryptoadvance/specter/specter.py +817 -0
  111. cryptoadvance/specter/specter_error.py +65 -0
  112. cryptoadvance/specter/static/bcur/base58.min.js +1 -0
  113. cryptoadvance/specter/static/bcur/buffer.min.js +1 -0
  114. cryptoadvance/specter/static/bcur/urlib.min.js +23 -0
  115. cryptoadvance/specter/static/bitcoin-release-pubkey.asc +784 -0
  116. cryptoadvance/specter/static/favicon.js +22 -0
  117. cryptoadvance/specter/static/fonts/RobotoMono-Bold.ttf +0 -0
  118. cryptoadvance/specter/static/fonts/RobotoMono-Regular.ttf +0 -0
  119. cryptoadvance/specter/static/fonts/Social-Bold.otf +0 -0
  120. cryptoadvance/specter/static/fonts/Social-Medium.otf +0 -0
  121. cryptoadvance/specter/static/fonts/Social-Regular.otf +0 -0
  122. cryptoadvance/specter/static/helpers.js +214 -0
  123. cryptoadvance/specter/static/hwi.js +205 -0
  124. cryptoadvance/specter/static/img/add-person.svg +1 -0
  125. cryptoadvance/specter/static/img/alert.svg +3 -0
  126. cryptoadvance/specter/static/img/arrow-right.svg +4 -0
  127. cryptoadvance/specter/static/img/backspace.svg +1 -0
  128. cryptoadvance/specter/static/img/bitcoin-logo.svg +6 -0
  129. cryptoadvance/specter/static/img/broken-connection.svg +55 -0
  130. cryptoadvance/specter/static/img/caret-down.svg +3 -0
  131. cryptoadvance/specter/static/img/caret-up.svg +3 -0
  132. cryptoadvance/specter/static/img/check.svg +3 -0
  133. cryptoadvance/specter/static/img/check_thick.svg +3 -0
  134. cryptoadvance/specter/static/img/checkbox-tick.svg +1 -0
  135. cryptoadvance/specter/static/img/checkbox-untick.svg +1 -0
  136. cryptoadvance/specter/static/img/clear-character.svg +3 -0
  137. cryptoadvance/specter/static/img/clock.svg +3 -0
  138. cryptoadvance/specter/static/img/close.svg +1 -0
  139. cryptoadvance/specter/static/img/copy-color.svg +61 -0
  140. cryptoadvance/specter/static/img/copy.svg +4 -0
  141. cryptoadvance/specter/static/img/cross.svg +4 -0
  142. cryptoadvance/specter/static/img/cross_thick.svg +4 -0
  143. cryptoadvance/specter/static/img/devices/bitbox02_icon.svg +11 -0
  144. cryptoadvance/specter/static/img/devices/bitcoincore_icon.svg +11 -0
  145. cryptoadvance/specter/static/img/devices/cobo_icon.svg +11 -0
  146. cryptoadvance/specter/static/img/devices/coldcard_icon.svg +26 -0
  147. cryptoadvance/specter/static/img/devices/elementscore_icon.svg +49 -0
  148. cryptoadvance/specter/static/img/devices/hwi_icon.svg +15 -0
  149. cryptoadvance/specter/static/img/devices/jade_icon.svg +14 -0
  150. cryptoadvance/specter/static/img/devices/keepkey_icon.svg +13 -0
  151. cryptoadvance/specter/static/img/devices/keystone_icon.svg +14 -0
  152. cryptoadvance/specter/static/img/devices/ledger_icon.svg +14 -0
  153. cryptoadvance/specter/static/img/devices/other_icon.svg +15 -0
  154. cryptoadvance/specter/static/img/devices/passport_icon.svg +66 -0
  155. cryptoadvance/specter/static/img/devices/seedsigner_icon.svg +9 -0
  156. cryptoadvance/specter/static/img/devices/specter_icon.svg +16 -0
  157. cryptoadvance/specter/static/img/devices/trezor_icon.svg +11 -0
  158. cryptoadvance/specter/static/img/disconnected.svg +1 -0
  159. cryptoadvance/specter/static/img/down-arrow.svg +39 -0
  160. cryptoadvance/specter/static/img/edit.svg +3 -0
  161. cryptoadvance/specter/static/img/exit.svg +5 -0
  162. cryptoadvance/specter/static/img/expand-less.svg +1 -0
  163. cryptoadvance/specter/static/img/expand-more.svg +1 -0
  164. cryptoadvance/specter/static/img/failed.svg +63 -0
  165. cryptoadvance/specter/static/img/favicon-dark-mode.png +0 -0
  166. cryptoadvance/specter/static/img/favicon-light-mode.png +0 -0
  167. cryptoadvance/specter/static/img/file.svg +3 -0
  168. cryptoadvance/specter/static/img/flip-horizontal.svg +6 -0
  169. cryptoadvance/specter/static/img/gear.svg +3 -0
  170. cryptoadvance/specter/static/img/generate_icon.svg +14 -0
  171. cryptoadvance/specter/static/img/ghost.png +0 -0
  172. cryptoadvance/specter/static/img/ghost_3d.png +0 -0
  173. cryptoadvance/specter/static/img/ghost_3d_transparent.png +0 -0
  174. cryptoadvance/specter/static/img/github.svg +2 -0
  175. cryptoadvance/specter/static/img/hidden.svg +4 -0
  176. cryptoadvance/specter/static/img/icon.icns +0 -0
  177. cryptoadvance/specter/static/img/icon.ico +0 -0
  178. cryptoadvance/specter/static/img/icon.png +0 -0
  179. cryptoadvance/specter/static/img/info_sign.svg +4 -0
  180. cryptoadvance/specter/static/img/key.svg +3 -0
  181. cryptoadvance/specter/static/img/light-bulb.svg +48 -0
  182. cryptoadvance/specter/static/img/liquid-logo.svg +121 -0
  183. cryptoadvance/specter/static/img/loader.gif +0 -0
  184. cryptoadvance/specter/static/img/loader_boxes.svg +17 -0
  185. cryptoadvance/specter/static/img/love.png +0 -0
  186. cryptoadvance/specter/static/img/menu.svg +5 -0
  187. cryptoadvance/specter/static/img/mixed-clock.svg +79 -0
  188. cryptoadvance/specter/static/img/mixed.svg +9 -0
  189. cryptoadvance/specter/static/img/no-dollars.svg +3 -0
  190. cryptoadvance/specter/static/img/not-supported.svg +52 -0
  191. cryptoadvance/specter/static/img/note.svg +85 -0
  192. cryptoadvance/specter/static/img/other.svg +15 -0
  193. cryptoadvance/specter/static/img/party.png +0 -0
  194. cryptoadvance/specter/static/img/plus.svg +4 -0
  195. cryptoadvance/specter/static/img/preferences_tab_screenshot.png +0 -0
  196. cryptoadvance/specter/static/img/qr-code.svg +27 -0
  197. cryptoadvance/specter/static/img/radio-button-running-node.svg +1 -0
  198. cryptoadvance/specter/static/img/radio-button-selected-node.svg +1 -0
  199. cryptoadvance/specter/static/img/receive-clock.svg +57 -0
  200. cryptoadvance/specter/static/img/receive.svg +4 -0
  201. cryptoadvance/specter/static/img/refresh.svg +1 -0
  202. cryptoadvance/specter/static/img/sd-card.svg +3 -0
  203. cryptoadvance/specter/static/img/send-clock.svg +57 -0
  204. cryptoadvance/specter/static/img/send.svg +4 -0
  205. cryptoadvance/specter/static/img/snowflake.svg +8 -0
  206. cryptoadvance/specter/static/img/specter.svg +247 -0
  207. cryptoadvance/specter/static/img/tag.svg +1 -0
  208. cryptoadvance/specter/static/img/tor.svg +31 -0
  209. cryptoadvance/specter/static/img/transfer-clock.svg +82 -0
  210. cryptoadvance/specter/static/img/transfer.svg +5 -0
  211. cryptoadvance/specter/static/img/twitter.svg +1 -0
  212. cryptoadvance/specter/static/img/two-keys.svg +4 -0
  213. cryptoadvance/specter/static/img/usb.svg +4 -0
  214. cryptoadvance/specter/static/img/v1-icons/icon.icns +0 -0
  215. cryptoadvance/specter/static/img/v1-icons/icon.ico +0 -0
  216. cryptoadvance/specter/static/img/v1-icons/icon.png +0 -0
  217. cryptoadvance/specter/static/img/visible.svg +3 -0
  218. cryptoadvance/specter/static/img/warning_sign.svg +4 -0
  219. cryptoadvance/specter/static/output.css +2462 -0
  220. cryptoadvance/specter/static/pdf/jspdf.es.js +36077 -0
  221. cryptoadvance/specter/static/pdf/jspdf.es.js.map +1 -0
  222. cryptoadvance/specter/static/pdf/jspdf.es.min.js +507 -0
  223. cryptoadvance/specter/static/pdf/jspdf.es.min.js.map +1 -0
  224. cryptoadvance/specter/static/pdf/polyfills.es.js +62 -0
  225. cryptoadvance/specter/static/progress-wizard.min.css +1 -0
  226. cryptoadvance/specter/static/pruned-node-today-release-pubkey.asc +12 -0
  227. cryptoadvance/specter/static/qr/qr-scanner-worker.min.js +86 -0
  228. cryptoadvance/specter/static/qr/qr-scanner.min.js +12 -0
  229. cryptoadvance/specter/static/qr/qr-scanner.min.js.map +1 -0
  230. cryptoadvance/specter/static/qr/qrcode.min.js +1 -0
  231. cryptoadvance/specter/static/style.css +244 -0
  232. cryptoadvance/specter/static/styles.css +1585 -0
  233. cryptoadvance/specter/static/torbrowser-release-pubkey.asc +332 -0
  234. cryptoadvance/specter/static/typography.css +20 -0
  235. cryptoadvance/specter/templates/500.jinja +35 -0
  236. cryptoadvance/specter/templates/500_timeout.jinja +35 -0
  237. cryptoadvance/specter/templates/base.jinja +168 -0
  238. cryptoadvance/specter/templates/components/editable_title.jinja +42 -0
  239. cryptoadvance/specter/templates/components/explorer_select.jinja +28 -0
  240. cryptoadvance/specter/templates/components/network_label.jinja +17 -0
  241. cryptoadvance/specter/templates/components/price_bar.jinja +246 -0
  242. cryptoadvance/specter/templates/device/components/add_keys.js +25 -0
  243. cryptoadvance/specter/templates/device/components/device_type.jinja +13 -0
  244. cryptoadvance/specter/templates/device/device.jinja +259 -0
  245. cryptoadvance/specter/templates/device/device_blinding_key.jinja +101 -0
  246. cryptoadvance/specter/templates/device/new_device/new_device_keys.jinja +545 -0
  247. cryptoadvance/specter/templates/device/new_device/new_device_mnemonic.jinja +188 -0
  248. cryptoadvance/specter/templates/device/new_device/new_device_type.jinja +63 -0
  249. cryptoadvance/specter/templates/device/new_device_manual.jinja +458 -0
  250. cryptoadvance/specter/templates/hwi_bridge.jinja +34 -0
  251. cryptoadvance/specter/templates/includes/address-data.html +151 -0
  252. cryptoadvance/specter/templates/includes/address-label.html +311 -0
  253. cryptoadvance/specter/templates/includes/address-row.html +174 -0
  254. cryptoadvance/specter/templates/includes/addresses-table.html +512 -0
  255. cryptoadvance/specter/templates/includes/asset-label.html +248 -0
  256. cryptoadvance/specter/templates/includes/coin_selection.html +187 -0
  257. cryptoadvance/specter/templates/includes/dnd-textarea.html +153 -0
  258. cryptoadvance/specter/templates/includes/explorer-link.html +38 -0
  259. cryptoadvance/specter/templates/includes/fee-selection.html +418 -0
  260. cryptoadvance/specter/templates/includes/file-uploader.html +79 -0
  261. cryptoadvance/specter/templates/includes/helpers.jinja +81 -0
  262. cryptoadvance/specter/templates/includes/hwi/components/passphrase.jinja +29 -0
  263. cryptoadvance/specter/templates/includes/hwi/components/pin.jinja +101 -0
  264. cryptoadvance/specter/templates/includes/hwi/components/select_device.jinja +155 -0
  265. cryptoadvance/specter/templates/includes/hwi/components/wallet.jinja +131 -0
  266. cryptoadvance/specter/templates/includes/hwi/hwi.jinja +230 -0
  267. cryptoadvance/specter/templates/includes/language/language_js.jinja +33 -0
  268. cryptoadvance/specter/templates/includes/language/language_select.jinja +11 -0
  269. cryptoadvance/specter/templates/includes/merkletooltip.html +12 -0
  270. cryptoadvance/specter/templates/includes/message-box.html +100 -0
  271. cryptoadvance/specter/templates/includes/message-events.js +9 -0
  272. cryptoadvance/specter/templates/includes/overlay/broadcast_tx.jinja +17 -0
  273. cryptoadvance/specter/templates/includes/overlay/key_export_qr.jinja +74 -0
  274. cryptoadvance/specter/templates/includes/overlay/liquid_assets_registry.html +135 -0
  275. cryptoadvance/specter/templates/includes/overlay/overlay.html +107 -0
  276. cryptoadvance/specter/templates/includes/overlay/qr_code_sign.jinja +38 -0
  277. cryptoadvance/specter/templates/includes/overlay/qr_code_sign_message.jinja +38 -0
  278. cryptoadvance/specter/templates/includes/overlay/sd_card_sign.jinja +27 -0
  279. cryptoadvance/specter/templates/includes/overlay/sign_tx_method.jinja +125 -0
  280. cryptoadvance/specter/templates/includes/page-limit-select.html +10 -0
  281. cryptoadvance/specter/templates/includes/qr-code.html +436 -0
  282. cryptoadvance/specter/templates/includes/qr-scanner.html +235 -0
  283. cryptoadvance/specter/templates/includes/recipient-box.html +506 -0
  284. cryptoadvance/specter/templates/includes/sidebar/components/node_connection.jinja +51 -0
  285. cryptoadvance/specter/templates/includes/sidebar/components/node_select_popup.jinja +102 -0
  286. cryptoadvance/specter/templates/includes/sidebar/components/sidebar_btn.jinja +15 -0
  287. cryptoadvance/specter/templates/includes/sidebar/components/sidebar_device_list_item.jinja +17 -0
  288. cryptoadvance/specter/templates/includes/sidebar/components/sidebar_services_list.jinja +10 -0
  289. cryptoadvance/specter/templates/includes/sidebar/components/sidebar_wallet_list_item.jinja +93 -0
  290. cryptoadvance/specter/templates/includes/sidebar/components/wallet_type_svg.jinja +11 -0
  291. cryptoadvance/specter/templates/includes/sidebar/sidebar.jinja +361 -0
  292. cryptoadvance/specter/templates/includes/text-explainer.html +72 -0
  293. cryptoadvance/specter/templates/includes/tool-tip.html +179 -0
  294. cryptoadvance/specter/templates/includes/tx-data.html +279 -0
  295. cryptoadvance/specter/templates/includes/tx-row.html +471 -0
  296. cryptoadvance/specter/templates/includes/tx-table.html +1187 -0
  297. cryptoadvance/specter/templates/login.jinja +21 -0
  298. cryptoadvance/specter/templates/node/components/bitcoin_core_info.jinja +202 -0
  299. cryptoadvance/specter/templates/node/components/no_tx_hint.jinja +8 -0
  300. cryptoadvance/specter/templates/node/components/node_logo.jinja +7 -0
  301. cryptoadvance/specter/templates/node/internal_node_logs.jinja +21 -0
  302. cryptoadvance/specter/templates/node/internal_node_settings.jinja +54 -0
  303. cryptoadvance/specter/templates/node/node_settings.jinja +249 -0
  304. cryptoadvance/specter/templates/register.jinja +43 -0
  305. cryptoadvance/specter/templates/services/choose.jinja +238 -0
  306. cryptoadvance/specter/templates/services/components/plugin_card.jinja +16 -0
  307. cryptoadvance/specter/templates/services/components/wishlist.jinja +6 -0
  308. cryptoadvance/specter/templates/services/inject_in_basejinja_body_bottom.jinja +8 -0
  309. cryptoadvance/specter/templates/services/inject_in_basejinja_body_top.jinja +8 -0
  310. cryptoadvance/specter/templates/services/inject_in_basejinja_head.jinja +8 -0
  311. cryptoadvance/specter/templates/settings/auth_settings.jinja +161 -0
  312. cryptoadvance/specter/templates/settings/components/settings_menu.jinja +32 -0
  313. cryptoadvance/specter/templates/settings/components/settings_menu_item.jinja +15 -0
  314. cryptoadvance/specter/templates/settings/general_settings.jinja +266 -0
  315. cryptoadvance/specter/templates/settings/hwi_settings.jinja +86 -0
  316. cryptoadvance/specter/templates/settings/tor_settings.jinja +212 -0
  317. cryptoadvance/specter/templates/setup/bitcoind.jinja +45 -0
  318. cryptoadvance/specter/templates/setup/bitcoind_datadir.jinja +188 -0
  319. cryptoadvance/specter/templates/setup/end.jinja +8 -0
  320. cryptoadvance/specter/templates/setup/node_type.jinja +17 -0
  321. cryptoadvance/specter/templates/setup/setup_page.jinja +78 -0
  322. cryptoadvance/specter/templates/setup/start.jinja +17 -0
  323. cryptoadvance/specter/templates/setup/tor.jinja +52 -0
  324. cryptoadvance/specter/templates/wallet/addresses/wallet_addresses.jinja +25 -0
  325. cryptoadvance/specter/templates/wallet/components/editable_label.jinja +41 -0
  326. cryptoadvance/specter/templates/wallet/components/explorer_link.jinja +15 -0
  327. cryptoadvance/specter/templates/wallet/components/wallet_menu.jinja +32 -0
  328. cryptoadvance/specter/templates/wallet/components/wallet_menu_item.jinja +21 -0
  329. cryptoadvance/specter/templates/wallet/components/wallet_pdf.jinja +259 -0
  330. cryptoadvance/specter/templates/wallet/components/wallet_tab.jinja +14 -0
  331. cryptoadvance/specter/templates/wallet/history/components/total_wallet_balances.jinja +153 -0
  332. cryptoadvance/specter/templates/wallet/history/wallet_history.jinja +37 -0
  333. cryptoadvance/specter/templates/wallet/new_wallet/components/import_wallet_account_map.jinja +117 -0
  334. cryptoadvance/specter/templates/wallet/new_wallet/import_wallet.jinja +70 -0
  335. cryptoadvance/specter/templates/wallet/new_wallet/new_wallet.jinja +76 -0
  336. cryptoadvance/specter/templates/wallet/new_wallet/new_wallet_keys.jinja +309 -0
  337. cryptoadvance/specter/templates/wallet/new_wallet/new_wallet_type.jinja +60 -0
  338. cryptoadvance/specter/templates/wallet/overview/balance_overview.jinja +17 -0
  339. cryptoadvance/specter/templates/wallet/overview/header_and_summary.jinja +1 -0
  340. cryptoadvance/specter/templates/wallet/overview/tx_table.jinja +18 -0
  341. cryptoadvance/specter/templates/wallet/overview/wallets_overview.jinja +26 -0
  342. cryptoadvance/specter/templates/wallet/receive/wallet_receive.jinja +193 -0
  343. cryptoadvance/specter/templates/wallet/send/components/send_nav.jinja +20 -0
  344. cryptoadvance/specter/templates/wallet/send/import/wallet_importpsbt.jinja +63 -0
  345. cryptoadvance/specter/templates/wallet/send/new/wallet_send.jinja +653 -0
  346. cryptoadvance/specter/templates/wallet/send/pending/components/pending_psbt_item.jinja +53 -0
  347. cryptoadvance/specter/templates/wallet/send/pending/components/pending_psbt_table.jinja +35 -0
  348. cryptoadvance/specter/templates/wallet/send/pending/wallet_sendpending.jinja +12 -0
  349. cryptoadvance/specter/templates/wallet/send/sign/wallet_send_sign_psbt.jinja +493 -0
  350. cryptoadvance/specter/templates/wallet/settings/components/export_wallet_account_map.jinja +34 -0
  351. cryptoadvance/specter/templates/wallet/settings/wallet_settings.jinja +486 -0
  352. cryptoadvance/specter/templates/welcome/components/get_started.jinja +26 -0
  353. cryptoadvance/specter/templates/welcome/components/remaining_remarks.jinja +16 -0
  354. cryptoadvance/specter/templates/welcome/components/specter_remote.jinja +12 -0
  355. cryptoadvance/specter/templates/welcome/components/tick_checkboxes.jinja +102 -0
  356. cryptoadvance/specter/templates/welcome/welcome.jinja +21 -0
  357. cryptoadvance/specter/tor_daemon.py +108 -0
  358. cryptoadvance/specter/translations/bg/LC_MESSAGES/messages.po +4374 -0
  359. cryptoadvance/specter/translations/de/LC_MESSAGES/messages.po +4438 -0
  360. cryptoadvance/specter/translations/el/LC_MESSAGES/messages.po +4376 -0
  361. cryptoadvance/specter/translations/es/LC_MESSAGES/messages.po +4396 -0
  362. cryptoadvance/specter/translations/fi/LC_MESSAGES/messages.po +4358 -0
  363. cryptoadvance/specter/translations/fr/LC_MESSAGES/messages.po +4414 -0
  364. cryptoadvance/specter/translations/he/LC_MESSAGES/messages.po +4361 -0
  365. cryptoadvance/specter/translations/hi/LC_MESSAGES/messages.po +4366 -0
  366. cryptoadvance/specter/translations/hr/LC_MESSAGES/messages.po +4361 -0
  367. cryptoadvance/specter/translations/is/LC_MESSAGES/messages.po +4361 -0
  368. cryptoadvance/specter/translations/it/LC_MESSAGES/messages.po +4361 -0
  369. cryptoadvance/specter/translations/ko/LC_MESSAGES/messages.po +4361 -0
  370. cryptoadvance/specter/translations/mal/LC_MESSAGES/messages.po +4358 -0
  371. cryptoadvance/specter/translations/nl/LC_MESSAGES/messages.po +4381 -0
  372. cryptoadvance/specter/translations/pl/LC_MESSAGES/messages.po +4376 -0
  373. cryptoadvance/specter/translations/pt/LC_MESSAGES/messages.po +4371 -0
  374. cryptoadvance/specter/translations/ru/LC_MESSAGES/messages.po +4373 -0
  375. cryptoadvance/specter/translations/sr/LC_MESSAGES/messages.po +4361 -0
  376. cryptoadvance/specter/translations/sv/LC_MESSAGES/messages.po +4377 -0
  377. cryptoadvance/specter/translations/ta/LC_MESSAGES/messages.po +4358 -0
  378. cryptoadvance/specter/translations/tr/LC_MESSAGES/messages.po +4361 -0
  379. cryptoadvance/specter/translations/zh_Hans_CN/LC_MESSAGES/messages.po +4379 -0
  380. cryptoadvance/specter/translations/zh_Hant_TW/LC_MESSAGES/messages.po +4380 -0
  381. cryptoadvance/specter/user.py +559 -0
  382. cryptoadvance/specter/util/__init__.py +0 -0
  383. cryptoadvance/specter/util/base43.py +58 -0
  384. cryptoadvance/specter/util/base58.py +52 -0
  385. cryptoadvance/specter/util/bcur.py +199 -0
  386. cryptoadvance/specter/util/bitcoind_setup_tasks.py +199 -0
  387. cryptoadvance/specter/util/checker.py +92 -0
  388. cryptoadvance/specter/util/common.py +139 -0
  389. cryptoadvance/specter/util/descriptor.py +504 -0
  390. cryptoadvance/specter/util/fee_estimation.py +188 -0
  391. cryptoadvance/specter/util/file_download.py +22 -0
  392. cryptoadvance/specter/util/flask.py +35 -0
  393. cryptoadvance/specter/util/json_rpc.py +41 -0
  394. cryptoadvance/specter/util/merkleblock.py +448 -0
  395. cryptoadvance/specter/util/migrations/__init__.py +0 -0
  396. cryptoadvance/specter/util/migrations/migration_0000.py +28 -0
  397. cryptoadvance/specter/util/migrations/migration_0001.py +129 -0
  398. cryptoadvance/specter/util/migrations/migration_0002.py +111 -0
  399. cryptoadvance/specter/util/mnemonic.py +89 -0
  400. cryptoadvance/specter/util/price_providers.py +195 -0
  401. cryptoadvance/specter/util/psbt.py +492 -0
  402. cryptoadvance/specter/util/reflection.py +268 -0
  403. cryptoadvance/specter/util/reflection_fs.py +70 -0
  404. cryptoadvance/specter/util/requests_tools.py +43 -0
  405. cryptoadvance/specter/util/rpcauth.py +55 -0
  406. cryptoadvance/specter/util/setup_states.py +18 -0
  407. cryptoadvance/specter/util/sha256sum.py +11 -0
  408. cryptoadvance/specter/util/shell.py +73 -0
  409. cryptoadvance/specter/util/specter_migrator.py +274 -0
  410. cryptoadvance/specter/util/tor.py +95 -0
  411. cryptoadvance/specter/util/tor_setup_tasks.py +68 -0
  412. cryptoadvance/specter/util/tx.py +103 -0
  413. cryptoadvance/specter/util/version.py +259 -0
  414. cryptoadvance/specter/util/wallet_importer.py +551 -0
  415. cryptoadvance/specter/util/xpub.py +18 -0
  416. cryptoadvance/specter/wallet/__init__.py +3 -0
  417. cryptoadvance/specter/wallet/abstract_wallet.py +25 -0
  418. cryptoadvance/specter/wallet/addresslist.py +282 -0
  419. cryptoadvance/specter/wallet/tx_fetcher.py +275 -0
  420. cryptoadvance/specter/wallet/txlist.py +685 -0
  421. cryptoadvance/specter/wallet/wallet.py +1940 -0
  422. cryptoadvance/specterext/devhelp/__init__.py +0 -0
  423. cryptoadvance/specterext/devhelp/config.py +13 -0
  424. cryptoadvance/specterext/devhelp/console.py +58 -0
  425. cryptoadvance/specterext/devhelp/controller.py +116 -0
  426. cryptoadvance/specterext/devhelp/devices/devhelpdevice.py +11 -0
  427. cryptoadvance/specterext/devhelp/service.py +63 -0
  428. cryptoadvance/specterext/devhelp/static/devhelp/css/styles.css +5 -0
  429. cryptoadvance/specterext/devhelp/static/devhelp/img/mydevice-logo.svg +80 -0
  430. cryptoadvance/specterext/devhelp/static/devhelp/img/orange-wrench.png +0 -0
  431. cryptoadvance/specterext/devhelp/templates/devhelp/base.jinja +5 -0
  432. cryptoadvance/specterext/devhelp/templates/devhelp/components/devhelp_menu.jinja +16 -0
  433. cryptoadvance/specterext/devhelp/templates/devhelp/components/devhelp_tab.jinja +8 -0
  434. cryptoadvance/specterext/devhelp/templates/devhelp/dev-console.jinja +114 -0
  435. cryptoadvance/specterext/devhelp/templates/devhelp/html/address-data.jinja +73 -0
  436. cryptoadvance/specterext/devhelp/templates/devhelp/html/address-label.jinja +52 -0
  437. cryptoadvance/specterext/devhelp/templates/devhelp/html/address-row.jinja +51 -0
  438. cryptoadvance/specterext/devhelp/templates/devhelp/html/fee-selection.jinja +43 -0
  439. cryptoadvance/specterext/devhelp/templates/devhelp/html/macro_total_wallet_balances.jinja +88 -0
  440. cryptoadvance/specterext/devhelp/templates/devhelp/html/notification-system.jinja +136 -0
  441. cryptoadvance/specterext/devhelp/templates/devhelp/html/tx-table.jinja +127 -0
  442. cryptoadvance/specterext/devhelp/templates/devhelp/html_inject_in_basejinja.jinja +17 -0
  443. cryptoadvance/specterext/devhelp/templates/devhelp/includes/set-address.html +20 -0
  444. cryptoadvance/specterext/devhelp/templates/devhelp/includes/set-wallet.html +11 -0
  445. cryptoadvance/specterext/devhelp/templates/devhelp/index.jinja +29 -0
  446. cryptoadvance/specterext/devhelp/templates/devhelp/settings.jinja +24 -0
  447. cryptoadvance/specterext/electrum/__init__.py +0 -0
  448. cryptoadvance/specterext/electrum/controller.py +33 -0
  449. cryptoadvance/specterext/electrum/devices/__init__.py +0 -0
  450. cryptoadvance/specterext/electrum/devices/electrum.py +21 -0
  451. cryptoadvance/specterext/electrum/service.py +28 -0
  452. cryptoadvance/specterext/electrum/static/electrum/img/devices/electrum_icon.svg +15 -0
  453. cryptoadvance/specterext/electrum/static/electrum/img/electrum_lightblue.svg +193 -0
  454. cryptoadvance/specterext/electrum/static/electrum/img/electrum_manual/1.png +0 -0
  455. cryptoadvance/specterext/electrum/static/electrum/img/electrum_manual/2.png +0 -0
  456. cryptoadvance/specterext/electrum/templates/electrum/device/new_device_keys_electrum.jinja +41 -0
  457. cryptoadvance/specterext/electrum/templates/electrum/index.jinja +17 -0
  458. cryptoadvance/specterext/notifications/__init__.py +0 -0
  459. cryptoadvance/specterext/notifications/config.py +25 -0
  460. cryptoadvance/specterext/notifications/controller.py +90 -0
  461. cryptoadvance/specterext/notifications/notification_manager.py +485 -0
  462. cryptoadvance/specterext/notifications/notifications.py +166 -0
  463. cryptoadvance/specterext/notifications/service.py +88 -0
  464. cryptoadvance/specterext/notifications/static/notifications/css/styles.css +105 -0
  465. cryptoadvance/specterext/notifications/static/notifications/img/notification.png +0 -0
  466. cryptoadvance/specterext/notifications/templates/notifications/base.jinja +4 -0
  467. cryptoadvance/specterext/notifications/templates/notifications/components/notifications_menu.jinja +16 -0
  468. cryptoadvance/specterext/notifications/templates/notifications/components/notifications_tab.jinja +8 -0
  469. cryptoadvance/specterext/notifications/templates/notifications/html_inject_in_basejinja.jinja +13 -0
  470. cryptoadvance/specterext/notifications/templates/notifications/index.jinja +88 -0
  471. cryptoadvance/specterext/notifications/templates/notifications/message_box.js +161 -0
  472. cryptoadvance/specterext/notifications/templates/notifications/notifications.js +396 -0
  473. cryptoadvance/specterext/notifications/templates/notifications/settings.jinja +98 -0
  474. cryptoadvance/specterext/notifications/ui_notifications.py +234 -0
  475. cryptoadvance/specterext/notifications/websockets_server_client.py +444 -0
  476. cryptoadvance/specterext/spectrum/__init__.py +0 -0
  477. cryptoadvance/specterext/spectrum/bridge_rpc.py +122 -0
  478. cryptoadvance/specterext/spectrum/config.py +99 -0
  479. cryptoadvance/specterext/spectrum/controller.py +192 -0
  480. cryptoadvance/specterext/spectrum/controller_helpers.py +83 -0
  481. cryptoadvance/specterext/spectrum/service.py +167 -0
  482. cryptoadvance/specterext/spectrum/spectrum_node.py +235 -0
  483. cryptoadvance/specterext/spectrum/static/spectrum/css/styles.css +1 -0
  484. cryptoadvance/specterext/spectrum/static/spectrum/img/electrum_lightblue.svg +193 -0
  485. cryptoadvance/specterext/spectrum/static/spectrum/img/ghost.png +0 -0
  486. cryptoadvance/specterext/spectrum/static/spectrum/img/logo.jpeg +0 -0
  487. cryptoadvance/specterext/spectrum/static/spectrum/img/logo.svg +20 -0
  488. cryptoadvance/specterext/spectrum/templates/spectrum/base.jinja +7 -0
  489. cryptoadvance/specterext/spectrum/templates/spectrum/components/spectrum_info.jinja +63 -0
  490. cryptoadvance/specterext/spectrum/templates/spectrum/components/spectrum_menu.jinja +15 -0
  491. cryptoadvance/specterext/spectrum/templates/spectrum/components/spectrum_no_tx_hint.jinja +7 -0
  492. cryptoadvance/specterext/spectrum/templates/spectrum/components/spectrum_node_connection.jinja +46 -0
  493. cryptoadvance/specterext/spectrum/templates/spectrum/components/spectrum_node_logo.jinja +1 -0
  494. cryptoadvance/specterext/spectrum/templates/spectrum/components/spectrum_tab.jinja +8 -0
  495. cryptoadvance/specterext/spectrum/templates/spectrum/index.jinja +123 -0
  496. cryptoadvance/specterext/spectrum/templates/spectrum/settings.jinja +19 -0
  497. cryptoadvance/specterext/spectrum/templates/spectrum/spectrum_setup.jinja +61 -0
  498. cryptoadvance/specterext/spectrum/templates/spectrum/spectrum_setup_beta.jinja +27 -0
  499. cryptoadvance/specterext/spectrum/templates/spectrum/spectrum_wallets.jinja +63 -0
  500. cryptoadvance/specterext/spectrum/templates/spectrum/welcome/components/get_started.jinja +15 -0
  501. cryptoadvance/specterext/spectrum/templates/spectrum/welcome/components/tick_checkboxes.jinja +89 -0
  502. cryptoadvance/specterext/swan/__init__.py +0 -0
  503. cryptoadvance/specterext/swan/client.py +478 -0
  504. cryptoadvance/specterext/swan/config.py +28 -0
  505. cryptoadvance/specterext/swan/controller.py +262 -0
  506. cryptoadvance/specterext/swan/service.py +465 -0
  507. cryptoadvance/specterext/swan/static/swan/img/swan_icon.svg +1 -0
  508. cryptoadvance/specterext/swan/static/swan/img/swan_logo.svg +2 -0
  509. cryptoadvance/specterext/swan/templates/swan/api_error.jinja +16 -0
  510. cryptoadvance/specterext/swan/templates/swan/components/base.jinja +1 -0
  511. cryptoadvance/specterext/swan/templates/swan/components/swan_menu.jinja +15 -0
  512. cryptoadvance/specterext/swan/templates/swan/components/swan_tab.jinja +8 -0
  513. cryptoadvance/specterext/swan/templates/swan/index.jinja +64 -0
  514. cryptoadvance/specterext/swan/templates/swan/oauth2_start.jinja +62 -0
  515. cryptoadvance/specterext/swan/templates/swan/oauth2_success.jinja +20 -0
  516. cryptoadvance/specterext/swan/templates/swan/settings.jinja +48 -0
  517. cryptoadvance/specterext/swan/templates/swan/withdrawals.jinja +46 -0
  518. cryptoadvance_specter-2.1.2.dist-info/LICENSE +21 -0
  519. cryptoadvance_specter-2.1.2.dist-info/METADATA +287 -0
  520. cryptoadvance_specter-2.1.2.dist-info/RECORD +523 -0
  521. cryptoadvance_specter-2.1.2.dist-info/WHEEL +5 -0
  522. cryptoadvance_specter-2.1.2.dist-info/entry_points.txt +2 -0
  523. cryptoadvance_specter-2.1.2.dist-info/top_level.txt +1 -0
File without changes
@@ -0,0 +1,7 @@
1
+ from logging.config import dictConfig
2
+ from .cli import entry_point
3
+ import logging
4
+
5
+ if __name__ == "__main__":
6
+
7
+ entry_point()
@@ -0,0 +1,34 @@
1
+ # file generated by setuptools-scm
2
+ # don't change, don't track in version control
3
+
4
+ __all__ = [
5
+ "__version__",
6
+ "__version_tuple__",
7
+ "version",
8
+ "version_tuple",
9
+ "__commit_id__",
10
+ "commit_id",
11
+ ]
12
+
13
+ TYPE_CHECKING = False
14
+ if TYPE_CHECKING:
15
+ from typing import Tuple
16
+ from typing import Union
17
+
18
+ VERSION_TUPLE = Tuple[Union[int, str], ...]
19
+ COMMIT_ID = Union[str, None]
20
+ else:
21
+ VERSION_TUPLE = object
22
+ COMMIT_ID = object
23
+
24
+ version: str
25
+ __version__: str
26
+ __version_tuple__: VERSION_TUPLE
27
+ version_tuple: VERSION_TUPLE
28
+ commit_id: COMMIT_ID
29
+ __commit_id__: COMMIT_ID
30
+
31
+ __version__ = version = '2.1.2'
32
+ __version_tuple__ = version_tuple = (2, 1, 2)
33
+
34
+ __commit_id__ = commit_id = None
@@ -0,0 +1,18 @@
1
+ """ API Blueprint Application """
2
+
3
+ import os
4
+ from flask import Flask, Blueprint, session
5
+ from flask_restful import Api
6
+ from flask_httpauth import HTTPBasicAuth, HTTPTokenAuth
7
+ from flask import current_app as app
8
+
9
+ api_bp = Blueprint("api_bp", __name__, template_folder="templates", url_prefix="/api")
10
+
11
+ api_rest = Api(api_bp, decorators=[app.csrf.exempt])
12
+
13
+ auth = HTTPBasicAuth()
14
+
15
+ token_auth = HTTPTokenAuth()
16
+
17
+ from . import views
18
+ from .rest import api
File without changes
@@ -0,0 +1,83 @@
1
+ import logging
2
+ import json
3
+
4
+ import cryptoadvance.specter as specter
5
+ from ...wallet import Wallet
6
+ from .base import (
7
+ SecureResource,
8
+ rest_resource,
9
+ )
10
+ from ..security import require_admin, verify_password
11
+ from flask_restful import abort
12
+ from flask import current_app as app
13
+ from datetime import datetime
14
+ from ...specter_error import SpecterError
15
+
16
+ from ...util.fee_estimation import get_fees
17
+
18
+ from .. import token_auth
19
+ from .resource_jwt import JWTResource, JWTResourceById
20
+ from .resource_healthz import ResourceLiveness, ResourceReadyness
21
+ from .resource_psbt import ResourcePsbt
22
+ from .resource_specter import ResourceSpecter
23
+ from .resource_txlist import ResourceTXlist
24
+
25
+ logger = logging.getLogger(__name__)
26
+
27
+
28
+ @rest_resource
29
+ class ResourceWallet(SecureResource):
30
+
31
+ endpoints = ["/v1alpha/wallets/<wallet_alias>/"]
32
+
33
+ def get(self, wallet_alias):
34
+ user = token_auth.current_user()
35
+ try:
36
+ wallet: Wallet = app.specter.user_manager.get_user(
37
+ user
38
+ ).wallet_manager.get_by_alias(wallet_alias)
39
+ except SpecterError as se:
40
+ logger.error(se)
41
+ if str(se).startswith(f"Wallet {wallet_alias} does not exist!"):
42
+ return abort(403, message=f"Wallet {wallet_alias} does not exist")
43
+ logger.error(se)
44
+ return abort(500)
45
+
46
+ wallet.update_balance()
47
+ wallet.check_utxo()
48
+ wallet.check_unused()
49
+
50
+ return_dict = {}
51
+ address_index = wallet.address_index
52
+ validate_merkle_proofs = app.specter.config.get("validate_merkle_proofs")
53
+ tx_list = []
54
+ idx = 0
55
+ tx_len = 1
56
+ transactions = app.specter.wallet_manager.full_txlist(
57
+ fetch_transactions=False, validate_merkle_proofs=validate_merkle_proofs
58
+ )
59
+ tx_list.append(transactions)
60
+
61
+ # Flatten the list
62
+ flat_list = []
63
+ for element in tx_list:
64
+ for dic_item in element:
65
+ flat_list.append(dic_item)
66
+
67
+ # Check if scanning
68
+ scan = wallet.rescan_progress
69
+ return_dict[wallet_alias] = wallet.__dict__
70
+ return_dict["txlist"] = flat_list
71
+ return_dict["scan"] = scan
72
+ return_dict["address_index"] = address_index
73
+ return_dict["utxo"] = wallet.utxo
74
+
75
+ # Serialize only objects that are json compatible
76
+ # This will exclude classes and methods
77
+ def safe_serialize(obj):
78
+ def default(o):
79
+ return f"{type(o).__qualname__}"
80
+
81
+ return json.dumps(obj, default=default)
82
+
83
+ return json.loads(safe_serialize(return_dict))
@@ -0,0 +1,92 @@
1
+ """ API Backend - Base Resource Models """
2
+
3
+ from functools import wraps
4
+ import logging
5
+ import re
6
+ from flask_restful import Resource, abort
7
+
8
+ from cryptoadvance.specter.api import api_rest
9
+ from cryptoadvance.specter.api.security import require_admin
10
+ from cryptoadvance.specter.api import auth, token_auth
11
+ from cryptoadvance.specter.specter_error import SpecterError
12
+
13
+ logger = logging.getLogger(__name__)
14
+
15
+
16
+ def error_handling(func):
17
+ """User needs Admin-rights method decorator"""
18
+
19
+ @wraps(func)
20
+ def wrapper(*args, **kwargs):
21
+ """wrapping the whole error-handling around methods"""
22
+ try:
23
+ return func(*args, **kwargs)
24
+ except SpecterError as se:
25
+ logger.error(se)
26
+ # Not that elegant as this function is accumulating all the error-handling for different
27
+ # endpoints. On the other hand, this is probabyl more tied to different SpecterErrors
28
+ # rather than the implementation of a rest-endpoint.
29
+ match = re.match("Wallet (.+) does not exist!", str(se))
30
+ if match:
31
+ return abort(403, message=f"Wallet {match.group(1)} does not exist")
32
+ if str(se).endswith(
33
+ "does not have sufficient funds to make the transaction."
34
+ ):
35
+ return abort(
36
+ 412,
37
+ message=f"Wallet does not have sufficient funds to make the transaction.",
38
+ )
39
+ return abort(500)
40
+ except Exception as e:
41
+ logger.error("Unexpected Exception in Rest-Request:")
42
+ logger.exception(e)
43
+ return abort(
44
+ 500,
45
+ message="Can't tell you the reason of the issue. Please check the logs",
46
+ )
47
+
48
+ return wrapper
49
+
50
+
51
+ class BaseResource(Resource):
52
+ """A baseClass for rsources which returns Method not allowed by default"""
53
+
54
+ method_decorators = [error_handling]
55
+
56
+ def get(self, *args, **kwargs):
57
+ abort(405)
58
+
59
+ def post(self, *args, **kwargs):
60
+ abort(405)
61
+
62
+ def put(self, *args, **kwargs):
63
+ abort(405)
64
+
65
+ def patch(self, *args, **kwargs):
66
+ abort(405)
67
+
68
+ def delete(self, *args, **kwargs):
69
+ abort(405)
70
+
71
+
72
+ class SecureResource(BaseResource):
73
+ """A REST-resource which makes sure that the user is Authenticated"""
74
+
75
+ method_decorators = [error_handling, token_auth.login_required]
76
+
77
+
78
+ class BasicAuthResource(BaseResource):
79
+ """A REST-resource which makes sure that the user is Authenticated"""
80
+
81
+ method_decorators = [error_handling, auth.login_required]
82
+
83
+
84
+ class AdminResource(BaseResource):
85
+ """A REST-resource which makes sure that the user is an admin"""
86
+
87
+ method_decorators = [error_handling, require_admin, token_auth.login_required]
88
+
89
+
90
+ def rest_resource(resource_cls):
91
+ """Decorator for adding resources to Api App"""
92
+ api_rest.add_resource(resource_cls, *resource_cls.endpoints)
@@ -0,0 +1,42 @@
1
+ """
2
+ liveness and readiness probes are a semi-standard way of health-checking.
3
+ See e.g. here:
4
+ https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes/
5
+ """
6
+ import json
7
+ import logging
8
+ from os import abort
9
+
10
+ from cryptoadvance.specter.api.rest.base import BaseResource, rest_resource
11
+ from flask import current_app as app
12
+
13
+ logger = logging.getLogger(__name__)
14
+
15
+
16
+ @rest_resource
17
+ class ResourceLiveness(BaseResource):
18
+ """/api/healthz/liveness
19
+ Whether the app is up and running although it might not have connection to DB/nodes etc.
20
+ """
21
+
22
+ endpoints = ["/healthz/liveness"]
23
+
24
+ def get(self):
25
+ return {"message": "i am alive"}
26
+
27
+
28
+ @rest_resource
29
+ class ResourceReadyness(BaseResource):
30
+ """/api/healthz/readyness
31
+ Whether the app is up and running AND ALL its dependent services (in our case nodes) are properly functioning as well.
32
+ """
33
+
34
+ endpoints = ["/healthz/readyness"]
35
+
36
+ def get(self):
37
+ try:
38
+ # Not sure whether that's enough. Probably improvable:
39
+ app.specter.check()
40
+ except Exception as e:
41
+ abort(500, message="Readyness probe failed")
42
+ return {"message": "i am ready"}
@@ -0,0 +1,135 @@
1
+ import jwt
2
+ from flask import current_app as app
3
+ from flask_restful import Api, abort, reqparse
4
+ from cryptoadvance.specter.api.rest.base import (
5
+ BaseResource,
6
+ BasicAuthResource,
7
+ SecureResource,
8
+ rest_resource,
9
+ AdminResource,
10
+ )
11
+ import uuid
12
+ import datetime
13
+ import logging
14
+ from ...user import *
15
+ from .base import *
16
+ from pytimeparse import parse
17
+
18
+ from .. import auth
19
+
20
+ logger = logging.getLogger(__name__)
21
+
22
+ # Initialize the parser
23
+ parser = reqparse.RequestParser()
24
+ parser.add_argument(
25
+ "jwt_token_description", type=str, help="JWT token description", required=True
26
+ )
27
+ parser.add_argument("jwt_token_life", type=str, help="JWT token life", required=True)
28
+
29
+
30
+ @rest_resource
31
+ class JWTResource(BasicAuthResource):
32
+ """
33
+ A Resource to manage JWT tokens in order to authenticate against the REST-API
34
+ Other then the other Resources, this endpoint uses BasicAuth to avoid the chicken egg problem
35
+ This one is only to create a token. The other Resource for getting and deleting.
36
+ This violates the REST principles but only on the implementation-side. Happy for improvements here.
37
+ """
38
+
39
+ endpoints = ["/v1alpha/token/"]
40
+
41
+ def get(self):
42
+ # An endpoint to get all JWT tokens' information created by the user
43
+ user = auth.current_user()
44
+ user_details = app.specter.user_manager.get_user(user)
45
+ jwt_tokens = user_details.get_all_jwt_tokens_info()
46
+ if len(jwt_tokens) == 0:
47
+ return {"message": "Tokens does not exist"}, 404
48
+ return {"message": "Tokens exist", "jwt_tokens": jwt_tokens}, 200
49
+
50
+ def post(self):
51
+ # An endpoint to create a JWT token
52
+ user = auth.current_user()
53
+ data = parser.parse_args()
54
+ user_details = app.specter.user_manager.get_user(user)
55
+ jwt_token_id = user_details.generate_token_id()
56
+ jwt_token_description = data["jwt_token_description"]
57
+
58
+ # pytimeparse has been used to parse different time units to seconds
59
+ # For eg: "jwt_token_life_unit": "1 hour" will be parsed to 3600 seconds
60
+ # For more information visit: https://pypi.org/project/pytimeparse/
61
+ jwt_token_life = parse(data["jwt_token_life"])
62
+ jwt_token = user_details.generate_jwt_token(
63
+ user_details.username,
64
+ jwt_token_id,
65
+ jwt_token_description,
66
+ jwt_token_life,
67
+ )
68
+ if user_details.validate_jwt_token_description(jwt_token_description):
69
+ user_details.add_jwt_token(
70
+ jwt_token_id,
71
+ jwt_token,
72
+ jwt_token_description,
73
+ jwt_token_life,
74
+ )
75
+ return {
76
+ "message": "Token generated",
77
+ "jwt_token_id": jwt_token_id,
78
+ "jwt_token": jwt_token,
79
+ "jwt_token_description": jwt_token_description,
80
+ "jwt_token_life": jwt_token_life,
81
+ }, 201
82
+ else:
83
+ return {"message": "Token description already exists or is blank"}, 400
84
+
85
+
86
+ @rest_resource
87
+ class JWTResourceById(BasicAuthResource):
88
+ """
89
+ A Resource to manage individual JWT token
90
+ """
91
+
92
+ endpoints = ["/v1alpha/token/<jwt_token_id>/"]
93
+
94
+ def get(self, jwt_token_id):
95
+ # An endpoint to get a JWT token by id
96
+ user = auth.current_user()
97
+ user_details = app.specter.user_manager.get_user(user)
98
+ jwt_tokens = user_details.jwt_tokens
99
+ jwt_token = user_details.get_jwt_token(jwt_token_id)
100
+ jwt_token_life_remaining = user_details.jwt_token_life_remaining(jwt_token_id)
101
+ expiry_status = f"Valid"
102
+ if jwt_token_life_remaining == 0:
103
+ expiry_status = f"Expired"
104
+ if (
105
+ not user_details.verify_jwt_token_id_and_jwt_token(jwt_token_id, jwt_token)
106
+ and jwt_tokens[jwt_token_id] is None
107
+ ):
108
+ return {
109
+ "message": "Token does not exist, make sure to enter correct token id"
110
+ }, 404
111
+ return {
112
+ "message": "Token exists",
113
+ "jwt_token_description": jwt_token["jwt_token_description"],
114
+ "jwt_token_life": jwt_token["jwt_token_life"],
115
+ "jwt_token_life_remaining": jwt_token_life_remaining,
116
+ "expiry_status": expiry_status,
117
+ }, 200
118
+
119
+ def delete(self, jwt_token_id):
120
+ # An endpoint to delete a JWT token by id
121
+ user = auth.current_user()
122
+ user_details = app.specter.user_manager.get_user(user)
123
+ jwt_tokens = user_details.jwt_tokens
124
+ jwt_token = user_details.get_jwt_token(jwt_token_id)
125
+
126
+ if (
127
+ not user_details.verify_jwt_token_id_and_jwt_token(jwt_token_id, jwt_token)
128
+ and jwt_tokens[jwt_token_id] is None
129
+ ):
130
+ return {
131
+ "message": "Token does not exist, make sure to enter correct token id"
132
+ }, 404
133
+
134
+ user_details.delete_jwt_token(jwt_token_id)
135
+ return {"message": "Token deleted"}, 200
@@ -0,0 +1,53 @@
1
+ import logging
2
+ import base64
3
+ from json import dumps
4
+
5
+ from .base import (
6
+ SecureResource,
7
+ rest_resource,
8
+ )
9
+
10
+ from flask import current_app as app, request, Response
11
+ from ...wallet import Wallet
12
+ from ...commands.psbt_creator import PsbtCreator
13
+ from ...specter_error import SpecterError
14
+ from .. import token_auth
15
+
16
+ logger = logging.getLogger(__name__)
17
+
18
+
19
+ @rest_resource
20
+ class ResourcePsbt(SecureResource):
21
+ """/api/v1alpha/specter"""
22
+
23
+ endpoints = ["/v1alpha/wallets/<wallet_alias>/psbt"]
24
+
25
+ def get(self, wallet_alias):
26
+ user = token_auth.current_user()
27
+ wallet_manager = app.specter.user_manager.get_user(user).wallet_manager
28
+ # Check that the wallet belongs to the user from Basic Auth
29
+ try:
30
+ wallet = wallet_manager.get_by_alias(wallet_alias)
31
+ except SpecterError as se:
32
+ # ToDo: Be more specific here. How do we know that this SpecterError is a fit to that message?
33
+ logger.warning(
34
+ f"User user {user} denied access to {wallet_alias} because of {se}"
35
+ )
36
+ error_message = dumps(
37
+ {"message": "The wallet does not belong to the user in the request."}
38
+ )
39
+ return Response(error_message, 403)
40
+ pending_psbts = wallet.pending_psbts_dict()
41
+ return {"result": pending_psbts or {}}
42
+
43
+ def post(self, wallet_alias):
44
+ user = token_auth.current_user()
45
+ wallet: Wallet = app.specter.user_manager.get_user(
46
+ user
47
+ ).wallet_manager.get_by_alias(wallet_alias)
48
+ logger.debug(f"Got a post request for creating a psbt: {request.json}")
49
+ psbt_creator = PsbtCreator(
50
+ app.specter, wallet, "json", request_json=request.json
51
+ )
52
+ psbt = psbt_creator.create_psbt(wallet)
53
+ return {"result": psbt}
@@ -0,0 +1,46 @@
1
+ import logging
2
+
3
+ from cryptoadvance.specter.api.rest.base import (
4
+ AdminResource,
5
+ rest_resource,
6
+ )
7
+ from flask import current_app as app
8
+ from datetime import datetime
9
+
10
+ logger = logging.getLogger(__name__)
11
+
12
+
13
+ @rest_resource
14
+ class ResourceSpecter(AdminResource):
15
+ """/api/v1alpha/specter"""
16
+
17
+ endpoints = ["/v1alpha/specter"]
18
+
19
+ def get(self):
20
+ specter_data = app.specter
21
+
22
+ return_dict = {
23
+ "data_folder": specter_data.data_folder,
24
+ "config": specter_data.config,
25
+ "info": specter_data.info,
26
+ "network_info": specter_data.network_info,
27
+ "device_manager_datafolder": specter_data.device_manager.data_folder,
28
+ "devices_names": specter_data.device_manager.devices_names,
29
+ "wallets_names": specter_data.wallet_manager.wallets_names,
30
+ "last_update": datetime.now().strftime("%m/%d/%Y, %H:%M:%S"),
31
+ }
32
+
33
+ # Include alias list for easy lookup between names and alias
34
+ # Maybe there's a better way to create this
35
+ wallets_alias = []
36
+ alias_name = {}
37
+ name_alias = {}
38
+ for wallet in return_dict["wallets_names"]:
39
+ alias = specter_data.wallet_manager.wallets[wallet].alias
40
+ wallets_alias.append(alias)
41
+ alias_name[alias] = wallet
42
+ name_alias[wallet] = alias
43
+ return_dict["alias_name"] = alias_name
44
+ return_dict["name_alias"] = name_alias
45
+ return_dict["wallets_alias"] = wallets_alias
46
+ return return_dict
@@ -0,0 +1,34 @@
1
+ import json
2
+ import logging
3
+
4
+ from cryptoadvance.specter.api.rest.base import AdminResource, rest_resource
5
+ from flask import current_app as app
6
+
7
+ from .. import token_auth
8
+
9
+ logger = logging.getLogger(__name__)
10
+
11
+
12
+ @rest_resource
13
+ class ResourceTXlist(AdminResource):
14
+ """/api/v1alpha/full_txlist"""
15
+
16
+ endpoints = ["/v1alpha/specter/full_txlist/"]
17
+
18
+ def get(self):
19
+ user = token_auth.current_user()
20
+ wallet_manager = app.specter.user_manager.get_user(user).wallet_manager
21
+ validate_merkle_proofs = app.specter.config.get("validate_merkle_proofs")
22
+ idx = 0
23
+ tx_len = 1
24
+ tx_list = []
25
+ transactions = wallet_manager.full_txlist(
26
+ fetch_transactions=False, validate_merkle_proofs=validate_merkle_proofs
27
+ )
28
+ tx_list.append(transactions)
29
+ # Flatten the list
30
+ flat_list = []
31
+ for element in tx_list:
32
+ for dic_item in element:
33
+ flat_list.append(dic_item)
34
+ return flat_list
@@ -0,0 +1,73 @@
1
+ """ Security Related things for the REST-API """
2
+ import logging, jwt
3
+ from functools import wraps
4
+
5
+ from cryptoadvance.specter.user import User, verify_password as user_verify_password
6
+ from flask import current_app as app
7
+ from flask import g
8
+ from flask_restful import abort
9
+ from . import auth, token_auth
10
+ from ..user import *
11
+ from . import auth
12
+ from flask import current_app as app
13
+
14
+ logger = logging.getLogger(__name__)
15
+
16
+
17
+ @auth.verify_password
18
+ def verify_password(username, password):
19
+ """Validate user passwords and store user in the 'g' object"""
20
+ if not username or not password:
21
+ return abort(401)
22
+ the_user = app.specter.user_manager.get_user_by_username(username)
23
+ if not the_user:
24
+ return abort(401)
25
+ g.user = app.specter.user_manager.get_user_by_username(username)
26
+ if user_verify_password(g.user.password_hash, password):
27
+ logger.info(f"Rest-Request for user {username} PASSED password-test")
28
+ return username
29
+ else:
30
+ logger.info(f"Rest-Request for user {username} FAILED password-test")
31
+ return abort(401)
32
+
33
+ return g.user is not None and verify_password(g.user.password_hash, password)
34
+
35
+
36
+ @token_auth.verify_token
37
+ def verify_token(jwt_token):
38
+ """Validate JWT token and store user in the 'g' object"""
39
+ if not jwt_token:
40
+ return abort(401)
41
+ try:
42
+ payload = jwt.decode(jwt_token, app.config["SECRET_KEY"], algorithms=["HS256"])
43
+ username = payload["username"]
44
+ the_user = app.specter.user_manager.get_user_by_username(username)
45
+ if not the_user:
46
+ return abort(401)
47
+ g.user = app.specter.user_manager.get_user_by_username(username)
48
+ logger.info({"payload": payload})
49
+ logger.info(f"Rest-Request for user {username} PASSED JWT-test")
50
+ return username
51
+ except jwt.ExpiredSignatureError:
52
+ logger.info(f"Token expired. Please create a new one")
53
+ return abort(401)
54
+ except jwt.InvalidTokenError:
55
+ logger.info(f"Invalid token. Please create a new one")
56
+ return abort(401)
57
+
58
+
59
+ def require_admin(func):
60
+ """User needs Admin-rights method decorator"""
61
+
62
+ @wraps(func)
63
+ def wrapper(*args, **kwargs):
64
+ """this needs to get implemented properly"""
65
+ # Verify if User is Admin
66
+ if g.user == None:
67
+ return abort(401)
68
+ if g.user.is_admin:
69
+ return func(*args, **kwargs)
70
+ else:
71
+ return abort(401)
72
+
73
+ return wrapper
@@ -0,0 +1,18 @@
1
+ <html>
2
+
3
+ <body>
4
+ The documentation for the API FOR THE MASTER BRANCH can be found here:
5
+ <a href="https://github.com/cryptoadvance/specter-desktop/blob/master/docs/api/README.md">https://github.com/cryptoadvance/specter-desktop/blob/master/docs/api/api.md</a>
6
+
7
+ <br><br>
8
+ Make sure to choose the right version for the version you're currently using: {{version}}
9
+
10
+ <br><br>
11
+ {% if version != "custom" %}
12
+ So assuming that, please use this url:
13
+ <a href="https://github.com/cryptoadvance/specter-desktop/blob/v{{version}}/docs/api/README.md">https://github.com/cryptoadvance/specter-desktop/blob/v{{version}}/docs/api/api.md</a>
14
+ {% endif %}
15
+
16
+ </body>
17
+
18
+ </html>
@@ -0,0 +1,11 @@
1
+ from flask import render_template
2
+ from cryptoadvance.specter.api import api_bp
3
+ from flask import current_app as app
4
+
5
+
6
+ @api_bp.route("/")
7
+ def api():
8
+ """rendering the documentation for the api"""
9
+ return render_template(
10
+ "api.html", version=app.specter.version._get_current_version()
11
+ )