Compare commits

..

729 Commits

Author SHA1 Message Date
9d1cd085ea ad psbt base64 file upload test 2020-07-14 09:52:17 +02:00
311972c39f Update changelog 2020-07-14 16:43:48 +09:00
72d4fa6cd0 Merge pull request #1740 from btcpayserver/psbt-decode
streamline decode of uploaded psbt file + fix action button alginment
2020-07-14 16:43:19 +09:00
016bf1d671 add download psbt action 2020-07-14 09:36:58 +02:00
406b06a0be Update changelog 2020-07-14 16:31:01 +09:00
24439f1dc2 Merge pull request #1737 from btcpayserver/payjoin-hw-fix
Fix Payjoin HWW signing
2020-07-14 16:29:11 +09:00
15df2dfb0c Merge pull request #1735 from btcpayserver/2fa-config-screen
Fix 2FA config screens
2020-07-14 16:27:09 +09:00
d393cee732 streamline decode of uploaded psbt file + fix action button alginment 2020-07-14 09:18:40 +02:00
4c175ca340 bump version 2020-07-14 16:05:07 +09:00
5ed21fd740 Update lang 2020-07-14 16:04:58 +09:00
88af6c441f Can refund invalid invoices 2020-07-14 15:42:37 +09:00
eb14635a53 broadcast hww payjopin immediately 2020-07-13 15:02:51 +02:00
37b065ce6a Merge pull request #1736 from btcpayserver/basic-auth-fix
fail auth on incorrect basic auth value
2020-07-13 18:03:26 +09:00
dd0f8faf79 Merge pull request #1707 from Kukks/corsapi
Enable CORS and fix small doc error
2020-07-13 18:01:43 +09:00
006ebf3f15 Fix 2FA config screens 2020-07-13 10:58:53 +02:00
572c7ebbd8 Fix Payjoin HWW signing
fixes #1557
2020-07-13 10:54:39 +02:00
b728cd61ae Merge pull request #1716 from arc3x/pull-payment-view-filter-fix
Fix: Filter payouts by PullPaymentDataId when fetching transactions for a specific pull payment
2020-07-13 17:40:55 +09:00
04f71155b0 Merge pull request #1721 from dennisreimann/ui-updates-account
UI updates: Account section
2020-07-13 17:39:35 +09:00
e45c5ae71e Merge pull request #1724 from bolatovumar/fix-1723
Widen destination address field and make it monospace
2020-07-13 17:39:09 +09:00
632911d28c Merge pull request #1727 from dennisreimann/ui-updates-server
UI updates: Server settings section
2020-07-13 17:38:33 +09:00
5fb72513a0 Merge pull request #1733 from bolatovumar/fix-1732
Improve "Pull payments" table look
2020-07-13 17:37:59 +09:00
4b392ad70a fail auth on incorrect basic auth value
fixes #1713
2020-07-13 08:35:13 +02:00
42f6fbb4e5 Merge pull request #1504 from Argoneum/argoneum
Add Argoneum
2020-07-13 15:00:44 +09:00
afce1682a6 Replace pull payments body copy with a tooltip docs link 2020-07-12 12:45:30 -07:00
9f7af1c7d3 Replace | with - in pull payments table actions column 2020-07-12 12:37:36 -07:00
ca1355f80c Right-align "Actions" column in pull payments table 2020-07-12 12:35:11 -07:00
0d2f35c22f Merge pull request #1731 from btcpayserver/fix/json-indent
Modifying launchSettings.json to follow 2 space indent convention
2020-07-12 07:50:51 -05:00
6c71949888 Improve "Pull payments" table look
fix #1732
2020-07-11 21:03:46 -07:00
91e06d0858 Modifying launchSettings.json to follow 2 space indent convention 2020-07-11 16:45:44 -05:00
fe776edc9e Updating dev LND to 0.10.2-beta 2020-07-11 16:31:38 -05:00
8a7825f3bd Improve service settings view 2020-07-09 17:22:28 +02:00
3f23531f20 Improve email settings view 2020-07-09 17:22:22 +02:00
29d95a53a3 Improve users list view 2020-07-09 17:22:06 +02:00
718835255f Improve spacing for status messages 2020-07-09 17:21:29 +02:00
ca1f910d55 Improve maintenance view 2020-07-09 17:20:43 +02:00
0e410af63f Fix spacing for subnavs on mobile 2020-07-09 17:20:08 +02:00
0bbe095f6f General table style improvements 2020-07-09 17:19:25 +02:00
8b1a457312 Widen destination address field and make it monospace
fix #1723
2020-07-08 19:58:57 -07:00
7a46b2fd1b Improve user profile view 2020-07-08 19:20:32 +02:00
bfd25b8a14 Improve API keys list view 2020-07-08 19:20:24 +02:00
dae8163846 Improve change password view 2020-07-08 19:20:11 +02:00
4db6c16068 Improve U2F view 2020-07-08 19:19:55 +02:00
906ecc021b Improve 2FA views 2020-07-08 19:19:29 +02:00
8fc593a73e Improve secondary login view 2020-07-08 19:18:40 +02:00
f8e3b62edf Improve spacing for ordered lists and status messages 2020-07-08 19:18:04 +02:00
3051724ad8 Add Argoneum 2020-07-07 07:44:45 +03:00
b82abb066d Fix typo 2020-07-07 07:43:33 +03:00
ccfb97612e forwarded filter for PullPaymentDataId in GetPayoutInPeriod 2020-07-06 15:49:39 -07:00
6bf3dd96fb Merge pull request #1 from btcpayserver/master
upstream pull
2020-07-01 11:36:58 -07:00
f1e8b4b6e6 fix json 2020-06-30 08:54:57 +02:00
82af723f1f Enable CORS and fix small doc error 2020-06-30 08:26:19 +02:00
aeb90a3674 Merge pull request #1706 from dennisreimann/store-lightning
Improve information structure on Lightning page
2020-06-30 11:06:07 +09:00
64ab8e3fbe Merge pull request #1704 from btcpayserver/fix/code-cleanup-1
Code cleanup
2020-06-30 11:04:49 +09:00
f7474340cd Update BTCPayServer/Views/Stores/AddLightningNode.cshtml
Co-authored-by: Andrew Camilleri <evilkukka@gmail.com>
2020-06-29 22:38:50 +02:00
04acbf6509 Improve information structure on Lightning page 2020-06-29 16:54:07 +02:00
f88c02cccd Removing unused usings, readonly fields where possible 2020-06-28 22:07:48 -05:00
be5e0ea3fd Adding editorconfig reference 2020-06-28 21:48:10 -05:00
b6c7af32de Cleaning up bom from cs files 2020-06-28 21:44:35 -05:00
29294318d0 Specifying utf-8 as default charset for all files 2020-06-28 21:44:09 -05:00
d3325f17c5 Add missing file 2020-06-28 18:00:51 +09:00
51514252b6 Run dotnet format 2020-06-28 17:55:27 +09:00
18abc4913b Move hosting classes in right folder 2020-06-28 17:49:23 +09:00
d2958e1a7d Move extensions methods in specific classes 2020-06-28 17:16:53 +09:00
be44c3f9c2 Isolate OnModelCreating in Data classes (#1702) 2020-06-27 21:55:16 +09:00
72e407b69d Typos in PullPayments.cshtml (#1699)
Fixes typos in Pull Payments UI text.

No related issue, standalone PR.
2020-06-27 12:01:19 +02:00
66b9d0739b Set noindex, nofollow to ViewPullPayment.cshtml (#1700) 2020-06-27 12:00:10 +02:00
3e717ecdbc Set noindex, nofollow to ViewPaymentRequest.cshtml (#1701) 2020-06-27 11:58:55 +02:00
91720a0f34 Add changelog 2020-06-27 15:43:10 +09:00
9d531a385d bump 2020-06-27 15:39:58 +09:00
26137200b9 Do not use Onion-Location for custom domains (Fix #1693) 2020-06-27 15:39:02 +09:00
376b5fc160 Fix warning message when using SQLite (Fix #1695) 2020-06-27 15:35:32 +09:00
dbb2924ccc Fix: Create store could be called with a scoped store's modify apikey (#1696) 2020-06-27 15:34:03 +09:00
d0188f42b7 Fix crowdfound on root 2020-06-27 15:33:34 +09:00
6208706d46 Better error message if permission missing 2020-06-27 14:05:56 +09:00
3288264ca0 Add changelog 2020-06-27 12:23:27 +09:00
16f2ddddf0 Fix Point of Sale with custom domains 2020-06-27 12:21:19 +09:00
783185d99c Fix Point of Sale with custom domains 2020-06-27 12:13:17 +09:00
4ca83de131 changelog (#1669)
* changelog

* Update Changelog.md

Co-authored-by: Dennis Reimann <mail@dennisreimann.de>

* Update Changelog.md

* Update Changelog.md

* Update Changelog.md

* Update Changelog.md

* Update Changelog.md

* Update Changelog.md

* Update Changelog.md

* Update Changelog.md

* Apply suggestions from code review

Co-authored-by: Pavlenex <pavlenex@btcpayserver.org>

Co-authored-by: Dennis Reimann <mail@dennisreimann.de>
Co-authored-by: Pavlenex <pavlenex@btcpayserver.org>
2020-06-26 23:07:35 +09:00
f2b986a357 Remove warnings 2020-06-26 20:52:59 +09:00
a0065bc2ba catch cancled task exception in notif 2020-06-26 11:54:18 +02:00
dc43b54892 bump version 2020-06-26 17:09:00 +09:00
603a3dd273 bump NBitcoin 2020-06-26 16:29:40 +09:00
16b5f70e4b Fix permission on store's lightning server 2020-06-26 16:20:34 +09:00
9a989b46cc add supporter 2020-06-26 07:12:22 +02:00
6c64e7c220 Update fi-FI language 2020-06-25 18:03:33 +09:00
d66325a241 fix coin parser for weird networks 2020-06-25 10:51:27 +02:00
bf8190d122 bump nbx docker 2020-06-25 10:33:05 +02:00
23aec25686 Merge pull request #1685 from dennisreimann/broken-links
Check and fix broken anchor links.
2020-06-25 17:25:43 +09:00
405c0c609f Merge pull request #1691 from Eskyee/patch-9
remove unnecessary whitespace
2020-06-25 17:22:15 +09:00
95e0f3378d Merge pull request #1690 from btcpayserver/consolidatetables
Consolidate tables before release
2020-06-25 17:17:57 +09:00
c9850a5e24 remove unnecessary whitespace
cleaning up the unnecessary white space.
2020-06-25 08:33:34 +01:00
3cf7d01f37 Merge pull request #1688 from Kukks/fix-coin-parser
fix ypub/zpub parsing for all alts
2020-06-25 15:45:02 +09:00
ae9fae1f7d Consolidate tables before release 2020-06-25 15:43:45 +09:00
69b423edc8 Merge pull request #1689 from btcpayserver/invoicerefund
Implement invoice refund
2020-06-25 15:32:17 +09:00
5e8b379c50 Add invoice refund 2020-06-25 15:31:46 +09:00
d03124dfba Add an approval state to pull payments 2020-06-25 13:35:10 +09:00
fdc11bba8d Remove old unused refund table 2020-06-25 13:34:25 +09:00
dc5d8a6cb7 Refresh UI notifications automatically on update (#1680)
* Refresh UI notifications automatically on update

* make notif timeago live

* pass cancellation token

* Update InvoiceEventData.cs
2020-06-24 10:23:16 +02:00
2042f59283 fix ypub/zpub parsing for all alts
@gruve-p reported that ypub import was not working and then found this. no ypub/zpub import for any alts worked before lol
2020-06-24 10:18:45 +02:00
8230a408ac Add pull payment feature (#1639) 2020-06-24 10:34:09 +09:00
7805e5cea4 Fix version byte for zpub (#1686) 2020-06-24 10:19:50 +09:00
36868644dc Check and fix broken anchor links.
In addition to #1682.
2020-06-23 17:51:25 +02:00
321b67efd4 remove password type input on passphrase 2020-06-23 16:41:04 +02:00
9ea42dd981 Checkout CSS improvements (#1684)
* Checkout: Hide hidden items

As [reported on Mattermost](https://chat.btcpayserver.org/btcpayserver/pl/4mxado5a3ifnzxyhrszusz4q8e) the old way of hiding does not work well with widescreen displays.

* Checkout: Minor theme improvements
2020-06-23 16:25:43 +02:00
631d97c6b3 Fix 404 link (#1682) 2020-06-23 22:52:19 +09:00
13569fe4a2 Improve notifications UI (#1678)
* Add No JS support for notification seen toggle

* Invalidate cache when user toggles seen/massaction

* mark notif as seen after click

* add additional mass actions

* fix formatting

* add pav changes

* invalidate cache on new notifs
2020-06-23 10:06:02 +09:00
12e2b93ac9 Add invoice notifications (#1674)
* Add invoice notifications

* fixeth le order

* comment-to-code auto commit

* reduce notifications
2020-06-22 16:32:51 +09:00
0dd1b668cd Support wasabi file format input (#1671)
* Support wasabi file format input

This adds support to importing the wasabi file format which seems to be used more for imports by Wasabi,ColdCard,BlueWallet & Cobo Vault (and way better than electrum anyway)

* fixes

* add test
2020-06-22 15:39:29 +09:00
e751be21ea Altcoin - Add Chaincoin (#1636)
* Altcoin - Add Chaincoin

* Image

* Altcoin - Rating CHC

* Altcoin - Chaincoin insertion

* Revert

* Fix large diff

* Unit Test revert
2020-06-22 14:41:20 +09:00
15b8a159f5 Merge pull request #1672 from NicolasDorier/refactor/bip78
Adapt payjoin for BIP78
2020-06-22 13:58:14 +09:00
24a88fcfb5 Adapt payjoin for BIP78 2020-06-22 13:57:42 +09:00
9f842be53a fixed broken URL links (#1677) 2020-06-20 17:08:50 +02:00
c6632fe083 Change generate wallet passphrase to text input to fix autocomplete (#1676) 2020-06-20 16:02:36 +02:00
0b720768b8 Asyncify NotificationManager 2020-06-17 11:26:21 +09:00
9f12fe7e0a Merge pull request #1670 from btcpayserver/refactor/notifications2
Introduce INotificationHandler
2020-06-17 10:12:16 +09:00
cff5b82b06 Introduce INotificationHandler 2020-06-16 23:29:25 +09:00
677cc3bee9 Merge pull request #1666 from NicolasDorier/refactor/notificatoin
Small refactoring of Notifications
2020-06-16 15:46:27 +09:00
aef5cc50d5 Add the StoreScope 2020-06-15 20:52:53 +09:00
d7eeadac41 Do not allow generation of dummy even if regtest 2020-06-15 17:19:03 +09:00
7cdfa7d4c5 Use attribute to map notifcations to their string 2020-06-15 17:19:03 +09:00
9070b475ea Make the NotificationSender more generic 2020-06-15 17:19:02 +09:00
43a99bfef2 fix supporters 2020-06-15 10:08:38 +02:00
18ffd678b7 Bugfixing context factory reference 2020-06-15 01:25:55 -05:00
7566d3dac8 Tweaking date display in notifications 2020-06-15 01:23:55 -05:00
741b93dc04 Removing obsolete NotificationDbSaver hosted service 2020-06-15 01:22:09 -05:00
b19298f633 Merge pull request #1651 from btcpayserver/feat/notifications
Notification system
2020-06-15 00:59:51 -05:00
1954dfd4d7 Removing Generate Test Notification button 2020-06-15 00:58:23 -05:00
31cc966b38 Bugfixing setting of Created, expanding test 2020-06-15 00:57:20 -05:00
261931c8ef Adding list notification test 2020-06-15 00:53:12 -05:00
2c44c25b25 Signaling reference pass, bugfixing reference to deserialized blob 2020-06-15 00:36:50 -05:00
f072ec3a8c Adding paging to notifications grid 2020-06-15 00:00:56 -05:00
113869bd08 Renaming to BaseNotification 2020-06-14 23:49:08 -05:00
0dab96f0a6 Moving Notification to dedicated Service namespace 2020-06-14 23:49:08 -05:00
342f63a625 Directly casting to NotificationEvent, evading null case 2020-06-14 23:49:08 -05:00
f52c6b65ce Switching to using registered IMemoryCache 2020-06-14 23:49:08 -05:00
07efa87fe5 Refactoring conversion of data to view model, switching to FillViewModel 2020-06-14 23:49:08 -05:00
ffa04b625a Changing case for private methods 2020-06-14 23:49:08 -05:00
b9807aac56 Add Notification entity to database in one migration 2020-06-14 23:49:08 -05:00
b973c0ab82 Removing database migrations in preparation for squashing them into one 2020-06-14 23:49:08 -05:00
0d876b9322 Removing csv jquery voodoo and using checkbox viewmodel mapping 2020-06-14 23:49:08 -05:00
09a72f2cfb Cascade delete notifications for user 2020-06-14 23:49:08 -05:00
455ac8786a Explicitly define NotificationType for NewVersionNotification 2020-06-14 23:49:08 -05:00
213e68859e Renaming class file 2020-06-14 23:49:08 -05:00
2f4967a23a Limiting Notification string fields 2020-06-14 23:49:08 -05:00
0c170fc399 Caching of notifications, refactoring NotificationManager into singleton 2020-06-14 23:49:08 -05:00
d1383d78c5 Disconnecting NotificationBase from Event, introducing NotificationSender 2020-06-14 23:49:08 -05:00
8876f1f992 Making NotificationEventBase classes internal to reduce leak 2020-06-14 23:49:08 -05:00
b53cb50a91 Pkzipping Notification blobs to keep with convention 2020-06-14 23:49:08 -05:00
1f35534dfb Providing overridable NotificationType property, direct mapping 2020-06-14 23:49:08 -05:00
294dad01c3 Switching to UserManager for fetching user id 2020-06-14 23:49:08 -05:00
0ec566e6df Removing modal reference that's not needed 2020-06-14 23:49:08 -05:00
536a85eadc Moving Notifications nav item to separate partial 2020-06-14 23:49:08 -05:00
8cdc73c31f Moving layout partial to separate folder 2020-06-14 23:49:08 -05:00
afaabd06d9 Abstracting conversion to ViewModel, requiring implementation on class 2020-06-14 23:49:08 -05:00
bb6f6e7d27 Adding icon to Action link 2020-06-14 23:49:08 -05:00
73588ea22b Generalizing saving to database and registration of NotificationEventBase classes 2020-06-14 23:49:08 -05:00
b6e3ad9325 Refactoring code to extract claim parsing 2020-06-14 23:49:08 -05:00
7e9bf9598d Providing support for mass actions on notifications, delete first 2020-06-14 23:49:08 -05:00
3680e03cdb Moving to structure where click on td is counted as seen 2020-06-14 23:49:08 -05:00
0b89598f39 Marking notification read through js magic 2020-06-14 23:49:08 -05:00
bad4c9dc60 Confirming deleting of notification 2020-06-14 23:49:08 -05:00
95a751c505 Displaying last 5 notifications in Layout 2020-06-14 23:49:08 -05:00
359e761922 Mark read and unread 2020-06-14 23:49:08 -05:00
654bb0c8ca Displaying number of unread messages in _Layout.cshtml 2020-06-14 23:49:08 -05:00
3eb503b13b Tweaking notification display and allowing deletion 2020-06-14 23:49:08 -05:00
31e0bb43e8 Updating migration with our ef core voodoo magic
We're deleting partial designer classes and moving attributes to main class
2020-06-14 23:49:08 -05:00
4bc0fd98ca Saving notifications to database and loading them from there 2020-06-14 23:49:08 -05:00
9206f0cd2e Handling notifications event and rendering them through controller 2020-06-14 23:49:08 -05:00
e834cd7595 Add Notification Entity migration 2020-06-14 23:49:08 -05:00
50e1e2d982 Standardizing DbSet properties, reducing whitespace 2020-06-14 23:49:08 -05:00
6ddb20d022 Foundation for events to propagate notifications 2020-06-14 23:49:08 -05:00
0cacfa140b Renaming Notice to Notification
Longer, but what can we do...
2020-06-14 23:49:08 -05:00
1ab016d21e Foundation for notices grid 2020-06-14 23:49:08 -05:00
6ad7d18c42 Escaping at character in link 2020-06-14 23:31:54 -05:00
a46774c2ee Merge pull request #1663 from Kukks/supporters
Handle Supporters display
2020-06-15 09:15:56 +09:00
58f9b9b0c1 Handle Supporters display
closes #1624
2020-06-14 16:09:36 +02:00
0000257dcc Merge pull request #1659 from Kukks/psbt-fullprev
Add AlwaysIncludeNonWitnessUTXO to Wallet Send
2020-06-14 22:47:57 +09:00
8c3907df82 add info 2020-06-14 15:45:58 +02:00
f7c1dff576 Merge pull request #1660 from woutersamaey/icon-colors-bootstrap-friendly
Colored "check" and "times" icons green or red the bootstrap way
2020-06-14 22:12:20 +09:00
16982dc76a Merge pull request #1662 from bolatovumar/fix-1661
Update "Back to the app list" links to not open in new tab by default
2020-06-14 22:11:57 +09:00
9532db7bae Update "Back to the app list" links to not open in new tab by default
fix #1661
2020-06-13 19:18:38 -07:00
a93062e0f0 Colored "check" and "times" icons green or red the bootstrap way 2020-06-12 15:22:39 +02:00
b7c65b2ba6 Add AlwaysIncludeNonWitnessUTXO to Wallet Send 2020-06-12 13:58:55 +02:00
f40a8853f6 Require Owner role to the store for modifying store via Greenfield 2020-06-12 18:26:20 +09:00
1889c33d80 Merge pull request #1656 from dennisreimann/docs-links
Update and fix documentation links
2020-06-12 14:51:12 +09:00
308ca479df Merge pull request #1655 from pavlenex/utxo-change
Rename "Make sure no UTXO change is created" to "Don't create UTXO change"
2020-06-12 14:50:38 +09:00
0b7d5c839a Merge pull request #1630 from Kukks/public-endpoint-json
Pay endpoint: if JsonResponse is true, send error in json too
2020-06-12 14:50:17 +09:00
9e0d6618b1 Merge pull request #1629 from Kukks/ipnorder
Add order id to IPN
2020-06-12 14:49:51 +09:00
02a2bd92af Merge pull request #1658 from NicolasDorier/thub
Add thunderhub integration
2020-06-12 14:29:11 +09:00
03d90f79ea Add thunderhub integration 2020-06-12 14:28:28 +09:00
b066cfd904 Update and fix documentation links 2020-06-11 16:09:33 +02:00
475d7f01b7 fix broken link 2020-06-11 12:22:33 +02:00
b30597b8f1 Change the seed saved in NBXplorer to hot wallet (#1652)
* Change the seed saved in NBXplorer name

* the hot wallet
2020-06-11 12:19:40 +02:00
1824f03d35 Rename UTXO change 2020-06-11 12:10:51 +02:00
4cd3d167b1 Autofocus 2FA-code input on page load (#1650)
UX improvement that allows you to directly paste the 2FA-code. Useful when you are using e.g. the 1Password browser extension.
2020-06-10 19:40:06 +02:00
4640c63094 Merge pull request #1637 from jad0c/patch-1
fix broken FAQ link in readme
2020-06-10 16:49:59 +09:00
2460012caa Merge pull request #1646 from Kukks/fix/pos-format
Fix possible view exception in pos app
2020-06-10 10:27:37 +09:00
db7768ef57 Fix possible view exception in pos app
Replaced string.format with a simpler replace and also allow `{Price}` instead of `{0}` as it's obscure to non c# devs
2020-06-09 19:56:44 +02:00
74b6aa7353 Merge pull request #1623 from Kukks/telemetry
Opt out from telemetry data in docker
2020-06-09 22:07:51 +09:00
0e0297d650 Merge pull request #1643 from NicolasDorier/fix/ln
Fix lightning implementation, docs and tests
2020-06-09 21:52:45 +09:00
8dd6ecc0b8 Fix lightning implementation, docs and tests 2020-06-09 17:24:34 +09:00
e84d4d3cb5 Merge pull request #1644 from btcpayserver/feat/lnd-0.10.1-beta
Bump LND version to 0.10.1-beta
2020-06-09 16:06:37 +09:00
da54154ae7 Bump LND version 2020-06-08 23:28:45 -05:00
a9dbbe1955 Merge pull request #1640 from btcpayserver/renametoscope
Rename Permission.StoreId to Permission.Scope
2020-06-07 23:27:11 +09:00
3fbe86c286 Rename Permission.StoreId to Permission.Scope 2020-06-07 23:17:48 +09:00
0022e71dd4 Merge pull request #1628 from Kukks/greenfield/consistentreturn
GreenField: Handle status codes, error models consistently
2020-06-07 18:59:22 +09:00
c74121fefc Opt out from telemetry data in docker
https://www.michaelcrump.net/part12-aspnetcore/
https://docs.microsoft.com/en-us/dotnet/core/tools/telemetry
2020-06-07 08:32:00 +02:00
67c3581989 Add order id to IPN
fixes #1598
2020-06-07 08:31:42 +02:00
1d1c1141a3 Pay endpoint: if JsonResponse is true, send error in json too
fixes #1532
2020-06-07 08:30:54 +02:00
cf00784096 fix swagger 2020-06-07 08:30:04 +02:00
db209af787 Updating ports for merchant lnd
I saw several instances where btcpayservertests_merchant_lnd_1 failed to start in circleci
2020-06-07 01:24:47 -05:00
30bd94ee43 fix tests 2020-06-07 08:21:45 +02:00
f313a5f221 GreenField: Handle status codes, error models consistently 2020-06-07 08:21:45 +02:00
b9ef5af5d7 Fixing variable reference
Who'll save Emperor if not me
2020-06-06 23:52:21 -05:00
59677b6521 fix broken FAQ link in readme 2020-06-06 21:44:13 -04:00
56283df05a Can only sign with NBX if imported with NBX 2020-06-07 09:38:29 +09:00
ef271a088a Merge pull request #1634 from dennisreimann/minor-fixups
Minor fix ups
2020-06-06 09:48:28 +09:00
6043b7c75d Minor fix ups
Resolves https://github.com/btcpayserver/btcpayserver/pull/1633#discussion_r435655010
2020-06-05 11:38:55 +02:00
c338779f0e Merge pull request #1633 from dennisreimann/onion-location
Add Onion-Location HTTP header
2020-06-05 11:09:55 +09:00
67758609a7 Add Onion-Location HTTP header
Closes #1626.
2020-06-04 08:53:55 +02:00
f2bb24f6ab Fix build error #1588 2020-06-03 15:49:27 +09:00
44ee7c66ce Merge pull request #1620 from NicolasDorier/additionaldata
[GreenField] Add additional data to allow roundtrip of upper version fields
2020-06-01 19:23:35 +09:00
117622200b Merge pull request #1622 from Kukks/network-rates-decouple
Remove dependency on Common from Rating
2020-06-01 15:25:19 +09:00
340ba5c714 fix symbol 2020-06-01 08:13:39 +02:00
9e16b506e5 Small esthetic refacotring 2020-06-01 13:10:21 +09:00
e865d85c2c Merge pull request #1619 from NicolasDorier/adddoc
[Greenfield] Document store API
2020-06-01 11:47:16 +09:00
284e66c730 fix test 2020-05-31 20:54:50 +02:00
587f244f1d Remove dependency on Common from Rating
replaces #1591 and #1592 , closes #1571 Replaces the Currencies.txt to a json format which includes the networks too ( there is also a test to check now) Also makes CurrencyPair not depend on network and instead use CurrencyNameTable
2020-05-31 20:54:50 +02:00
379e5741e7 fix broken bootstrap theme generator link 2020-05-31 20:54:24 +02:00
ec4c346e0a [Greenfield] Document store API 2020-05-31 12:04:23 +09:00
5099f98d2a [GreenField] Add additional data to allow roundtrip of upper version fields 2020-05-31 11:51:36 +09:00
ebc99adc58 Merge pull request #1615 from NicolasDorier/refactor/timespan
Always use second based TimeSpan in Greenfield
2020-05-31 10:55:40 +09:00
048dff7e9e Always use second based TimeSpan in Greenfield 2020-05-31 08:52:32 +09:00
a70934938a Merge pull request #1605 from dennisreimann/pos-refactoring
Point of Sale Refactoring
2020-05-30 13:14:50 +09:00
d9a93f996f Merge branch 'master' of https://github.com/btcpayserver/btcpayserver 2020-05-29 18:47:40 +09:00
3456d87bb5 Merge pull request #1612 from Kukks/api/swaggerln
Api/swaggerln
2020-05-29 18:47:25 +09:00
4947fa4d45 Add also money json converter 2020-05-29 10:15:01 +02:00
37f4b34b5e Add Lightmoney json converter + do swagger defs for ln api 2020-05-29 10:04:28 +02:00
66206399e1 Rename LightningPrivateRouteHint =>privateRouteHints 2020-05-29 09:03:07 +09:00
1e3f62718d GreenField: Cross-implemenation Lightning Node API (#1566)
* GreenField: Cross-implemenation Lightning Node API

* switch to hard unrsstricted check

* fix

* set LightningPrivateRouteHints in swagger + stores api

* add priv route hint

* rename models and add swagger defs to models
2020-05-29 09:00:13 +09:00
114ab98059 Merge pull request #1611 from Kukks/fix/pr-expiry-big
Fix: Paid payment requests are not marked as completed if there is an expiry date set
2020-05-29 08:58:58 +09:00
47baa219fd Merge pull request #1609 from NicolasDorier/pj3
Adapt PJ implementation to latest BIP
2020-05-29 08:58:38 +09:00
96509717cb Fix: Paid payment requests are not marked as completed if there is an expiry date set 2020-05-28 17:45:06 +02:00
89bbcb6092 Merge pull request #1610 from pavlenex/supporter-new
Add new supporter to readme
2020-05-29 00:05:21 +09:00
95dbb65612 GreenField: Payment Request property missing jsonconverter 2020-05-28 16:57:03 +02:00
7db8d52624 add missing title in swagger payment request def 2020-05-28 16:53:50 +02:00
77073fa78c fix swagger schema 2020-05-28 16:42:47 +02:00
9e315f99d0 POS: Updates from code review 2020-05-28 12:50:08 +02:00
16ad3ee7fe Add test for payment request payment status update in greenfield 2020-05-28 09:48:47 +02:00
559015c70d POS: Test fixes 2020-05-28 09:40:34 +02:00
15d02dab4f Add new supporter to readme 2020-05-28 09:28:42 +02:00
332a1da167 POS: Updates from code review 2020-05-28 08:59:48 +02:00
e12aa9e657 POS: Use views instead of partials 2020-05-28 08:50:04 +02:00
9503e07dc8 Adapt PJ implementation to latest BIP 2020-05-28 13:35:48 +09:00
9b44370832 support version revision tags 2020-05-27 16:56:39 +02:00
568015c58f add new supporter 2020-05-27 16:41:50 +02:00
58f56eac90 POS: Updates from code review
Thanks @kukks
2020-05-27 14:20:21 +02:00
03532e4063 Merge pull request #1604 from janoside/master
Clarify/clean up warning shown when adding a lightning node
2020-05-27 12:34:36 +09:00
de6081c2dc Merge pull request #1602 from Kukks/electrum-file
Rename Coldcard to Electrum/Airgapped hardware wallets
2020-05-27 12:33:43 +09:00
197b46880c POS: Separate static and cart views 2020-05-26 21:53:23 +02:00
b7ec22ee89 POS: Set ViewType via optional URL parameter
Falls back to the DefaultView defined in the POS settings.

POS: Fix POST-Route
2020-05-26 21:53:22 +02:00
fad53a9fa2 POS: Replace EnableShoppingCart with DefaultView 2020-05-26 16:48:47 +02:00
5b4fec11ed Merge pull request #1596 from NicolasDorier/random-rbf
Randomize RBF if the user does not care
2020-05-26 03:23:33 +09:00
0ef4602a65 Clarify/clean up warning shown when adding a lightning node 2020-05-25 13:42:58 -04:00
c8f182f13f Rename Coldcard to Electrum/Airgapped hardware wallets
Also adds support to read the xpub from the file directly ( Cobo Vault support)
2020-05-25 15:49:44 +02:00
36630d9586 Randomize RBF if the user does not care 2020-05-25 19:46:42 +09:00
32f2acee53 Removed unexisting file in csproj 2020-05-25 16:08:16 +09:00
3be2ef5c91 Merge pull request #1599 from NicolasDorier/removeledger
Remove LedgerWallet direct integration
2020-05-25 07:50:33 +09:00
7e5d269c39 Remove LedgerWallet direct integration 2020-05-25 07:41:30 +09:00
6e0c090622 Merge pull request #1597 from NicolasDorier/refactor/wallet-param
Refactor parameter passing in wallet functions
2020-05-25 07:15:52 +09:00
cccf3ca617 The signing context should not be passed to PSBT screen 2020-05-25 07:05:01 +09:00
9e9b5945fe Ensure the payjoin can generate a high R signature if the payer is sending it 2020-05-25 06:47:43 +09:00
77f6019d82 Use EnforceLowR suggestion of NBXplorer for signing 2020-05-25 06:34:49 +09:00
35432d919c Refactor common data structure for wallet into SigningContext 2020-05-25 06:29:06 +09:00
25e6f82aa3 Refactor parameter passing in wallet functions 2020-05-25 04:55:28 +09:00
d22993871f Bump NBXplorer 2020-05-24 20:19:06 +09:00
80563de587 Add support for Bitpay invoice create property "paymentCurrencies" (#1589) 2020-05-24 19:11:26 +09:00
b5102c4269 Bump NBX (#1595) 2020-05-24 17:59:43 +09:00
9d215ea27d Reuse same html and handling of commands for PSBT signing/ Wallet Send (#1587)
* Reuse same html and handling of commands for PSBT signing/ Wallet Send

* fix ledger
2020-05-24 04:31:21 +09:00
cdf6886c39 Require loggedin user for docs? (#1567)
* Require loggedin user for docs?

We had talked before that docs should be for authorized users only. We had it in when we had Nswag but must have lost it after we switch to manual swagger files

* fix
2020-05-24 04:18:51 +09:00
79b034b505 GreenField: Add properties to Store API (#1573)
* GreenField: Add properties to Store API

* Update StoreBaseData.cs

* fix api

* fix swagger
2020-05-24 04:13:18 +09:00
bfba105aec Update packages (may fix #1590) 2020-05-22 19:23:37 +09:00
1bbdaa1251 Make sure replaced transactions have linethrough in the invoice list 2020-05-21 01:50:39 +09:00
ca462bec84 Merge pull request #1585 from btcpayserver/feat/private-route-hints
Adding private route hints based on store settings
2020-05-20 08:10:08 +09:00
eb5dcab32d Upgrading to BTCPayServer.Lightning to 1.1.15 2020-05-19 18:00:35 -05:00
ca3acdacdc Setting PriveRoute hints when creating lightning invoices 2020-05-19 16:47:26 -05:00
33f63508e8 Adding setting in checkout experience for inclusion of private route hints 2020-05-19 16:27:06 -05:00
5033cb3186 Support specifying payment method through apps (#1539)
* Support specifying payment method through apps

closes #1525
This is great if you want to offer items with an incentive to use a specific payment method without messing with the rates.
For example, you can have `Item A` which costs 25$ and your store is configured for USDT and BTC. You can create two items, with different prices, where Item A costs 20$ if you pay with bitcoin or 25$ if you paid in dirty fiat pegs

* make code cleaner

* Add Test

* fix test

* fix test
2020-05-20 03:54:24 +09:00
3d1122be7c Merge pull request #1583 from NicolasDorier/refactor/serverinfo
Refactor server info data structure
2020-05-20 03:43:39 +09:00
1d092a15fb Refactor server info data structure 2020-05-20 03:27:06 +09:00
501a21b89e bump .net core on dockerfile 2020-05-20 03:10:30 +09:00
b9006e4417 fix rebase
# Conflicts:
#	BTCPayServer.Tests/GreenfieldAPITests.cs
2020-05-19 20:09:19 +02:00
5b3b96b372 GreenField: Payment Requests CRUD (#1430)
* GreenField: Payment Requests CRUD

* fixes

* fix swagger

* fix swag

* rebase fixes

* Add new permissions for payment requests

* Adapt PR to archive

* fix tst

* add to contains policxy

* make decimals returned as string due to avoid shitty language parsing issues

* do not register decimal json converter as global

* fix cultureinfo for json covnerter

* pr changes

* add json convertet test

* fix json test

* fix rebase
2020-05-20 02:59:23 +09:00
338a0f9251 Merge pull request #1576 from dennisreimann/api-server-info
GreenField: Add Server Info API basics
2020-05-20 02:31:16 +09:00
29ba761d7c Merge pull request #1581 from NicolasDorier/syncpj
Sync payjoin receiver implementation to the bip
2020-05-19 21:10:35 +09:00
b96e668dfd Sync payjoin receiver implementation to the bip 2020-05-19 20:57:04 +09:00
de3753d04e Rename payjoin optional parameters, implement sender minFeeRate 2020-05-19 20:57:03 +09:00
2a030fe7fb Use different close button color variable (#1580)
fix #1579
2020-05-18 21:52:26 +02:00
f595d823b6 Decode item description on POS app page (#1578)
fix #938
2020-05-18 21:51:58 +02:00
78d191f7d8 Incorporate code review feedback 2020-05-18 16:51:21 +02:00
3b6dbe76c5 Add sync state 2020-05-18 16:02:15 +02:00
e3b348b55c GreenField: Add Server Info API basics 2020-05-18 15:29:04 +02:00
cf012a7946 fix dead link (#1575) 2020-05-18 08:44:12 +02:00
8d1ff01ee8 Adapt payjoin implementation to the BIP (#1569) 2020-05-17 05:07:24 +09:00
e9bda50054 Bumping LND to v0.9.2-beta in dev 2020-05-13 18:06:14 -05:00
8ca2824b00 Open wallet with BIP21 links (#1565)
* Open wallet with BIP21 links

https://i.imgur.com/IWefMKB.gifv

* remove debugger;

* Move to settings
2020-05-12 22:32:33 +09:00
f7d70daff3 Add invalid-transaction as wellknown error 2020-05-12 21:42:51 +09:00
42d27d69dc Merge db migrations 2020-05-10 00:53:21 +09:00
5a9d1e3257 Merge pull request #1560 from Kukks/archive-pr
Archive Payment reqeusts
2020-05-10 00:51:59 +09:00
9cc9a16bb9 Merge pull request #1556 from Kukks/invoice-archive
Archive Invoice
2020-05-10 00:51:11 +09:00
a3efe9a9dc Merge pull request #1561 from NicolasDorier/bp/new
Refactoring of payjoin to support new spec
2020-05-10 00:50:40 +09:00
94b0b9498d adapt tests 2020-05-09 15:17:59 +02:00
bb322d6bf3 add e2e test 2020-05-09 15:05:52 +02:00
b0f820e95a Implement noadjustfee, feebumpindex and v parameters for payjoin 2020-05-09 21:22:00 +09:00
da588380ed Remove httpCode from error message 2020-05-09 19:33:48 +09:00
8fa65408ed Archive Payment reqeusts
closes #1588
2020-05-08 12:33:47 +02:00
2d68d0da63 Redo App template editor with Vue based app (#1544)
* Redo App template editor with Vue based app

* fix styles better

* remove debug

* support methods

* make price required

* fix styling for validation errors

* show create or edit in title based on context

* add border bottom when image present

* escape/unescape

* more validation fixes

* fix responsive style

* Toggle template field

* add errors to the app

* enhance validation
2020-05-08 05:37:59 +09:00
2bc7fa0316 Show warning when enabling Payjoin but supported payment methods are not using a hot wallet (#1545)
* Show warning when enabling Payjoin but supported payment methods are not using a hot wallet

https://i.imgur.com/RXBhr0n.png fixes #1474

* expose p2p port
2020-05-08 05:37:10 +09:00
55f416c48c apply window scroll offset to copied notification offset (#1550)
resolves #1549
2020-05-08 05:35:25 +09:00
aff91f49ef Make fee rate options pretty (#1554) 2020-05-08 05:34:39 +09:00
ba02372d13 Try to tell browser that autocomplete is not welcome in generate wallet (#1555)
fixes #1553
2020-05-07 21:41:37 +09:00
e5a3ef3e22 Archive Invoice 2020-05-07 12:50:07 +02:00
137c3ef2ce Add changelog 2020-05-05 19:19:27 +09:00
87352f0b62 Make sure wallet support decimal fee, and allow user to select different fee rate based on expected confirmation time 2020-05-05 19:10:53 +09:00
2226884946 add qrcode margins (#1547)
addresses #1537 by adding a margin to the qrcodes in ShowLightningNodeInfo and WalletReceive (use same settings as Checkout)
2020-05-05 10:26:57 +02:00
9d2cd46464 fix tests and bump 2020-05-05 07:23:00 +09:00
f3b2b350ce Fix build 2020-05-05 07:06:32 +09:00
96c04481da bump NBXplorer 2020-05-05 06:55:19 +09:00
dad2642fa7 Make sure we match the user's sequence 2020-05-05 04:45:10 +09:00
59bdb943dd Reverting invoice row display so AM/PM is not cut off 2020-05-04 01:42:02 -05:00
67da6ee379 Decimal precision and filter valid transaction (#1538)
The liquid transactions list was showing all transactions to the wallet, even when it had nothing to do with the specific crypto code (e.g sending LBTC txs in USDT, LCAD in USDT, etc). This PR fixes that.

It also uses the previously introduced checkout decimal precision fix to the Wallets screen, specifically the balance amount on wallet llist and balance change on transaction list.
2020-05-04 01:04:34 +09:00
9c9c102e74 fix PadRight formatter 2020-05-03 09:32:10 +02:00
26241be6fa Ensure dropdown option doesn't overflow container (#1533)
fix #1526
2020-05-03 01:39:39 +09:00
2bb4dd5d01 Fix decimal points shown in Checkout UI based on currency ( always showed btc decimal precision before) (#1529)
* Fix decimal points shown in Checkout UI based on currency ( always showed btc decimal precision before)

* cleanup ShowMoney
2020-05-03 01:28:35 +09:00
5312bb1dee Merge pull request #1535 from Kukks/elementsbump
Bump elements and fix test
2020-05-02 20:47:22 +09:00
bf6f5aa335 Bump c-lightning 2020-05-02 20:33:55 +09:00
4a58763f98 Bump elements and fix test 2020-05-02 13:26:55 +02:00
b8202da7aa Fix tests 2020-05-02 00:59:36 +09:00
edfc82ac75 Merge pull request #1522 from Kukks/view-seed
Add View seed to wallet settings
2020-05-01 21:36:27 +09:00
b28fc85974 Fix: Do not returns HTML content if authentication to API fails 2020-05-01 21:33:42 +09:00
ab1b36bcdc add test for view seed 2020-05-01 13:34:11 +02:00
5443ac4688 Merge pull request #1531 from Kukks/api/store/prep
GreenField: Prep store for more data
2020-05-01 18:49:29 +09:00
d92d8ba0e4 Merge pull request #1524 from Kukks/txlist-labelfix
Add top Label filter + fix label link inconsistency
2020-05-01 18:47:48 +09:00
0f19d303eb Merge pull request #1527 from Kukks/app-inv-clean
Make App Inventory Updater run updates in order
2020-05-01 18:46:08 +09:00
1332f597e5 Merge pull request #1528 from Kukks/payjoin/ui-linkfix
Payjoin: Fix payjoin detection in checkout UI
2020-05-01 18:44:50 +09:00
de004074b7 Fix typo 2020-05-01 18:43:40 +09:00
29741f39ac Merge pull request #1523 from Kukks/sender-payjoin-label
Tag payjoin for sender too
2020-05-01 05:27:33 +09:00
33ea8984fc format 2020-04-30 16:44:27 +02:00
85517b0344 GreenField: Prep store for more data
refactored things around a bit to make it cleaner for when we add more properties to the store model
2020-04-30 16:43:16 +02:00
74c574255e Payjoin: Fix payjoin detection in checkout UI
sometimes, it would think there is a payjoin enabled invoice when really, it was just the address or asset id that has `pj` in it
2020-04-30 09:05:17 +02:00
70d4e98dff Make App Inventory Updater run updates in order
followed the same logic we used in the new auto labelling
2020-04-29 14:51:37 +02:00
f1900d30f2 clean format 2020-04-29 11:21:47 +02:00
463567cb07 Add top Label filter + fix label link inconsistency 2020-04-29 10:11:23 +02:00
53b0e675c3 Tag payjoin for sender too 2020-04-29 09:09:16 +02:00
d323bb35cc Add View seed to wallet settings 2020-04-29 08:28:13 +02:00
3e13e478ad Fix click on label 2020-04-29 01:43:41 +09:00
5f421b0679 Changlog 1.0.4.2 (#1513) 2020-04-29 01:23:02 +09:00
c99fe54db1 bump 2020-04-29 01:21:58 +09:00
05a2985c5b Changlog 1.0.4.2 2020-04-29 01:07:20 +09:00
47408498b9 Revert "View seed option if available (#1518)" (#1521)
This reverts commit e75b4ec6bfb41dfca018315350e7305f95cc39f0.
2020-04-29 00:57:41 +09:00
e75b4ec6bf View seed option if available (#1518) 2020-04-29 00:55:53 +09:00
ff99ab1239 Improve pay button with custom text (#1520)
Fixes #1517.
2020-04-29 00:52:48 +09:00
2841cd8498 Updates from design system (#1519)
* Use variable names as defined in the design system

* Use bootstrao version from design system
2020-04-29 00:48:55 +09:00
519f4af867 Bump pj original tx broadcast timeout 2020-04-29 00:23:51 +09:00
68cc3aba21 update translations 2020-04-29 00:22:48 +09:00
3a2970a495 Label Factory (#1516)
* Label Factory

* fix typo and format
2020-04-28 16:53:34 +09:00
b31fb1a269 Auto label utxos based on invoice and payjoin (#1499)
* Auto label utxos based on invoice and payjoin

This PR introduces automatic labelling to transactions.
* If it is an incoming tx to an invoice, it will tag it as such.
* If it was a payjoin tx , it will tag it as such.
* If a transaction's inputs were exposed to a payjoin sender, we tag it as such.

* wip

* wip

* support in coinselection

* remove ugly hack

* support wallet transactions page

* remove messy loop

* better label template helpers

* add tests and susbcribe to event

* simplify data

* fix test

* fix label  + color

* fix remove label

* renove useless call

* add toString

* fix potential crash by txid

* trim json keyword in manual label

* format file
2020-04-28 15:06:28 +09:00
3801eeec43 Payjoin: Better UIH1 & UIH2 based selection (#1473)
* Try to make SelectUTXO care about all inputs and outputs

* wip

* wip

* Add test and fix seelctor

* remove space

* review changes

* revert back to index check
2020-04-28 01:28:21 +09:00
94cdd399d5 Finetune colors (#1514)
* Better harmonic neutral color progression

fix

* Invert light/dark colors for dark theme

fix

* Lighten form control borders a bit

* Use correct text color variables
2020-04-27 23:57:18 +09:00
c784144a07 Greenfield: Add update store API (#1495)
* Greenfield: Add update store API

* update update store model

* change greenfield controller name to stop conflict
2020-04-27 20:13:20 +09:00
b600e5777e Add tooltip for store deriv + show "Not set" + "show end piece of string" (#1507)
* Add tooltip for store deriv + show "Not set" + "show end piece of string"

fixes #1506

* use regex witchraft

* adjust with regex
2020-04-27 19:55:46 +09:00
e49074d797 fix bip21 + coinselection combo bug in wallet send 2020-04-27 12:12:01 +02:00
02d26467f9 remove fake bundle 2020-04-27 12:04:18 +02:00
e68b45c76a Update lightning-charge to v0.4.19 (#1511)
Changes the default units from mBTC to sats
2020-04-27 18:44:12 +09:00
f410f7d4d1 Hide LN option for liquid Assets (#1512)
Was getting a bit crowded for stuff that isn't supported yet.
2020-04-27 18:15:38 +09:00
d4dbe6fe17 Typo fix (#1503) 2020-04-27 05:18:36 +09:00
c7305ba5e1 Bump lightning 2020-04-27 04:39:17 +09:00
e11963aca0 Checkout dark theme improvements (#1510)
Increase the contrast for some elements. Closes #1508.
2020-04-27 04:23:03 +09:00
2d77426e04 Bump lightning 2020-04-27 04:10:31 +09:00
7e0f9e1d28 Fix docker-customer-lightning-cli.ps1 pay doesn't work (Fix #1509) 2020-04-27 03:59:16 +09:00
18e181bb9f Bump lightning library, logs channel setup 2020-04-27 03:53:45 +09:00
c3c9585a95 Bump BTCPayServer.Lightning 2020-04-27 02:29:34 +09:00
4b5b941761 Update translations 2020-04-26 15:34:30 +09:00
79c70b31a3 Fix tests 2020-04-26 01:47:47 +09:00
072139f707 bump Nbitcoin 2020-04-26 01:11:50 +09:00
9d80db98c5 bump NBitcoin 2020-04-26 01:01:09 +09:00
a5df029d43 update test to loop through all formats for payjoin 2020-04-25 17:38:04 +02:00
47f16aadd5 Rely on NBitcoin to get the expected hash 2020-04-26 00:26:02 +09:00
f8b2b18c6e Fix PJ (#1502)
* Fix P2SH-P2WPKH case for Payjoin (Fix #1500)

* fix p2sh issue

Co-authored-by: nicolas.dorier <nicolas.dorier@gmail.com>
2020-04-26 00:19:24 +09:00
4be6c06af5 add payjoin e2e test for all compatible formats 2020-04-25 16:12:16 +02:00
92c58eea7f Fix: Sign with NBX option not present after decoding PSBT (#1497) 2020-04-23 22:02:26 +09:00
5e6049bf3f Payjoin fix: return psbt in same format it was received (#1496)
* Payjoin fix: return psbt in same format it was received

* fix formatting
2020-04-23 22:02:00 +09:00
7adaa146dc Merge pull request #1471 from dennisreimann/api-health-endpoint
GreenField: Add health check endpoint
2020-04-23 02:44:11 +09:00
e3b51f593e Merge pull request #1411 from Kukks/api/stores/get
GreenField: Create/Get/Delete Stores
2020-04-23 02:42:29 +09:00
e64094dfcc fix permissions for client api tester 2020-04-22 15:12:38 +02:00
cb6fcadb86 add scope test 2020-04-22 15:05:13 +02:00
297b84a18b add request name validation 2020-04-22 15:05:13 +02:00
b7c0e049b5 fix bug in permission store selector 2020-04-22 15:05:13 +02:00
aeef160d0b separate store swagger 2020-04-22 15:05:13 +02:00
34c1a304a9 Add Create Store 2020-04-22 15:05:13 +02:00
4f1ae4733c remove store api 2020-04-22 15:05:13 +02:00
e009c1a25a Fixing CheckNoDeadLink test now that btse blocks our call from circleci 2020-04-22 15:05:13 +02:00
79f12a7058 fix client 2020-04-22 15:05:13 +02:00
deb197cfa5 GreenField: Get Stores 2020-04-22 15:05:13 +02:00
2710130667 add error message instead of 500 status
fixes #1494
2020-04-22 14:18:36 +02:00
48163961ed Rename LCAD image (#1493)
Fixes #1491.
2020-04-22 08:47:44 +02:00
8658cb5f29 Re-add versioning for btcpay.js (#1489) 2020-04-22 08:24:29 +02:00
a6a56e4791 fix controller 2020-04-21 17:09:17 +02:00
22e39998e2 Updates from code review
Thanks @kukks!
2020-04-21 16:43:14 +02:00
70d1056d48 API: Health endpoint returns synchronized state 2020-04-21 16:29:54 +02:00
3bd5c3e1b5 API: Add health check endpoint 2020-04-21 14:59:33 +02:00
0a1a4fd3b5 Merge pull request #1490 from bolatovumar/fix-1488
Make both sides of payment request table look same
2020-04-21 20:15:33 +09:00
e508b22d34 Make both sides of payment request table look same
fix #1488
2020-04-20 20:45:59 -07:00
a7815f107e Merge pull request #1485 from Kukks/fix/pay-request-url
Fix: Payment request redirects to non-existing (404) URL after paymen…
2020-04-20 18:39:59 +09:00
ded5670108 Merge pull request #1486 from Kukks/hotwalletwarning
Show warning when using hot wallet on non admin
2020-04-20 01:56:18 +09:00
c1ffeb331b Fix typo 2020-04-20 01:47:27 +09:00
ad1148d3e2 Merge pull request #1487 from ketominer/master
Fix MySQL support (fixed width columns instead of blobs) replaces #1484
2020-04-19 21:26:36 +09:00
a7b926d907 fixed Address field size (back) 2020-04-19 13:48:05 +02:00
1f7a821c09 Show warning when using hot wallet on non admin
closes #1475
2020-04-19 13:45:51 +02:00
bf45edb5d8 Fix: Payment request redirects to non-existing (404) URL after payment completed
fixes #1479
2020-04-19 13:12:07 +02:00
686f5bf151 Fix MySQL support (fixed width columns instead of blobs) 2020-04-19 11:15:06 +02:00
426fe793e6 remove versioning for btcpay.js
fixes #1483
2020-04-19 09:29:20 +02:00
aee55103a3 Merge pull request #1477 from dennisreimann/asset-cache-busting
Improve static asset caching
2020-04-19 05:32:20 +09:00
778bf97079 Merge pull request #1478 from dennisreimann/assert-link-not-dead
Improve AssertLinkNotDead test output in case of exception
2020-04-19 03:10:45 +09:00
2dcb3111f8 Add changelog 2020-04-19 03:05:23 +09:00
03d1f98402 Improve AssertLinkNotDead test output in case of exception
If the test fails with an exception other than the `EqualException` the failed URL isn't logged. This general exception handler takes care of e.g. `HttpRequestException` and reports the URL that failed to be checked.

Stumbled upon this while checking why [this test run](https://app.circleci.com/pipelines/github/btcpayserver/btcpayserver/2934/workflows/0525d9fd-e4de-49dc-957b-d98b16a9abd4/jobs/7199/parallel-runs/0/steps/0-102) fails.
2020-04-18 19:33:53 +02:00
34755b32dc bump 2020-04-19 02:09:12 +09:00
6679ee1ca2 Merge pull request #1472 from Kukks/payjoin/p2shfixes
Fix Payjoin p2sh
2020-04-19 02:01:10 +09:00
8420c74b31 Improve static asset caching
Cache static assets for one year and set the correct cache control header. Adds the cache busting version based on file content to asset references to invalidate the cache on change. ([further details on the approach](https://andrewlock.net/adding-cache-control-headers-to-static-files-in-asp-net-core/) and [why one year](https://ashton.codes/set-cache-control-max-age-1-year/))

Most of the changes are the additions of the `asp-append-version="true"` attribute, the main configuration change is in `Startup.cs`.
2020-04-18 17:56:05 +02:00
0077105a2d remove hacks 2020-04-18 08:29:07 +02:00
51db617584 fixes 2020-04-18 08:09:49 +02:00
514b695907 fix coin addition for p2sh 2020-04-18 08:09:49 +02:00
b470ce2dad fix p2sh test error codes 2020-04-18 08:09:49 +02:00
161850150a fix p2sh detection input 2020-04-18 08:09:49 +02:00
b02cfa9d41 fix subtract fees auto tick when clicking on balance 2020-04-17 15:24:27 +02:00
dfe655393d Fix enable payjoin when p2sh 2020-04-16 17:23:29 +02:00
8c81dae167 bump 2020-04-16 22:44:53 +09:00
de75d30f06 bump 2020-04-16 22:41:36 +09:00
8ba99d4e7c Merge pull request #1469 from NicolasDorier/changelog
Add changelog 1.0.4.0
2020-04-16 22:40:04 +09:00
c3bc25a7d4 Add changelog 2020-04-16 22:38:38 +09:00
42be03b560 bump nbx and nbitcoin 2020-04-16 19:37:10 +09:00
e73aece9c3 Merge pull request #1467 from dennisreimann/404-center-supporters
Center supporter logos on 404 page
2020-04-16 14:47:35 +09:00
69c57867b3 Merge pull request #1468 from NicolasDorier/persisit/offchaintx
Persist offchain transactions
2020-04-16 14:46:48 +09:00
7434163848 Persist offchain transactions 2020-04-16 14:36:50 +09:00
00d1c4ebcc Navbar fixes (#1466)
* Fix onion position in mobile navbar

* Show nav hover highlight only on desktop

* Fix navbar icon color
2020-04-15 17:13:58 +02:00
26067fbfe2 Center supporter logos on 404 page 2020-04-15 16:49:13 +02:00
03458efea4 Change payjoin endpoint key to pj 2020-04-13 11:52:22 +02:00
bd21bf9c0f add payjoin tooltip 2020-04-13 11:51:25 +02:00
5b7a20c33e Merge pull request #1464 from NicolasDorier/payjoin/persistance
Persist planned transactions and locks for payjoin
2020-04-13 16:57:13 +09:00
c73c34dfaa Persisting locked input and outpoints 2020-04-13 16:06:07 +09:00
a3a9361ba5 Persist the Delayed Broadcaster 2020-04-13 16:00:33 +09:00
2f0e9569a1 Fix build error 2020-04-13 15:57:57 +09:00
511a0efa89 Merge pull request #1465 from Kukks/hot-wallet-policy
add additional server policy for hot wallet RPC import
2020-04-13 15:51:01 +09:00
4ae91ba307 Merge pull request #1461 from bolatovumar/fix-1459
Make sure sponsor logos show up nicely on all screen sizes
2020-04-13 15:49:23 +09:00
3a70f467eb Merge pull request #1457 from bolatovumar/fix-1456
Add mnemonic phrase color CSS variable
2020-04-13 15:48:55 +09:00
4e09bb0b01 add additional server policy for hot wallet
So that if you enable hot wallets for all, you can still not allow them to import to your RPC
2020-04-13 08:48:35 +02:00
5ae18cf21f Make sure mnemonic phrase doesn't blend into background 2020-04-13 08:05:44 +02:00
6bfb6a795e Merge pull request #1462 from NicolasDorier/improve-ux-hotwallet
Do not ask for address confirmation if a new wallet is generated
2020-04-13 13:55:34 +09:00
1d2540543b Payjoin: Randomly round the payment output if it is one input tx 2020-04-13 13:34:23 +09:00
9efe6267d3 Do not ask for address confirmation if a new wallet is generated 2020-04-13 13:03:55 +09:00
cb10551d2c Make sure sponsor logos show up nicely on all screen sizes
fix #1459
2020-04-12 15:08:28 -07:00
b0073af5aa Merge pull request #1408 from Kukks/api/api-key-uu-refactor
Refactor UI for Add APIKey/Authorize
2020-04-10 22:00:32 +09:00
7ca7f53446 Merge pull request #1447 from dennisreimann/modern-theme
New default theme
2020-04-10 16:55:55 +09:00
ad284a4b61 Refactor UI for Add APIKey/Authorize 2020-04-10 09:49:01 +02:00
95e7d5ded9 fix tests 2020-04-10 09:18:08 +02:00
55722b3191 Improve border color themeing 2020-04-10 09:18:08 +02:00
5e34efc9f4 Improve invoice table details display 2020-04-10 09:18:08 +02:00
6f85ffd9df Update footer color 2020-04-10 09:18:08 +02:00
9783a76c38 Fix generated API key color 2020-04-10 09:18:08 +02:00
05952f95f1 Split light and dark theme
To make them explicitely selectable.
2020-04-10 09:18:08 +02:00
b9c97cc5d7 Homepage updates 2020-04-10 09:18:08 +02:00
d5b088b924 Improve color handling 2020-04-10 09:18:08 +02:00
fbd5673cfd POS logo coloring fix 2020-04-10 09:18:08 +02:00
dbb7ad083a Add alert-link classes where necessary 2020-04-10 09:18:08 +02:00
ce7e4234cc Decrease font-size to match classic theme 2020-04-10 09:18:07 +02:00
d2b38fdfce Set default theme for kitchensink 2020-04-10 09:18:07 +02:00
fcdcc5e69b Update main nav hover
fix
2020-04-10 09:18:07 +02:00
8d73606809 Footer updates 2020-04-10 09:18:07 +02:00
15a7c4d092 Use consistent variable names 2020-04-10 09:18:07 +02:00
c205e41072 Rename modern to default theme 2020-04-10 09:18:07 +02:00
48c220b751 Header updates for light/dark theme
fix
2020-04-10 09:18:07 +02:00
06ff268644 Update bootstrap and kitchensink
Discourage use of explicit light/dark classes, because they interfere with the approach of having parallel light/dark themes.
2020-04-10 09:18:07 +02:00
9ee920a816 Draft modern theme
Based on the design input from Figma, see https://www.figma.com/file/C7Xyq0FlxgFW8vaBr8ht1z/BTCPAY?node-id=17%3A126

Color updates
2020-04-10 09:18:07 +02:00
a403363015 Move font-size setting to site.css 2020-04-10 09:18:07 +02:00
6274958409 Trust the payment method details for the payjoin enabled and make invoice logs consistent (#1450) 2020-04-10 16:00:41 +09:00
d47e225dce Fix email sending on registration crash (#1454) 2020-04-10 15:59:39 +09:00
841cf61c92 Add L-CAD support (new Liquid Asset) (#1448)
* Add Liquid CAD support

Adds the Liquid CAD asset ID from Bull Bitcoin

* Add the Liquid CAD logo

* Fix image asset

Co-authored-by: Andrew Camilleri <evilkukka@gmail.com>
2020-04-10 15:59:02 +09:00
2d2c5b46af Support RBF and PayJoin for GRS (#1455) 2020-04-10 15:38:00 +09:00
cc80e4636f Remove runtime compile on tests (#1453) 2020-04-09 23:19:45 +09:00
bb24c95e71 delete files on user delete (#1452)
fixes #1451
(I did not do a cascade delete for 2 reasons: Sqlite does not support the migration easily to alter a foreign key AND files would be orphaned in the storage with no record in the db)
2020-04-09 22:17:06 +09:00
c7a4158a39 use payjoin key from constants 2020-04-09 14:07:26 +02:00
ed0e423aa7 Add payment link in checkout with payjoin indicator (#1449)
* Add payment link in checkout with payjoin indicator

* move to bottom
2020-04-09 20:44:08 +09:00
1c0d713b00 Catch all error thrown by EndAccept 2020-04-09 20:36:19 +09:00
70c80f4d44 Remove useless line 2020-04-09 20:27:24 +09:00
e3f6de8472 Remove warnings, replace BIP79 by Payjoin, Fix strange error in Accept loop 2020-04-09 20:25:17 +09:00
95644f8884 Fix tests 2020-04-09 19:44:16 +09:00
f57db12c09 Document downside of socks proxy 2020-04-09 18:56:30 +09:00
0d821ff4db Connection: close when using the internal proxy, fix gateway errors with connections in limbo 2020-04-09 18:49:30 +09:00
6927d81175 Implement Http Tor proxy as a internal http proxy 2020-04-09 17:38:55 +09:00
e183714475 Add Tor Http Client Factory (#1445)
* WIP: Add Tor Http Client Factory

This PR adds a Tor Http Client Factory so that we can do HTTP requests over socks5( which we usually use tor's socks5).
Using it for payjoin when possible.

Currently have an issue where a 503 is always returned.  Must be something wrong with my tor config or the socks proxy lib Im using

* fix

* remove external dependency

* make payjoin client use tor client if available

* fix docker test

* use tor client only if available and necessary

* remove bip 79 mention
2020-04-08 22:40:41 +09:00
6602823067 Refactor the input type detection 2020-04-08 22:14:16 +09:00
111feeb673 Merge pull request #1441 from Kukks/payjoin/p2sh
Payjoin: P2SH support
2020-04-08 22:00:07 +09:00
3bf1b78b33 fix 2020-04-08 14:32:29 +02:00
751ccc333f make test less slimfy 2020-04-08 14:32:29 +02:00
624e6e4744 adapt 2020-04-08 14:32:29 +02:00
73b13c750d add P2sh support 2020-04-08 14:32:29 +02:00
148b04e9ba allow changing the payjoin key easily later 2020-04-08 14:32:29 +02:00
32938479ac WIP: Payjoin: P2SH support 2020-04-08 14:32:29 +02:00
aae0086e68 Merge pull request #1443 from dennisreimann/wallet-view-improvements
Wallet view improvements
2020-04-08 21:25:31 +09:00
1f4556bd9d Merge pull request #1440 from dennisreimann/transactions-dropdowns
Fix transaction dropdowns
2020-04-08 21:24:23 +09:00
d7bb15cac3 Merge pull request #1442 from dennisreimann/docker-bitcoin-generate-shell-script
Add bitcoin generate shell script
2020-04-08 21:22:47 +09:00
9a54445785 Merge pull request #1439 from Kukks/monero-fix
monero fixes
2020-04-08 21:11:27 +09:00
523edfef58 Fix wording for no vault connection 2020-04-08 13:29:54 +02:00
5a841216b8 Add checkbox coin selection (js version) 2020-04-08 13:29:16 +02:00
d6d58a98db Improve non-js coin selection 2020-04-08 13:15:03 +02:00
6a0cda69c9 Wallet view improvements
As brought up by @kukks with [this comment](https://github.com/btcpayserver/btcpayserver/pull/1434#issuecomment-609724703). These improvements can be applied across themes, so these fixes are separated from the originating PR.
Pure visual finetunings for the Coin Selection form and amount/fee rate links.
2020-04-08 12:38:26 +02:00
24691e5290 Bump NBitcoin and NBX 2020-04-08 19:34:12 +09:00
b203d369fb Fix payjoin tests 2020-04-08 18:24:04 +09:00
b1cc30d25d Fix sequence check on client 2020-04-08 17:51:22 +09:00
72e64885be Fix sequence check on client 2020-04-08 17:42:50 +09:00
f4a47f5197 Deterministically sort the UTXOs to select 2020-04-08 13:46:11 +09:00
fe45152529 Add bitcoin generate shell script
The shell equivalent to the existing powershell script.
2020-04-07 18:13:47 +02:00
9a9773853e Fix bug in payjoin receiver where too much fee could be substracted from receiver 2020-04-07 20:04:08 +09:00
9d2ab8b154 The payjoin receiver can inject a fake change 2020-04-07 18:14:31 +09:00
ba2184e21a Do not remove outputs in payjoin tx 2020-04-07 15:10:19 +09:00
829b0dd5e2 Fix transaction dropdowns
As brought up by @kukks with [this comment](https://github.com/btcpayserver/btcpayserver/pull/1434#issuecomment-609720019). The problem exists across themes, so the fix is separated from the originating PR.
2020-04-06 18:16:41 +02:00
9fc451c9ca Make stronger check on fee, let the merchant make bigger transaction if he pays the fee 2020-04-06 23:24:51 +09:00
452568e740 monero fixes 2020-04-06 16:12:48 +02:00
5503132ffc Fix vue-i18n var substitution error in checkout
fixes #1438
2020-04-06 13:38:58 +02:00
17a6b7d34f Rename an error of pj to unsupported-input 2020-04-06 20:27:48 +09:00
69ad9edc9a Check pj with 1 sat/b 2020-04-06 20:26:50 +09:00
80bb959ac3 Merge pull request #1415 from Kukks/wallet/camera
Scan address/bip21 with camera
2020-04-06 20:07:32 +09:00
1e0587af26 Make sure tests use fixed fees 2020-04-06 19:18:49 +09:00
16e35e8b55 update html styles 2020-04-06 11:51:01 +02:00
8278926e42 change wallet send buttons 2020-04-06 11:51:01 +02:00
1debbc3cdb Change error messages 2020-04-06 11:51:01 +02:00
65c99ead1d cleanup 2020-04-06 11:51:00 +02:00
2693dacae6 Scan address/bip21 with camera 2020-04-06 11:51:00 +02:00
7ce614f1c4 Merge pull request #1435 from btcpayserver/pr/dark-checkout
Dark checkout theme
2020-04-06 17:46:17 +09:00
79a0f97abb Merge pull request #1432 from Kukks/api/permission-blob
GreenField: Switch to Blob for API Keys
2020-04-06 17:42:32 +09:00
670e0ee7df Merge pull request #1436 from NicolasDorier/remove-rider-errors
Remove bugs reported by Rider
2020-04-06 17:36:07 +09:00
3f231a8894 Merge pull request #1437 from dennisreimann/manage-store-spacings
Improve section spacings on manage store page
2020-04-06 17:35:05 +09:00
f5dfee7642 Improve section spacings on manage store page 2020-04-06 10:12:05 +02:00
ab120c5dcb Fix tests 2020-04-06 17:05:03 +09:00
f085a5618b Defaulting Powered by BtcPayServer link to green in light and dark theme 2020-04-05 23:21:14 -05:00
d939baac84 Give more information to the user if payjoin fails 2020-04-06 13:19:51 +09:00
41d70e8462 Tweaking black background on Pay with and Totals line, colors for dropdowns 2020-04-05 23:09:31 -05:00
9af7edf8b8 Add comments to explain the Payment's ReceivedTime 2020-04-06 12:23:56 +09:00
01a8c20ee8 Use better time precision for time in PaymentEntity 2020-04-05 23:57:43 +09:00
4c966e2a09 Refactor the detection of the payjoin payment 2020-04-05 22:44:34 +09:00
42aead3c89 A replacement payment should have the same fee as the replaced one 2020-04-05 20:48:00 +09:00
a348960041 Make CanChangeNetworkFeeMode more resilient 2020-04-05 20:00:28 +09:00
c737a25234 Add logs to test CanChangeNetworkFeeMode 2020-04-05 18:54:12 +09:00
a01b2e4a83 Small optimization for faster AddDerivationScheme 2020-04-05 18:35:29 +09:00
5f838db281 Merge pull request #1431 from Kukks/api/merge-multiple-swagger
Swagger Generator: Merge multiple documents
2020-04-05 17:36:04 +09:00
08beffb005 Make sure FindPaymentViaPolling does not requests over and over the same coins 2020-04-05 16:50:19 +09:00
76b919d887 make swagger test use live endpoint 2020-04-05 09:43:49 +02:00
c106ac2c42 Adding margin around QR code 2020-04-04 23:44:47 -05:00
4a1fb71e09 Do not print dangerous info in the logs 2020-04-05 12:33:10 +09:00
98e2baae19 Remove bugs reported by Rider 2020-04-05 12:30:23 +09:00
963c69a0e0 Merge pull request #1321 from Kukks/bpu
BIP79
2020-04-05 12:10:55 +09:00
fd026a9733 Refactor server-side 2020-04-05 12:02:36 +09:00
e76785a64e Removing background gradient
It's not smooth on most displays
2020-04-04 18:03:37 -05:00
1a8f222e46 Migrating fixes on default theme back to legacy style 2020-04-04 17:54:13 -05:00
24d26d7a44 Streamlining btnGroupLnd styling 2020-04-04 17:49:43 -05:00
c86370c25a Extracting css class for Powered by BtcPayServer 2020-04-04 17:28:00 -05:00
20cba1d3a1 Tweaking colors on language dropdown hover 2020-04-04 17:16:09 -05:00
3e2efc7f27 Adding first iteration of dark design 2020-04-04 16:47:37 -05:00
d2c29aaec6 Tweaking text opacity, recommended fee line consistency 2020-04-04 16:47:26 -05:00
bb1c5dead5 Moving selection slider to bottom to comply with new design 2020-04-04 16:32:44 -05:00
41cc79600a Swagger Generator: Merge multiple documents
It's becoming very hard to edit the swagger file as it grows (especially with multiple PRs altering it). This PR allows the swagger file to be generated from multiple jsons instead which are merged in the controller.
2020-04-04 14:22:07 +02:00
238d4fceea Merge pull request #1426 from Kukks/fix-dead-link-tester
Fix dead link tester
2020-04-04 14:21:22 +02:00
c6d75de3d7 GreenField: Switch to Blob for API Keys 2020-04-02 09:32:22 +02:00
9e1ae29600 change broadcast button style 2020-03-31 14:57:24 +02:00
d60b00e8cd Merge pull request #1425 from Kukks/coin-selection-fix
Fix coin selection filter bug
2020-03-31 18:43:41 +09:00
49786f4195 add bitpay to blacklist 2020-03-31 11:13:22 +02:00
7b6eae6053 Fixing CheckNoDeadLink test now that btse blocks our call from circleci 2020-03-31 11:12:01 +02:00
a408541eb3 Fix coin selection filter bug 2020-03-31 11:07:57 +02:00
1ba25448cc Merge pull request #1423 from btcpayserver/feat/new-invoice
New invoice design
2020-03-31 17:33:10 +09:00
4d2e59e1a1 Change flow of payjoin in wallet + fix tests 2020-03-30 13:27:04 +02:00
7b4f686add Moving default theme back to root now that we don't have separate setting 2020-03-30 01:38:45 -05:00
ee0ef2881a Removing extra setting, depending on Custom CSS for bundled themes 2020-03-28 14:10:18 -06:00
22f79e9fe4 Merge pull request #1401 from Kukks/wallet-receive-improve
Allow wallet receive to generate new addresses
2020-03-29 00:38:32 +09:00
fdad5a47d5 Reformating file according to project standards 2020-03-27 18:04:30 -05:00
e32f3cbf80 Preserving legacy margin for previous CustomLogoLinks 2020-03-27 18:04:05 -05:00
b56d026fdb small changes 2020-03-27 14:59:00 +01:00
64717328f6 check output sum of proposed payjoin 2020-03-27 10:45:13 +01:00
065be9be64 Revert back to original transaction if payjoined tx does not work 2020-03-27 10:45:13 +01:00
10fcfab233 remove bpu TempData 2020-03-27 10:45:13 +01:00
ff9865c516 fix tor docker 2020-03-27 10:45:13 +01:00
59bae2c337 ToHashSet 2020-03-27 10:45:13 +01:00
89d9793692 remove support from old ledger websocket 2020-03-27 10:45:13 +01:00
23b2f55b47 use nameof 2020-03-27 10:45:13 +01:00
886510c2e1 remove tor for now 2020-03-27 10:45:13 +01:00
2b11b43d6d NRE fix 2020-03-27 10:45:13 +01:00
d90ffb2254 move payjoin settings to store settings from checkout experience 2020-03-27 10:45:13 +01:00
fc88a867fa try fix test 2020-03-27 10:45:13 +01:00
e4cb1a875b Remove tor client factory 2020-03-27 10:45:13 +01:00
1a62ee9260 try fix tor socks5 connection 2020-03-27 10:45:12 +01:00
56d5e6f99f fixes 2020-03-27 10:45:12 +01:00
f1821636db fix tor client creator 2020-03-27 10:45:12 +01:00
2e3a0706ee RBF Protection & Handling 2020-03-27 10:45:12 +01:00
89da4184ff BIP79 Support 2020-03-27 10:45:12 +01:00
1895e154d9 Add missing file 2020-03-27 18:42:59 +09:00
6d7b57ea3b A api key can always revoke itself, add a route to delete any api key 2020-03-27 14:46:51 +09:00
39a8c3fe47 GreenField: Create API Key 2020-03-27 14:17:31 +09:00
927c09ff7b Merge pull request #1418 from NicolasDorier/refactor/greenfield-classes
Rename classes in Greenfield Authentication, use different AuthenticationScheme for Basic versus APIKey
2020-03-27 13:41:32 +09:00
08abda1522 Restrict authentication to the APIController to GreenFieldAPIKeys 2020-03-27 13:34:03 +09:00
d219ba5d32 Split the greenfield authhandler in two classes 2020-03-27 13:06:41 +09:00
afdee9d8a2 Move directories, rename controllers 2020-03-27 12:58:45 +09:00
ac14f199e4 Renaming GreenField classes 2020-03-27 12:55:21 +09:00
76818fa385 Rename API Keys folder to GreenField 2020-03-27 12:44:21 +09:00
49be370e51 Rename GreenField auth to APIKey auth in swagger doc 2020-03-27 12:43:06 +09:00
fbe89f1784 Merge pull request #1416 from pavlenex/invoice-summary
Rename Paid summary to Invoice Summary
2020-03-27 12:32:15 +09:00
b7afcb90a2 Tweaking checkout logo to be set from css 2020-03-26 19:49:04 -05:00
a6ac67963e Adding setting to CheckoutExperience to pick checkout theme 2020-03-26 19:49:00 -05:00
bde8ed7aa2 Extracting checkout theme css as separate link 2020-03-26 19:48:54 -05:00
ca234838a3 Tweaks for close button, recommended fee 2020-03-26 19:48:48 -05:00
d54d340bef Adjusting new color scheme on invoice 2020-03-26 19:48:42 -05:00
a926a5eedf Fix warning 2020-03-26 22:56:30 +09:00
0df5e7d7a3 Fix clone button in edit payment request (Fix #1414) 2020-03-26 22:54:47 +09:00
034fb4ec80 Rename Paid summary to Invoice Summary 2020-03-26 12:50:08 +01:00
69482eb4fb Allow wallet receive to generate new addresses 2020-03-25 17:24:41 +01:00
10e52f08be Prevent NRE exception 2020-03-26 01:21:47 +09:00
5565d8dae5 Catch error with bitflyer 2020-03-26 01:21:46 +09:00
c633402fe2 Merge pull request #1410 from Kukks/coin-selection-fix
fix coin selection
2020-03-26 01:08:53 +09:00
0688feea3c Fix docker files 2020-03-26 00:57:54 +09:00
c906fd42df Add bitflyer direct integration 2020-03-26 00:48:01 +09:00
6468b39121 try fix test again 2020-03-25 14:11:38 +01:00
d0a95f5a69 fix coin selection 2020-03-25 14:11:38 +01:00
e36338d903 Merge pull request #1403 from Kukks/basic-auth
Greenfield API: Basic Auth
2020-03-25 21:00:14 +09:00
e596513fc1 Merge pull request #1409 from Kukks/fix-link-test
Fix Link checker test
2020-03-25 19:33:50 +09:00
77588182b9 Make validation uniform 2020-03-24 23:44:26 -05:00
ca00caa4a4 Do not allow 0 amount invocies for crowdfund and payment requests 2020-03-24 23:43:56 -05:00
36bd76248b Allow Pay Button to work on Apps
This PR allows you to use the pay button generator to create buttons that target apps. This means that you can generate an invoice that is linked to an item on the POS/Crowdfund (targeting the item is optional). The POS/Crowdfund item amount -> invoice creation amount validation works too so that the user cannot modify the amount of a perk using just html ( fixes #1392 )
2020-03-24 23:43:47 -05:00
f0f05acdfd Let 0 amount invoices pass through and allow email to be set when required but paid
@ketominer @Askuwheteau @IAskuwheteau
2020-03-24 23:43:19 -05:00
6df7ffd7e2 lol windows phone 2020-03-24 08:55:47 +01:00
91924512e6 Fix Link checker test 2020-03-24 08:00:47 +01:00
7899c2d5c5 fix test 2020-03-23 21:18:40 +01:00
56ba834ca2 Consolidate auth into one 2020-03-23 16:46:49 +01:00
d57fdd4785 Remove useless delay in tests 2020-03-23 17:19:19 +09:00
805e1f53b3 Test Wallet Receive, Send with NBX, Coin selection 2020-03-23 15:46:54 +09:00
40953ef2c6 Merge pull request #1399 from Kukks/coin-selection
New feature: Coin Selection
2020-03-23 14:05:11 +09:00
ff055c08fb Merge pull request #1404 from btcpayserver/pr/can-manage-wallet
Additional logging and tweaking for CanManageWallet test
2020-03-22 13:53:29 +09:00
f3d5cf3622 Additional logging and tweaking for CanManageWallet test 2020-03-21 12:23:02 -05:00
e48e8c34d9 fix tst 2020-03-20 17:59:14 +01:00
98a48cd0a5 fix swagger validation test 2020-03-20 17:37:39 +01:00
f8f358ebdb add to client, fix tests and doc 2020-03-20 17:14:47 +01:00
9d99c32305 add basic auth for greenfield 2020-03-20 14:07:31 +01:00
478b1463ff Improve documentation 2020-03-20 20:26:36 +09:00
7e7f0053e2 Improve documentation 2020-03-20 20:25:10 +09:00
9a940a044e Fix tests 2020-03-20 20:00:30 +09:00
d2864ccd7c Make sure ApiKeyData set all the fields, remove UserId 2020-03-20 20:00:05 +09:00
ad4dbdad6d Fix the PermissionJsonConverter 2020-03-20 19:57:00 +09:00
094307d688 Remove warning and improve UI of permission selection 2020-03-20 19:39:02 +09:00
53e7c84e73 Fix tests 2020-03-20 18:56:30 +09:00
2a865284da Merge pull request #1402 from Kukks/liquid-assets-divisibility
Fix liquid asset BIP21 decimal precision
2020-03-20 18:39:05 +09:00
4666238e38 Fix build 2020-03-20 18:38:21 +09:00
b54a7b80e3 add tests and fix 2020-03-20 09:31:22 +01:00
432d6bb261 Update documentation 2020-03-20 14:33:11 +09:00
fb36ed2cae Fix tests 2020-03-20 14:07:42 +09:00
55516a3253 Remove excessive folders 2020-03-20 14:03:28 +09:00
a0e638d500 Switch from System.Text.Json to Newtonsoft, typify the BTCPayServer.Client 2020-03-20 14:01:51 +09:00
2def9e7bd3 fix build 2020-03-20 13:58:07 +09:00
0bfc12ae3d Fix build 2020-03-20 13:44:02 +09:00
318d826694 Rename Permissions.Can.. to Policies.Can.. 2020-03-20 13:41:47 +09:00
44b3bb34a4 Merge pull request #1400 from NicolasDorier/refactor/permissions
Refactor permissions of GreenField
2020-03-20 13:30:58 +09:00
46edc281b6 Fix tests 2020-03-20 13:22:10 +09:00
d72139c2c1 Fix liquid asset BIP21 decimal precision
The way liquid assets decimal precision works is just an ui layer. Each unit of an asset is actually 1sat.
Fixes https://github.com/Blockstream/green_android/issues/86
2020-03-19 16:00:33 +01:00
29a807696b Refactor permissions of GreenField 2020-03-19 23:43:51 +09:00
517c65f1fc make no js version a littler better 2020-03-19 10:08:33 +01:00
8f18be727b add clear option 2020-03-19 10:02:31 +01:00
d6c66d0c03 New feature: Coin Selection
This opt-in feature allows you to select which utxos you want to use for a specific transaction.
2020-03-19 09:44:47 +01:00
eac33d494a Add logs 2020-03-19 13:34:11 +09:00
2105b44610 Make sure the create user is respecting the disable-registration settings 2020-03-19 13:30:53 +09:00
ab74013a05 Merge pull request #1398 from btcpayserver/pr/fix-tests
Adding loggin in CanManageWallet test, fixing UserControllerTests
2020-03-19 13:15:17 +09:00
967b02e373 Commenting out conflicting check 2020-03-18 19:17:15 -05:00
8432cd5477 Adding new check for expected behavior in UsersControllerTests 2020-03-18 19:01:27 -05:00
ccfca65c41 Reverting changes to UsersController because of CanCreateUsersViaAPI test 2020-03-18 18:55:45 -05:00
0a8abaf7d5 Refactoring if condition to ensure CanCreateUser permission
Fixing UsersControllerTests
2020-03-18 18:40:21 -05:00
47c1164003 Adding logging to detect failure of CanManageWallet test
If all logs are present it's possibly issue with TempData
2020-03-18 18:17:21 -05:00
65d26ad8a1 improve redoc documentation 2020-03-18 23:35:17 +09:00
0a0d8d53a4 Improve redoc 2020-03-18 23:30:27 +09:00
e50e3f662d Can create user without authentication if there is no admin 2020-03-18 23:10:15 +09:00
540a31207e Properly validate create user input 2020-03-18 20:51:50 +09:00
132c36df7b Remove useless routes and info in swagger 2020-03-18 20:25:54 +09:00
e351e0c9ea Remove dependency on NSwag 2020-03-18 20:08:09 +09:00
8d7b9fcef2 Merge pull request #1390 from Kukks/api/user-create
Greenfield API: Create User
2020-03-18 16:26:10 +09:00
6e1f3989e8 remove special case 2020-03-18 08:10:35 +01:00
e99767c7e2 Greenfield API: Create User
Slightly big PR because I started refactoring to reduce code duplication between the UI based business logic and the api one.
2020-03-17 08:21:27 +01:00
c85fb3e89f Remove ndax from test suite (crashing exchange) 2020-03-17 13:19:55 +09:00
348934488d Refactor tests for greenfield 2020-03-16 16:36:55 +09:00
6c8918a308 Merge pull request #1389 from Kukks/api/god-mode
Greenfield API: God Mode
2020-03-16 16:29:19 +09:00
ff2ea5815c add else tests 2020-03-16 08:13:44 +01:00
cc0202ecb3 fix test 2020-03-13 08:00:04 +01:00
0c065df4bd Greenfield API: God Mode
When the `ServerManagement` permission is granted, you should be able to do everything in the system.
Maybe I should rename it to GodMode as a permission to not have any confusion with managing server settings (currently `ServerManagement`)?
2020-03-12 18:43:57 +01:00
b5664dac81 Merge pull request #1387 from Kukks/api/users-get-current
Greenfield API: Get current User
2020-03-12 23:20:18 +09:00
8173296c96 Greenfield API: Get current User
Builds on #1368
This PR adds a new endpoint: Get current user.. It only returns the current user's id and email for now( let's extend later)
It also adds a new permission: `ProfileManagement` which is needed for this endpoint (and for update endpoints later)
2020-03-12 14:59:24 +01:00
71a00c0e67 Merge pull request #1384 from Kukks/api/authorize-ui
Make api docs only available after login
2020-03-12 12:00:00 +09:00
70b172addc Make api docs only available after login 2020-03-11 18:05:40 +01:00
2002c6750b target netstandard2.1 for Client 2020-03-11 16:54:53 +01:00
786be9d1f5 fix tests 2020-03-11 16:54:53 +01:00
233fa8a4a1 BTCPayServer.Client library + Revoke API Key 2020-03-11 16:54:53 +01:00
c74f52a61c Merge pull request #1383 from Kukks/fix-tests
fix e2e tests
2020-03-12 00:53:44 +09:00
245507f821 fix e2e tests 2020-03-11 16:52:29 +01:00
5495c4b5d3 Merge pull request #1382 from NicolasDorier/betterrbf
Simplify RBF handling, and handle case of double spend happening outs…
2020-03-11 22:41:46 +09:00
afd2c8e3d7 Bump nbx 2020-03-11 22:32:53 +09:00
c8e1db2102 Better event messages 2020-03-11 21:11:07 +09:00
95f859b6db Simplify RBF handling, and handle case of double spend happening outside of wallet (Fix #1375) 2020-03-11 21:05:12 +09:00
6bf7ef0798 Revert "Simplify RBF handling, and handle case of double spend happening outside of wallet (Fix #1375)"
This reverts commit 42152050a3786bd3db103220e1a45b60c9fcddaf.
2020-03-11 20:57:19 +09:00
42152050a3 Simplify RBF handling, and handle case of double spend happening outside of wallet (Fix #1375) 2020-03-11 20:46:37 +09:00
67befcc629 bump 2020-03-10 22:48:17 +09:00
3cdf881438 bump lightning libraries 2020-03-10 22:31:05 +09:00
153992a458 Use good rng for generating API keys 2020-03-10 21:30:46 +09:00
691a8d6fd8 Fix warnings 2020-03-10 21:28:00 +09:00
a9bf843be0 Bump various libraries 2020-03-10 21:24:22 +09:00
60e5afe690 Merge pull request #1379 from Kukks/fix-cf
fix duplicate key error in crowdfunding
2020-03-10 20:58:09 +09:00
980bedf301 Merge pull request #1378 from pavlenex/supporter-btse
Add new supporter to readme and front page
2020-03-10 20:18:40 +09:00
6f6e8ba1a1 fix duplicate key error in crowdfunding 2020-03-10 11:20:05 +01:00
d3af82e38b Add btse to readme and front page 2020-03-10 10:28:15 +01:00
65afc9f7b2 Make sure dashboard is initialized from the beginning 2020-03-10 17:42:53 +09:00
2e630ac5d8 WaitSiteIsOperational should only wait full sync 2020-03-10 17:24:38 +09:00
e6acc19bcc Add a test catching expirationTime bug (#1336) 2020-03-10 17:11:15 +09:00
c598a1827f Remove misleading error message (Fix #1377) 2020-03-10 16:33:50 +09:00
1edd19f403 bump 2020-03-10 15:54:02 +09:00
1052e9a035 Merge pull request #1376 from Kukks/fix-sqllite-again
fix sqlite again
2020-03-10 15:52:38 +09:00
5e15dd97b3 fix sqlite again
closes #1287
Seems like a merge conflict removed the fix for sqlite datetimeoffsets
2020-03-09 09:44:44 +01:00
7763ad5b2c Merge pull request #1372 from btcpayserver/pr/flaky-tests
Fixing ocassional CanManageWallet Selenium test fails
2020-03-06 19:22:43 +09:00
4e826553f8 Fixing ocassional CanManageWallet Selenium test fails
Looking through logs it seems like Generate button is never clicked, which can happen if modal is not displayed
https://circleci.com/gh/btcpayserver/btcpayserver/6167
2020-03-06 02:06:32 -06:00
782 changed files with 39462 additions and 9634 deletions

View File

@ -119,22 +119,23 @@ workflows:
# ignore any commit on any branch by default
branches:
ignore: /.*/
# only act on version tags v1.0.0.88
# only act on version tags v1.0.0.88 or v1.0.2-1
# OR feature tags like vlndseedbackup
tags:
only: /(v[1-9]+(\.[0-9]+)*)|(v[a-z]+)/
only: /(v[1-9]+(\.[0-9]+)*(-[0-9]+)?)|(v[a-z]+)/
- arm32v7:
filters:
branches:
ignore: /.*/
tags:
only: /(v[1-9]+(\.[0-9]+)*)|(v[a-z]+)/
only: /(v[1-9]+(\.[0-9]+)*(-[0-9]+)?)|(v[a-z]+)/
- arm64v8:
filters:
branches:
ignore: /.*/
tags:
only: /(v[1-9]+(\.[0-9]+)*)|(v[a-z]+)/
only: /(v[1-9]+(\.[0-9]+)*(-[0-9]+)?)|(v[a-z]+)/
- multiarch:
requires:
- amd64
@ -144,4 +145,4 @@ workflows:
branches:
ignore: /.*/
tags:
only: /(v[1-9]+(\.[0-9]+)*)|(v[a-z]+)/
only: /(v[1-9]+(\.[0-9]+)*(-[0-9]+)?)|(v[a-z]+)/

View File

@ -10,8 +10,9 @@ root = true
insert_final_newline = true
indent_style = space
indent_size = 4
charset = utf-8
[project.json]
[launchSettings.json]
indent_size = 2
# C# files
@ -146,4 +147,4 @@ indent_size = 2
[*.sh]
end_of_line = lf
[*.{cmd, bat}]
end_of_line = crlf
end_of_line = crlf

View File

@ -0,0 +1,13 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard2.1</TargetFramework>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="NBitcoin" Version="5.0.43" />
<PackageReference Include="BTCPayServer.Lightning.Common" Version="1.2.0" />
<PackageReference Include="Newtonsoft.Json" Version="12.0.3" />
</ItemGroup>
</Project>

View File

@ -0,0 +1,39 @@
using System;
using System.Net.Http;
using System.Threading;
using System.Threading.Tasks;
using BTCPayServer.Client.Models;
namespace BTCPayServer.Client
{
public partial class BTCPayServerClient
{
public virtual async Task<ApiKeyData> GetCurrentAPIKeyInfo(CancellationToken token = default)
{
var response = await _httpClient.SendAsync(CreateHttpRequest("api/v1/api-keys/current"), token);
return await HandleResponse<ApiKeyData>(response);
}
public virtual async Task<ApiKeyData> CreateAPIKey(CreateApiKeyRequest request, CancellationToken token = default)
{
if (request == null)
throw new ArgumentNullException(nameof(request));
var response = await _httpClient.SendAsync(CreateHttpRequest("api/v1/api-keys", bodyPayload: request, method: HttpMethod.Post), token);
return await HandleResponse<ApiKeyData>(response);
}
public virtual async Task RevokeCurrentAPIKeyInfo(CancellationToken token = default)
{
var response = await _httpClient.SendAsync(CreateHttpRequest("api/v1/api-keys/current", null, HttpMethod.Delete), token);
await HandleResponse(response);
}
public virtual async Task RevokeAPIKey(string apikey, CancellationToken token = default)
{
if (apikey == null)
throw new ArgumentNullException(nameof(apikey));
var response = await _httpClient.SendAsync(CreateHttpRequest($"api/v1/api-keys/{apikey}", null, HttpMethod.Delete), token);
await HandleResponse(response);
}
}
}

View File

@ -0,0 +1,24 @@
using System;
using System.Collections.Generic;
namespace BTCPayServer.Client
{
public partial class BTCPayServerClient
{
public static Uri GenerateAuthorizeUri(Uri btcpayHost, string[] permissions, bool strict = true,
bool selectiveStores = false)
{
var result = new UriBuilder(btcpayHost);
result.Path = "api-keys/authorize";
AppendPayloadToQuery(result,
new Dictionary<string, object>()
{
{"strict", strict}, {"selectiveStores", selectiveStores}, {"permissions", permissions}
});
return result.Uri;
}
}
}

View File

@ -0,0 +1,15 @@
using System.Threading;
using System.Threading.Tasks;
using BTCPayServer.Client.Models;
namespace BTCPayServer.Client
{
public partial class BTCPayServerClient
{
public virtual async Task<ApiHealthData> GetHealth(CancellationToken token = default)
{
var response = await _httpClient.SendAsync(CreateHttpRequest("api/v1/health"), token);
return await HandleResponse<ApiHealthData>(response);
}
}
}

View File

@ -0,0 +1,91 @@
using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Threading;
using System.Threading.Tasks;
using BTCPayServer.Client.Models;
namespace BTCPayServer.Client
{
public partial class BTCPayServerClient
{
public async Task<LightningNodeInformationData> GetLightningNodeInfo(string cryptoCode,
CancellationToken token = default)
{
var response = await _httpClient.SendAsync(
CreateHttpRequest($"api/v1/server/lightning/{cryptoCode}/info",
method: HttpMethod.Get), token);
return await HandleResponse<LightningNodeInformationData>(response);
}
public async Task ConnectToLightningNode(string cryptoCode, ConnectToNodeRequest request,
CancellationToken token = default)
{
if (request == null)
throw new ArgumentNullException(nameof(request));
var response = await _httpClient.SendAsync(
CreateHttpRequest($"api/v1/server/lightning/{cryptoCode}/connect", bodyPayload: request,
method: HttpMethod.Post), token);
await HandleResponse(response);
}
public async Task<IEnumerable<LightningChannelData>> GetLightningNodeChannels(string cryptoCode,
CancellationToken token = default)
{
var response = await _httpClient.SendAsync(
CreateHttpRequest($"api/v1/server/lightning/{cryptoCode}/channels",
method: HttpMethod.Get), token);
return await HandleResponse<IEnumerable<LightningChannelData>>(response);
}
public async Task<string> OpenLightningChannel(string cryptoCode, OpenLightningChannelRequest request,
CancellationToken token = default)
{
var response = await _httpClient.SendAsync(
CreateHttpRequest($"api/v1/server/lightning/{cryptoCode}/channels", bodyPayload: request,
method: HttpMethod.Post), token);
return await HandleResponse<string>(response);
}
public async Task<string> GetLightningDepositAddress(string cryptoCode, CancellationToken token = default)
{
var response = await _httpClient.SendAsync(
CreateHttpRequest($"api/v1/server/lightning/{cryptoCode}/address", method: HttpMethod.Post), token);
return await HandleResponse<string>(response);
}
public async Task PayLightningInvoice(string cryptoCode, PayLightningInvoiceRequest request,
CancellationToken token = default)
{
if (request == null)
throw new ArgumentNullException(nameof(request));
var response = await _httpClient.SendAsync(
CreateHttpRequest($"api/v1/server/lightning/{cryptoCode}/invoices/pay", bodyPayload: request,
method: HttpMethod.Post), token);
await HandleResponse(response);
}
public async Task<LightningInvoiceData> GetLightningInvoice(string cryptoCode,
string invoiceId, CancellationToken token = default)
{
if (invoiceId == null)
throw new ArgumentNullException(nameof(invoiceId));
var response = await _httpClient.SendAsync(
CreateHttpRequest($"api/v1/server/lightning/{cryptoCode}/invoices/{invoiceId}",
method: HttpMethod.Get), token);
return await HandleResponse<LightningInvoiceData>(response);
}
public async Task<LightningInvoiceData> CreateLightningInvoice(string cryptoCode, CreateLightningInvoiceRequest request,
CancellationToken token = default)
{
if (request == null)
throw new ArgumentNullException(nameof(request));
var response = await _httpClient.SendAsync(
CreateHttpRequest($"api/v1/server/lightning/{cryptoCode}/invoices", bodyPayload: request,
method: HttpMethod.Post), token);
return await HandleResponse<LightningInvoiceData>(response);
}
}
}

View File

@ -0,0 +1,92 @@
using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Threading;
using System.Threading.Tasks;
using BTCPayServer.Client.Models;
namespace BTCPayServer.Client
{
public partial class BTCPayServerClient
{
public async Task<LightningNodeInformationData> GetLightningNodeInfo(string storeId, string cryptoCode,
CancellationToken token = default)
{
var response = await _httpClient.SendAsync(
CreateHttpRequest($"api/v1/stores/{storeId}/lightning/{cryptoCode}/info",
method: HttpMethod.Get), token);
return await HandleResponse<LightningNodeInformationData>(response);
}
public async Task ConnectToLightningNode(string storeId, string cryptoCode, ConnectToNodeRequest request,
CancellationToken token = default)
{
if (request == null)
throw new ArgumentNullException(nameof(request));
var response = await _httpClient.SendAsync(
CreateHttpRequest($"api/v1/stores/{storeId}/lightning/{cryptoCode}/connect", bodyPayload: request,
method: HttpMethod.Post), token);
await HandleResponse(response);
}
public async Task<IEnumerable<LightningChannelData>> GetLightningNodeChannels(string storeId, string cryptoCode,
CancellationToken token = default)
{
var response = await _httpClient.SendAsync(
CreateHttpRequest($"api/v1/stores/{storeId}/lightning/{cryptoCode}/channels",
method: HttpMethod.Get), token);
return await HandleResponse<IEnumerable<LightningChannelData>>(response);
}
public async Task<string> OpenLightningChannel(string storeId, string cryptoCode, OpenLightningChannelRequest request,
CancellationToken token = default)
{
var response = await _httpClient.SendAsync(
CreateHttpRequest($"api/v1/stores/{storeId}/lightning/{cryptoCode}/channels", bodyPayload: request,
method: HttpMethod.Post), token);
return await HandleResponse<string>(response);
}
public async Task<string> GetLightningDepositAddress(string storeId, string cryptoCode,
CancellationToken token = default)
{
var response = await _httpClient.SendAsync(
CreateHttpRequest($"api/v1/stores/{storeId}/lightning/{cryptoCode}/address", method: HttpMethod.Post),
token);
return await HandleResponse<string>(response);
}
public async Task PayLightningInvoice(string storeId, string cryptoCode, PayLightningInvoiceRequest request,
CancellationToken token = default)
{
if (request == null)
throw new ArgumentNullException(nameof(request));
var response = await _httpClient.SendAsync(
CreateHttpRequest($"api/v1/stores/{storeId}/lightning/{cryptoCode}/invoices/pay", bodyPayload: request,
method: HttpMethod.Post), token);
await HandleResponse(response);
}
public async Task<LightningInvoiceData> GetLightningInvoice(string storeId, string cryptoCode,
string invoiceId, CancellationToken token = default)
{
if (invoiceId == null)
throw new ArgumentNullException(nameof(invoiceId));
var response = await _httpClient.SendAsync(
CreateHttpRequest($"api/v1/stores/{storeId}/lightning/{cryptoCode}/invoices/{invoiceId}",
method: HttpMethod.Get), token);
return await HandleResponse<LightningInvoiceData>(response);
}
public async Task<LightningInvoiceData> CreateLightningInvoice(string storeId, string cryptoCode,
CreateLightningInvoiceRequest request, CancellationToken token = default)
{
if (request == null)
throw new ArgumentNullException(nameof(request));
var response = await _httpClient.SendAsync(
CreateHttpRequest($"api/v1/stores/{storeId}/lightning/{cryptoCode}/invoices", bodyPayload: request,
method: HttpMethod.Post), token);
return await HandleResponse<LightningInvoiceData>(response);
}
}
}

View File

@ -0,0 +1,59 @@
using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Threading;
using System.Threading.Tasks;
using BTCPayServer.Client.Models;
namespace BTCPayServer.Client
{
public partial class BTCPayServerClient
{
public virtual async Task<IEnumerable<PaymentRequestData>> GetPaymentRequests(string storeId,
CancellationToken token = default)
{
var response =
await _httpClient.SendAsync(CreateHttpRequest($"api/v1/stores/{storeId}/payment-requests"), token);
return await HandleResponse<IEnumerable<PaymentRequestData>>(response);
}
public virtual async Task<PaymentRequestData> GetPaymentRequest(string storeId, string paymentRequestId,
CancellationToken token = default)
{
var response = await _httpClient.SendAsync(
CreateHttpRequest($"api/v1/stores/{storeId}/payment-requests/{paymentRequestId}"), token);
return await HandleResponse<PaymentRequestData>(response);
}
public virtual async Task ArchivePaymentRequest(string storeId, string paymentRequestId,
CancellationToken token = default)
{
var response = await _httpClient.SendAsync(
CreateHttpRequest($"api/v1/stores/{storeId}/payment-requests/{paymentRequestId}",
method: HttpMethod.Delete), token);
await HandleResponse(response);
}
public virtual async Task<PaymentRequestData> CreatePaymentRequest(string storeId,
CreatePaymentRequestRequest request, CancellationToken token = default)
{
if (request == null)
throw new ArgumentNullException(nameof(request));
var response = await _httpClient.SendAsync(
CreateHttpRequest($"api/v1/stores/{storeId}/payment-requests", bodyPayload: request,
method: HttpMethod.Post), token);
return await HandleResponse<PaymentRequestData>(response);
}
public virtual async Task<PaymentRequestData> UpdatePaymentRequest(string storeId, string paymentRequestId,
UpdatePaymentRequestRequest request, CancellationToken token = default)
{
if (request == null)
throw new ArgumentNullException(nameof(request));
var response = await _httpClient.SendAsync(
CreateHttpRequest($"api/v1/stores/{storeId}/payment-requests/{paymentRequestId}", bodyPayload: request,
method: HttpMethod.Put), token);
return await HandleResponse<PaymentRequestData>(response);
}
}
}

View File

@ -0,0 +1,61 @@
using System.Collections.Generic;
using System.Net.Http;
using System.Threading;
using System.Threading.Tasks;
using System.Web;
using BTCPayServer.Client.Models;
namespace BTCPayServer.Client
{
public partial class BTCPayServerClient
{
public async Task<PullPaymentData> CreatePullPayment(string storeId, CreatePullPaymentRequest request, CancellationToken cancellationToken = default)
{
var response = await _httpClient.SendAsync(CreateHttpRequest($"api/v1/stores/{HttpUtility.UrlEncode(storeId)}/pull-payments", bodyPayload: request, method: HttpMethod.Post), cancellationToken);
return await HandleResponse<PullPaymentData>(response);
}
public async Task<PullPaymentData> GetPullPayment(string pullPaymentId, CancellationToken cancellationToken = default)
{
var response = await _httpClient.SendAsync(CreateHttpRequest($"api/v1/pull-payments/{HttpUtility.UrlEncode(pullPaymentId)}", method: HttpMethod.Get), cancellationToken);
return await HandleResponse<PullPaymentData>(response);
}
public async Task<PullPaymentData[]> GetPullPayments(string storeId, bool includeArchived = false, CancellationToken cancellationToken = default)
{
Dictionary<string, object> query = new Dictionary<string, object>();
query.Add("includeArchived", includeArchived);
var response = await _httpClient.SendAsync(CreateHttpRequest($"api/v1/stores/{HttpUtility.UrlEncode(storeId)}/pull-payments", queryPayload: query, method: HttpMethod.Get), cancellationToken);
return await HandleResponse<PullPaymentData[]>(response);
}
public async Task ArchivePullPayment(string storeId, string pullPaymentId, CancellationToken cancellationToken = default)
{
var response = await _httpClient.SendAsync(CreateHttpRequest($"api/v1/stores/{HttpUtility.UrlEncode(storeId)}/pull-payments/{HttpUtility.UrlEncode(pullPaymentId)}", method: HttpMethod.Delete), cancellationToken);
await HandleResponse(response);
}
public async Task<PayoutData[]> GetPayouts(string pullPaymentId, bool includeCancelled = false, CancellationToken cancellationToken = default)
{
Dictionary<string, object> query = new Dictionary<string, object>();
query.Add("includeCancelled", includeCancelled);
var response = await _httpClient.SendAsync(CreateHttpRequest($"api/v1/pull-payments/{HttpUtility.UrlEncode(pullPaymentId)}/payouts", queryPayload: query, method: HttpMethod.Get), cancellationToken);
return await HandleResponse<PayoutData[]>(response);
}
public async Task<PayoutData> CreatePayout(string pullPaymentId, CreatePayoutRequest payoutRequest, CancellationToken cancellationToken = default)
{
var response = await _httpClient.SendAsync(CreateHttpRequest($"api/v1/pull-payments/{HttpUtility.UrlEncode(pullPaymentId)}/payouts", bodyPayload: payoutRequest, method: HttpMethod.Post), cancellationToken);
return await HandleResponse<PayoutData>(response);
}
public async Task CancelPayout(string storeId, string payoutId, CancellationToken cancellationToken = default)
{
var response = await _httpClient.SendAsync(CreateHttpRequest($"api/v1/stores/{HttpUtility.UrlEncode(storeId)}/payouts/{HttpUtility.UrlEncode(payoutId)}", method: HttpMethod.Delete), cancellationToken);
await HandleResponse(response);
}
public async Task<PayoutData> ApprovePayout(string storeId, string payoutId, ApprovePayoutRequest request, CancellationToken cancellationToken = default)
{
var response = await _httpClient.SendAsync(CreateHttpRequest($"api/v1/stores/{HttpUtility.UrlEncode(storeId)}/payouts/{HttpUtility.UrlEncode(payoutId)}", bodyPayload: request, method: HttpMethod.Post), cancellationToken);
return await HandleResponse<PayoutData>(response);
}
}
}

View File

@ -0,0 +1,15 @@
using System.Threading;
using System.Threading.Tasks;
using BTCPayServer.Client.Models;
namespace BTCPayServer.Client
{
public partial class BTCPayServerClient
{
public virtual async Task<ServerInfoData> GetServerInfo(CancellationToken token = default)
{
var response = await _httpClient.SendAsync(CreateHttpRequest("api/v1/server/info"), token);
return await HandleResponse<ServerInfoData>(response);
}
}
}

View File

@ -0,0 +1,51 @@
using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Threading;
using System.Threading.Tasks;
using BTCPayServer.Client.Models;
namespace BTCPayServer.Client
{
public partial class BTCPayServerClient
{
public virtual async Task<IEnumerable<StoreData>> GetStores(CancellationToken token = default)
{
var response = await _httpClient.SendAsync(CreateHttpRequest("api/v1/stores"), token);
return await HandleResponse<IEnumerable<StoreData>>(response);
}
public virtual async Task<StoreData> GetStore(string storeId, CancellationToken token = default)
{
var response = await _httpClient.SendAsync(
CreateHttpRequest($"api/v1/stores/{storeId}"), token);
return await HandleResponse<StoreData>(response);
}
public virtual async Task RemoveStore(string storeId, CancellationToken token = default)
{
var response = await _httpClient.SendAsync(
CreateHttpRequest($"api/v1/stores/{storeId}", method: HttpMethod.Delete), token);
await HandleResponse(response);
}
public virtual async Task<StoreData> CreateStore(CreateStoreRequest request, CancellationToken token = default)
{
if (request == null)
throw new ArgumentNullException(nameof(request));
var response = await _httpClient.SendAsync(CreateHttpRequest("api/v1/stores", bodyPayload: request, method: HttpMethod.Post), token);
return await HandleResponse<StoreData>(response);
}
public virtual async Task<StoreData> UpdateStore(string storeId, UpdateStoreRequest request, CancellationToken token = default)
{
if (request == null)
throw new ArgumentNullException(nameof(request));
if (storeId == null)
throw new ArgumentNullException(nameof(storeId));
var response = await _httpClient.SendAsync(CreateHttpRequest($"api/v1/stores/{storeId}", bodyPayload: request, method: HttpMethod.Put), token);
return await HandleResponse<StoreData>(response);
}
}
}

View File

@ -0,0 +1,23 @@
using System.Net.Http;
using System.Threading;
using System.Threading.Tasks;
using BTCPayServer.Client.Models;
namespace BTCPayServer.Client
{
public partial class BTCPayServerClient
{
public virtual async Task<ApplicationUserData> GetCurrentUser(CancellationToken token = default)
{
var response = await _httpClient.SendAsync(CreateHttpRequest("api/v1/users/me"), token);
return await HandleResponse<ApplicationUserData>(response);
}
public virtual async Task<ApplicationUserData> CreateUser(CreateApplicationUserRequest request,
CancellationToken token = default)
{
var response = await _httpClient.SendAsync(CreateHttpRequest("api/v1/users", null, request, HttpMethod.Post), token);
return await HandleResponse<ApplicationUserData>(response);
}
}
}

View File

@ -0,0 +1,131 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Text;
using System.Threading.Tasks;
using Newtonsoft.Json;
namespace BTCPayServer.Client
{
public partial class BTCPayServerClient
{
private readonly string _apiKey;
private readonly Uri _btcpayHost;
private readonly string _username;
private readonly string _password;
private readonly HttpClient _httpClient;
public Uri Host => _btcpayHost;
public string APIKey => _apiKey;
public BTCPayServerClient(Uri btcpayHost, HttpClient httpClient = null)
{
if (btcpayHost == null)
throw new ArgumentNullException(nameof(btcpayHost));
_btcpayHost = btcpayHost;
_httpClient = httpClient ?? new HttpClient();
}
public BTCPayServerClient(Uri btcpayHost, string APIKey, HttpClient httpClient = null)
{
_apiKey = APIKey;
_btcpayHost = btcpayHost;
_httpClient = httpClient ?? new HttpClient();
}
public BTCPayServerClient(Uri btcpayHost, string username, string password, HttpClient httpClient = null)
{
_apiKey = APIKey;
_btcpayHost = btcpayHost;
_username = username;
_password = password;
_httpClient = httpClient ?? new HttpClient();
}
protected async Task HandleResponse(HttpResponseMessage message)
{
if (message.StatusCode == System.Net.HttpStatusCode.UnprocessableEntity)
{
var err = JsonConvert.DeserializeObject<Models.GreenfieldValidationError[]>(await message.Content.ReadAsStringAsync());
;
throw new GreenFieldValidationException(err);
}
else if (message.StatusCode == System.Net.HttpStatusCode.BadRequest)
{
var err = JsonConvert.DeserializeObject<Models.GreenfieldAPIError>(await message.Content.ReadAsStringAsync());
throw new GreenFieldAPIException(err);
}
message.EnsureSuccessStatusCode();
}
protected async Task<T> HandleResponse<T>(HttpResponseMessage message)
{
await HandleResponse(message);
return JsonConvert.DeserializeObject<T>(await message.Content.ReadAsStringAsync());
}
protected virtual HttpRequestMessage CreateHttpRequest(string path,
Dictionary<string, object> queryPayload = null,
HttpMethod method = null)
{
UriBuilder uriBuilder = new UriBuilder(_btcpayHost) { Path = path };
if (queryPayload != null && queryPayload.Any())
{
AppendPayloadToQuery(uriBuilder, queryPayload);
}
var httpRequest = new HttpRequestMessage(method ?? HttpMethod.Get, uriBuilder.Uri);
if (_apiKey != null)
httpRequest.Headers.Authorization = new AuthenticationHeaderValue("token", _apiKey);
else if (!string.IsNullOrEmpty(_username))
{
httpRequest.Headers.Authorization = new AuthenticationHeaderValue("Basic", System.Convert.ToBase64String(Encoding.ASCII.GetBytes(_username + ":" + _password)));
}
return httpRequest;
}
protected virtual HttpRequestMessage CreateHttpRequest<T>(string path,
Dictionary<string, object> queryPayload = null,
T bodyPayload = default, HttpMethod method = null)
{
var request = CreateHttpRequest(path, queryPayload, method);
if (typeof(T).IsPrimitive || !EqualityComparer<T>.Default.Equals(bodyPayload, default(T)))
{
request.Content = new StringContent(JsonConvert.SerializeObject(bodyPayload), Encoding.UTF8, "application/json");
}
return request;
}
private static void AppendPayloadToQuery(UriBuilder uri, Dictionary<string, object> payload)
{
if (uri.Query.Length > 1)
uri.Query += "&";
foreach (KeyValuePair<string, object> keyValuePair in payload)
{
UriBuilder uriBuilder = uri;
if (!(keyValuePair.Value is string) && keyValuePair.Value.GetType().GetInterfaces().Contains((typeof(IEnumerable))))
{
foreach (var item in (IEnumerable)keyValuePair.Value)
{
uriBuilder.Query = uriBuilder.Query + Uri.EscapeDataString(keyValuePair.Key) + "=" +
Uri.EscapeDataString(item.ToString()) + "&";
}
}
else
{
uriBuilder.Query = uriBuilder.Query + Uri.EscapeDataString(keyValuePair.Key) + "=" +
Uri.EscapeDataString(keyValuePair.Value.ToString()) + "&";
}
}
uri.Query = uri.Query.Trim('&');
}
}
}

View File

@ -0,0 +1,15 @@
using System;
namespace BTCPayServer.Client
{
public class GreenFieldAPIException : Exception
{
public GreenFieldAPIException(Models.GreenfieldAPIError error) : base(error.Message)
{
if (error == null)
throw new ArgumentNullException(nameof(error));
APIError = error;
}
public Models.GreenfieldAPIError APIError { get; }
}
}

View File

@ -0,0 +1,28 @@
using System;
using System.Text;
using BTCPayServer.Client.Models;
namespace BTCPayServer.Client
{
public class GreenFieldValidationException : Exception
{
public GreenFieldValidationException(Models.GreenfieldValidationError[] errors) : base(BuildMessage(errors))
{
ValidationErrors = errors;
}
private static string BuildMessage(GreenfieldValidationError[] errors)
{
if (errors == null)
throw new ArgumentNullException(nameof(errors));
StringBuilder builder = new StringBuilder();
foreach (var error in errors)
{
builder.AppendLine($"{error.Path}: {error.Message}");
}
return builder.ToString();
}
public Models.GreenfieldValidationError[] ValidationErrors { get; }
}
}

View File

@ -0,0 +1,39 @@
using System;
using System.Globalization;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
namespace BTCPayServer.JsonConverters
{
public class DecimalStringJsonConverter : JsonConverter
{
public override bool CanConvert(Type objectType)
{
return (objectType == typeof(decimal) || objectType == typeof(decimal?));
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue,
JsonSerializer serializer)
{
JToken token = JToken.Load(reader);
switch (token.Type)
{
case JTokenType.Float:
case JTokenType.Integer:
case JTokenType.String:
return decimal.Parse(token.ToString(), CultureInfo.InvariantCulture);
case JTokenType.Null when objectType == typeof(decimal?):
return null;
default:
throw new JsonSerializationException("Unexpected token type: " +
token.Type);
}
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
if (value != null)
writer.WriteValue(((decimal)value).ToString(CultureInfo.InvariantCulture));
}
}
}

View File

@ -0,0 +1,15 @@
using System.Globalization;
using BTCPayServer.Lightning;
using Newtonsoft.Json;
namespace BTCPayServer.Client.JsonConverters
{
public class LightMoneyJsonConverter : BTCPayServer.Lightning.JsonConverters.LightMoneyJsonConverter
{
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
if (value != null)
writer.WriteValue(((LightMoney)value).MilliSatoshi.ToString(CultureInfo.InvariantCulture));
}
}
}

View File

@ -0,0 +1,25 @@
using System;
using System.Globalization;
using NBitcoin;
using Newtonsoft.Json;
namespace BTCPayServer.Client.JsonConverters
{
public class MoneyJsonConverter : NBitcoin.JsonConverters.MoneyJsonConverter
{
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
if (reader.TokenType == JsonToken.String)
{
return new Money(long.Parse((string)reader.Value));
}
return base.ReadJson(reader, objectType, existingValue, serializer);
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
if (value != null)
writer.WriteValue(((Money)value).Satoshi.ToString(CultureInfo.InvariantCulture));
}
}
}

View File

@ -0,0 +1,26 @@
using System;
using System.Diagnostics.CodeAnalysis;
using BTCPayServer.Lightning;
using NBitcoin.JsonConverters;
using Newtonsoft.Json;
namespace BTCPayServer.Client.JsonConverters
{
public class NodeUriJsonConverter : JsonConverter<NodeInfo>
{
public override NodeInfo ReadJson(JsonReader reader, Type objectType, [AllowNull] NodeInfo existingValue, bool hasExistingValue, JsonSerializer serializer)
{
if (reader.TokenType != JsonToken.String)
throw new JsonObjectException(reader.Path, "Unexpected token type for NodeUri");
if (NodeInfo.TryParse((string)reader.Value, out var info))
return info;
throw new JsonObjectException(reader.Path, "Invalid NodeUri");
}
public override void WriteJson(JsonWriter writer, [AllowNull] NodeInfo value, JsonSerializer serializer)
{
if (value is NodeInfo)
writer.WriteValue(value.ToString());
}
}
}

View File

@ -0,0 +1,32 @@
using System;
using System.Reflection;
using NBitcoin.JsonConverters;
using Newtonsoft.Json;
namespace BTCPayServer.Client.JsonConverters
{
public class PermissionJsonConverter : JsonConverter
{
public override bool CanConvert(Type objectType)
{
return typeof(Permission).GetTypeInfo().IsAssignableFrom(objectType.GetTypeInfo());
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
if (reader.TokenType == JsonToken.Null)
return null;
if (reader.TokenType != JsonToken.String)
throw new JsonObjectException("Type 'Permission' is expected to be a 'String'", reader);
if (reader.Value is String s && Permission.TryParse(s, out var permission))
return permission;
throw new JsonObjectException("Invalid 'Permission' String", reader);
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
if (value is Permission v)
writer.WriteValue(v.ToString());
}
}
}

View File

@ -0,0 +1,43 @@
using System;
using NBitcoin.JsonConverters;
using Newtonsoft.Json;
namespace BTCPayServer.Client.JsonConverters
{
public class TimeSpanJsonConverter : JsonConverter
{
public override bool CanConvert(Type objectType)
{
return objectType == typeof(TimeSpan) || objectType == typeof(TimeSpan?);
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
try
{
var nullable = objectType == typeof(TimeSpan?);
if (reader.TokenType == JsonToken.Null)
{
if (nullable)
return null;
return TimeSpan.Zero;
}
if (reader.TokenType != JsonToken.Integer)
throw new JsonObjectException("Invalid timespan, expected integer", reader);
return TimeSpan.FromSeconds((long)reader.Value);
}
catch
{
throw new JsonObjectException("Invalid locktime", reader);
}
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
if (value is TimeSpan s)
{
writer.WriteValue((long)s.TotalSeconds);
}
}
}
}

View File

@ -0,0 +1,7 @@
namespace BTCPayServer.Client.Models
{
public class ApiHealthData
{
public bool Synchronized { get; set; }
}
}

View File

@ -0,0 +1,14 @@
using BTCPayServer.Client.JsonConverters;
using Newtonsoft.Json;
namespace BTCPayServer.Client.Models
{
public class ApiKeyData
{
public string ApiKey { get; set; }
public string Label { get; set; }
[JsonProperty(ItemConverterType = typeof(PermissionJsonConverter))]
public Permission[] Permissions { get; set; }
}
}

View File

@ -0,0 +1,25 @@
namespace BTCPayServer.Client.Models
{
public class ApplicationUserData
{
/// <summary>
/// the id of the user
/// </summary>
public string Id { get; set; }
/// <summary>
/// the email AND username of the user
/// </summary>
public string Email { get; set; }
/// <summary>
/// Whether the user has verified their email
/// </summary>
public bool EmailConfirmed { get; set; }
/// <summary>
/// whether the user needed to verify their email on account creation
/// </summary>
public bool RequiresEmailConfirmation { get; set; }
}
}

View File

@ -0,0 +1,8 @@
namespace BTCPayServer.Client.Models
{
public class ApprovePayoutRequest
{
public int Revision { get; set; }
public string RateRule { get; set; }
}
}

View File

@ -0,0 +1,21 @@
using BTCPayServer.Client.JsonConverters;
using BTCPayServer.Lightning;
using Newtonsoft.Json;
namespace BTCPayServer.Client.Models
{
public class ConnectToNodeRequest
{
public ConnectToNodeRequest()
{
}
public ConnectToNodeRequest(NodeInfo nodeInfo)
{
NodeURI = nodeInfo;
}
[JsonConverter(typeof(NodeUriJsonConverter))]
[JsonProperty("nodeURI")]
public NodeInfo NodeURI { get; set; }
}
}

View File

@ -0,0 +1,13 @@
using BTCPayServer.Client.JsonConverters;
using Newtonsoft.Json;
namespace BTCPayServer.Client.Models
{
public class CreateApiKeyRequest
{
public string Label { get; set; }
[JsonProperty(ItemConverterType = typeof(PermissionJsonConverter))]
public Permission[] Permissions { get; set; }
}
}

View File

@ -0,0 +1,20 @@
namespace BTCPayServer.Client.Models
{
public class CreateApplicationUserRequest
{
/// <summary>
/// the email AND username of the new user
/// </summary>
public string Email { get; set; }
/// <summary>
/// password of the new user
/// </summary>
public string Password { get; set; }
/// <summary>
/// Whether this user is an administrator. If left null and there are no admins in the system, the user will be created as an admin.
/// </summary>
public bool? IsAdministrator { get; set; }
}
}

View File

@ -0,0 +1,28 @@
using System;
using BTCPayServer.Lightning;
using BTCPayServer.Lightning.JsonConverters;
using Newtonsoft.Json;
namespace BTCPayServer.Client.Models
{
public class CreateLightningInvoiceRequest
{
public CreateLightningInvoiceRequest()
{
}
public CreateLightningInvoiceRequest(LightMoney amount, string description, TimeSpan expiry)
{
Amount = amount;
Description = description;
Expiry = expiry;
}
[JsonConverter(typeof(LightMoneyJsonConverter))]
public LightMoney Amount { get; set; }
public string Description { get; set; }
[JsonConverter(typeof(JsonConverters.TimeSpanJsonConverter))]
public TimeSpan Expiry { get; set; }
public bool PrivateRouteHints { get; set; }
}
}

View File

@ -0,0 +1,6 @@
namespace BTCPayServer.Client.Models
{
public class CreatePaymentRequestRequest : PaymentRequestBaseData
{
}
}

View File

@ -0,0 +1,13 @@
using BTCPayServer.JsonConverters;
using Newtonsoft.Json;
namespace BTCPayServer.Client.Models
{
public class CreatePayoutRequest
{
public string Destination { get; set; }
[JsonConverter(typeof(DecimalStringJsonConverter))]
public decimal? Amount { get; set; }
public string PaymentMethod { get; set; }
}
}

View File

@ -0,0 +1,22 @@
using System;
using BTCPayServer.Client.JsonConverters;
using BTCPayServer.JsonConverters;
using Newtonsoft.Json;
namespace BTCPayServer.Client.Models
{
public class CreatePullPaymentRequest
{
public string Name { get; set; }
[JsonProperty(ItemConverterType = typeof(DecimalStringJsonConverter))]
public decimal Amount { get; set; }
public string Currency { get; set; }
[JsonConverter(typeof(TimeSpanJsonConverter))]
public TimeSpan? Period { get; set; }
[JsonConverter(typeof(NBitcoin.JsonConverters.DateTimeToUnixTimeConverter))]
public DateTimeOffset? ExpiresAt { get; set; }
[JsonConverter(typeof(NBitcoin.JsonConverters.DateTimeToUnixTimeConverter))]
public DateTimeOffset? StartsAt { get; set; }
public string[] PaymentMethods { get; set; }
}
}

View File

@ -0,0 +1,6 @@
namespace BTCPayServer.Client.Models
{
public class CreateStoreRequest : StoreBaseData
{
}
}

View File

@ -0,0 +1,23 @@
using System;
namespace BTCPayServer.Client.Models
{
public class GreenfieldAPIError
{
public GreenfieldAPIError()
{
}
public GreenfieldAPIError(string code, string message)
{
if (code == null)
throw new ArgumentNullException(nameof(code));
if (message == null)
throw new ArgumentNullException(nameof(message));
Code = code;
Message = message;
}
public string Code { get; set; }
public string Message { get; set; }
}
}

View File

@ -0,0 +1,24 @@
using System;
namespace BTCPayServer.Client.Models
{
public class GreenfieldValidationError
{
public GreenfieldValidationError()
{
}
public GreenfieldValidationError(string path, string message)
{
if (path == null)
throw new ArgumentNullException(nameof(path));
if (message == null)
throw new ArgumentNullException(nameof(message));
Path = path;
Message = message;
}
public string Path { get; set; }
public string Message { get; set; }
}
}

View File

@ -0,0 +1,30 @@
using System;
using BTCPayServer.Client.JsonConverters;
using BTCPayServer.Lightning;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
namespace BTCPayServer.Client.Models
{
public class LightningInvoiceData
{
public string Id { get; set; }
[JsonConverter(typeof(StringEnumConverter))]
public LightningInvoiceStatus Status { get; set; }
[JsonProperty("BOLT11")]
public string BOLT11 { get; set; }
[JsonConverter(typeof(NBitcoin.JsonConverters.DateTimeToUnixTimeConverter))]
public DateTimeOffset? PaidAt { get; set; }
[JsonConverter(typeof(NBitcoin.JsonConverters.DateTimeToUnixTimeConverter))]
public DateTimeOffset ExpiresAt { get; set; }
[JsonConverter(typeof(LightMoneyJsonConverter))]
public LightMoney Amount { get; set; }
[JsonConverter(typeof(LightMoneyJsonConverter))]
public LightMoney AmountReceived { get; set; }
}
}

View File

@ -0,0 +1,30 @@
using BTCPayServer.Client.JsonConverters;
using BTCPayServer.Lightning;
using Newtonsoft.Json;
namespace BTCPayServer.Client.Models
{
public class LightningNodeInformationData
{
[JsonProperty("nodeURIs", ItemConverterType = typeof(NodeUriJsonConverter))]
public NodeInfo[] NodeURIs { get; set; }
public int BlockHeight { get; set; }
}
public class LightningChannelData
{
public string RemoteNode { get; set; }
public bool IsPublic { get; set; }
public bool IsActive { get; set; }
[JsonConverter(typeof(LightMoneyJsonConverter))]
public LightMoney Capacity { get; set; }
[JsonConverter(typeof(LightMoneyJsonConverter))]
public LightMoney LocalBalance { get; set; }
public string ChannelPoint { get; set; }
}
}

View File

@ -0,0 +1,21 @@
using BTCPayServer.Client.JsonConverters;
using BTCPayServer.Lightning;
using NBitcoin;
using NBitcoin.JsonConverters;
using Newtonsoft.Json;
using MoneyJsonConverter = BTCPayServer.Client.JsonConverters.MoneyJsonConverter;
namespace BTCPayServer.Client.Models
{
public class OpenLightningChannelRequest
{
[JsonConverter(typeof(NodeUriJsonConverter))]
[JsonProperty("nodeURI")]
public NodeInfo NodeURI { get; set; }
[JsonConverter(typeof(MoneyJsonConverter))]
public Money ChannelAmount { get; set; }
[JsonConverter(typeof(FeeRateJsonConverter))]
public FeeRate FeeRate { get; set; }
}
}

View File

@ -0,0 +1,8 @@
namespace BTCPayServer.Client.Models
{
public class PayLightningInvoiceRequest
{
[Newtonsoft.Json.JsonProperty("BOLT11")]
public string BOLT11 { get; set; }
}
}

View File

@ -0,0 +1,26 @@
using System;
using System.Collections.Generic;
using BTCPayServer.JsonConverters;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
namespace BTCPayServer.Client.Models
{
public class PaymentRequestBaseData
{
[JsonProperty(ItemConverterType = typeof(DecimalStringJsonConverter))]
public decimal Amount { get; set; }
public string Currency { get; set; }
public DateTime? ExpiryDate { get; set; }
public string Title { get; set; }
public string Description { get; set; }
public string Email { get; set; }
public string EmbeddedCSS { get; set; }
public string CustomCSSLink { get; set; }
public bool AllowCustomPaymentAmounts { get; set; }
[JsonExtensionData]
public IDictionary<string, JToken> AdditionalData { get; set; }
}
}

View File

@ -0,0 +1,22 @@
using System;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
namespace BTCPayServer.Client.Models
{
public class PaymentRequestData : PaymentRequestBaseData
{
[JsonConverter(typeof(StringEnumConverter))]
public PaymentRequestData.PaymentRequestStatus Status { get; set; }
public DateTimeOffset Created { get; set; }
public string Id { get; set; }
public bool Archived { get; set; }
public enum PaymentRequestStatus
{
Pending = 0,
Completed = 1,
Expired = 2
}
}
}

View File

@ -0,0 +1,32 @@
using System;
using BTCPayServer.JsonConverters;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
namespace BTCPayServer.Client.Models
{
public enum PayoutState
{
AwaitingApproval,
AwaitingPayment,
InProgress,
Completed,
Cancelled
}
public class PayoutData
{
[JsonConverter(typeof(NBitcoin.JsonConverters.DateTimeToUnixTimeConverter))]
public DateTimeOffset Date { get; set; }
public string Id { get; set; }
public string PullPaymentId { get; set; }
public string Destination { get; set; }
public string PaymentMethod { get; set; }
[JsonConverter(typeof(DecimalStringJsonConverter))]
public decimal Amount { get; set; }
[JsonConverter(typeof(DecimalStringJsonConverter))]
public decimal? PaymentMethodAmount { get; set; }
[JsonConverter(typeof(StringEnumConverter))]
public PayoutState State { get; set; }
public int Revision { get; set; }
}
}

View File

@ -0,0 +1,24 @@
using System;
using BTCPayServer.Client.JsonConverters;
using BTCPayServer.JsonConverters;
using Newtonsoft.Json;
namespace BTCPayServer.Client.Models
{
public class PullPaymentData
{
[JsonConverter(typeof(NBitcoin.JsonConverters.DateTimeToUnixTimeConverter))]
public DateTimeOffset StartsAt { get; set; }
[JsonConverter(typeof(NBitcoin.JsonConverters.DateTimeToUnixTimeConverter))]
public DateTimeOffset? ExpiresAt { get; set; }
public string Id { get; set; }
public string Name { get; set; }
public string Currency { get; set; }
[JsonConverter(typeof(DecimalStringJsonConverter))]
public decimal Amount { get; set; }
[JsonConverter(typeof(TimeSpanJsonConverter))]
public TimeSpan? Period { get; set; }
public bool Archived { get; set; }
public string ViewLink { get; set; }
}
}

View File

@ -0,0 +1,47 @@
using System.Collections.Generic;
namespace BTCPayServer.Client.Models
{
public class ServerInfoData
{
/// <summary>
/// the BTCPay Server version
/// </summary>
public string Version { get; set; }
/// <summary>
/// the Tor hostname
/// </summary>
public string Onion { get; set; }
/// <summary>
/// the payment methods this server supports
/// </summary>
public IEnumerable<string> SupportedPaymentMethods { get; set; }
/// <summary>
/// are all chains fully synched
/// </summary>
public bool FullySynched { get; set; }
/// <summary>
/// detailed sync information per chain
/// </summary>
public IEnumerable<ServerInfoSyncStatusData> SyncStatus { get; set; }
}
public class ServerInfoSyncStatusData
{
public string CryptoCode { get; set; }
public int ChainHeight { get; set; }
public int? SyncHeight { get; set; }
public ServerInfoNodeData NodeInformation { get; set; }
}
public class ServerInfoNodeData
{
public int Headers { get; set; }
public int Blocks { get; set; }
public double VerificationProgress { get; set; }
}
}

View File

@ -0,0 +1,78 @@
using System;
using System.Collections.Generic;
using BTCPayServer.Client.JsonConverters;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
using Newtonsoft.Json.Linq;
namespace BTCPayServer.Client.Models
{
public abstract class StoreBaseData
{
/// <summary>
/// the name of the store
/// </summary>
public string Name { get; set; }
public string Website { get; set; }
[JsonConverter(typeof(TimeSpanJsonConverter))]
[JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
public TimeSpan InvoiceExpiration { get; set; } = TimeSpan.FromMinutes(15);
[JsonConverter(typeof(TimeSpanJsonConverter))]
[JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
public TimeSpan MonitoringExpiration { get; set; } = TimeSpan.FromMinutes(60);
[JsonConverter(typeof(StringEnumConverter))]
public SpeedPolicy SpeedPolicy { get; set; }
public string LightningDescriptionTemplate { get; set; }
public double PaymentTolerance { get; set; } = 0;
public bool AnyoneCanCreateInvoice { get; set; }
[JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
public bool ShowRecommendedFee { get; set; } = true;
[JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
public int RecommendedFeeBlockTarget { get; set; } = 1;
[JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
public string DefaultLang { get; set; } = "en";
public bool LightningAmountInSatoshi { get; set; }
public string CustomLogo { get; set; }
public string CustomCSS { get; set; }
public string HtmlTitle { get; set; }
public bool RedirectAutomatically { get; set; }
public bool RequiresRefundEmail { get; set; }
[JsonConverter(typeof(StringEnumConverter))]
[JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
public NetworkFeeMode NetworkFeeMode { get; set; } = NetworkFeeMode.Never;
public bool PayJoinEnabled { get; set; }
public bool LightningPrivateRouteHints { get; set; }
[JsonExtensionData]
public IDictionary<string, JToken> AdditionalData { get; set; }
}
public enum NetworkFeeMode
{
MultiplePaymentsOnly,
Always,
Never
}
public enum SpeedPolicy
{
HighSpeed = 0,
MediumSpeed = 1,
LowSpeed = 2,
LowMediumSpeed = 3
}
}

View File

@ -0,0 +1,10 @@
namespace BTCPayServer.Client.Models
{
public class StoreData : StoreBaseData
{
/// <summary>
/// the id of the store
/// </summary>
public string Id { get; set; }
}
}

View File

@ -0,0 +1,6 @@
namespace BTCPayServer.Client.Models
{
public class UpdatePaymentRequestRequest : PaymentRequestBaseData
{
}
}

View File

@ -0,0 +1,6 @@
namespace BTCPayServer.Client.Models
{
public class UpdateStoreRequest : StoreBaseData
{
}
}

View File

@ -0,0 +1,208 @@
using System;
using System.Collections.Generic;
using System.Linq;
namespace BTCPayServer.Client
{
public class Policies
{
public const string CanCreateLightningInvoiceInternalNode = "btcpay.server.cancreatelightninginvoiceinternalnode";
public const string CanCreateLightningInvoiceInStore = "btcpay.store.cancreatelightninginvoice";
public const string CanUseInternalLightningNode = "btcpay.server.canuseinternallightningnode";
public const string CanUseLightningNodeInStore = "btcpay.store.canuselightningnode";
public const string CanModifyServerSettings = "btcpay.server.canmodifyserversettings";
public const string CanModifyStoreSettings = "btcpay.store.canmodifystoresettings";
public const string CanModifyStoreSettingsUnscoped = "btcpay.store.canmodifystoresettings:";
public const string CanViewStoreSettings = "btcpay.store.canviewstoresettings";
public const string CanCreateInvoice = "btcpay.store.cancreateinvoice";
public const string CanViewPaymentRequests = "btcpay.store.canviewpaymentrequests";
public const string CanModifyPaymentRequests = "btcpay.store.canmodifypaymentrequests";
public const string CanModifyProfile = "btcpay.user.canmodifyprofile";
public const string CanViewProfile = "btcpay.user.canviewprofile";
public const string CanCreateUser = "btcpay.server.cancreateuser";
public const string CanManagePullPayments = "btcpay.store.canmanagepullpayments";
public const string Unrestricted = "unrestricted";
public static IEnumerable<string> AllPolicies
{
get
{
yield return CanCreateInvoice;
yield return CanModifyServerSettings;
yield return CanModifyStoreSettings;
yield return CanViewStoreSettings;
yield return CanViewPaymentRequests;
yield return CanModifyPaymentRequests;
yield return CanModifyProfile;
yield return CanViewProfile;
yield return CanCreateUser;
yield return Unrestricted;
yield return CanUseInternalLightningNode;
yield return CanCreateLightningInvoiceInternalNode;
yield return CanUseLightningNodeInStore;
yield return CanCreateLightningInvoiceInStore;
yield return CanManagePullPayments;
}
}
public static bool IsValidPolicy(string policy)
{
return AllPolicies.Any(p => p.Equals(policy, StringComparison.OrdinalIgnoreCase));
}
public static bool IsStorePolicy(string policy)
{
return policy.StartsWith("btcpay.store", StringComparison.OrdinalIgnoreCase);
}
public static bool IsStoreModifyPolicy(string policy)
{
return policy.StartsWith("btcpay.store.canmodify", StringComparison.OrdinalIgnoreCase);
}
public static bool IsServerPolicy(string policy)
{
return policy.StartsWith("btcpay.server", StringComparison.OrdinalIgnoreCase);
}
}
public class Permission
{
public static Permission Create(string policy, string scope = null)
{
if (TryCreatePermission(policy, scope, out var r))
return r;
throw new ArgumentException("Invalid Permission");
}
public static bool TryCreatePermission(string policy, string scope, out Permission permission)
{
permission = null;
if (policy == null)
throw new ArgumentNullException(nameof(policy));
policy = policy.Trim().ToLowerInvariant();
if (!Policies.IsValidPolicy(policy))
return false;
if (scope != null && !Policies.IsStorePolicy(policy))
return false;
permission = new Permission(policy, scope);
return true;
}
public static bool TryParse(string str, out Permission permission)
{
permission = null;
if (str == null)
throw new ArgumentNullException(nameof(str));
str = str.Trim();
var separator = str.IndexOf(':');
if (separator == -1)
{
str = str.ToLowerInvariant();
if (!Policies.IsValidPolicy(str))
return false;
permission = new Permission(str, null);
return true;
}
else
{
var policy = str.Substring(0, separator).ToLowerInvariant();
if (!Policies.IsValidPolicy(policy))
return false;
if (!Policies.IsStorePolicy(policy))
return false;
var storeId = str.Substring(separator + 1);
if (storeId.Length == 0)
return false;
permission = new Permission(policy, storeId);
return true;
}
}
internal Permission(string policy, string scope)
{
Policy = policy;
Scope = scope;
}
public bool Contains(Permission subpermission)
{
if (subpermission is null)
throw new ArgumentNullException(nameof(subpermission));
if (!ContainsPolicy(subpermission.Policy))
{
return false;
}
if (!Policies.IsStorePolicy(subpermission.Policy))
return true;
return Scope == null || subpermission.Scope == this.Scope;
}
public static IEnumerable<Permission> ToPermissions(string[] permissions)
{
if (permissions == null)
throw new ArgumentNullException(nameof(permissions));
foreach (var p in permissions)
{
if (TryParse(p, out var pp))
yield return pp;
}
}
private bool ContainsPolicy(string subpolicy)
{
if (this.Policy == Policies.Unrestricted)
return true;
if (this.Policy == subpolicy)
return true;
switch (subpolicy)
{
case Policies.CanViewStoreSettings when this.Policy == Policies.CanModifyStoreSettings:
case Policies.CanCreateInvoice when this.Policy == Policies.CanModifyStoreSettings:
case Policies.CanViewProfile when this.Policy == Policies.CanModifyProfile:
case Policies.CanModifyPaymentRequests when this.Policy == Policies.CanModifyStoreSettings:
case Policies.CanViewPaymentRequests when this.Policy == Policies.CanModifyStoreSettings:
case Policies.CanViewPaymentRequests when this.Policy == Policies.CanViewStoreSettings:
case Policies.CanCreateLightningInvoiceInternalNode when this.Policy == Policies.CanUseInternalLightningNode:
case Policies.CanCreateLightningInvoiceInStore when this.Policy == Policies.CanUseLightningNodeInStore:
return true;
default:
return false;
}
}
public string Scope { get; }
public string Policy { get; }
public override string ToString()
{
if (Scope != null)
{
return $"{Policy}:{Scope}";
}
return Policy;
}
public override bool Equals(object obj)
{
Permission item = obj as Permission;
if (item == null)
return false;
return ToString().Equals(item.ToString());
}
public static bool operator ==(Permission a, Permission b)
{
if (System.Object.ReferenceEquals(a, b))
return true;
if (((object)a == null) || ((object)b == null))
return false;
return a.ToString() == b.ToString();
}
public static bool operator !=(Permission a, Permission b)
{
return !(a == b);
}
public override int GetHashCode()
{
return ToString().GetHashCode();
}
}
}

View File

@ -0,0 +1,31 @@
using NBitcoin;
namespace BTCPayServer
{
public partial class BTCPayNetworkProvider
{
public void InitArgoneum()
{
var nbxplorerNetwork = NBXplorerNetworkProvider.GetFromCryptoCode("AGM");
Add(new BTCPayNetwork()
{
CryptoCode = nbxplorerNetwork.CryptoCode,
DisplayName = "Argoneum",
BlockExplorerLink = NetworkType == NetworkType.Mainnet
? "https://chainz.cryptoid.info/agm/tx.dws?{0}"
: "https://chainz.cryptoid.info/agm-test/tx.dws?{0}",
NBXplorerNetwork = nbxplorerNetwork,
UriScheme = "argoneum",
DefaultRateRules = new[]
{
"AGM_X = AGM_BTC * BTC_X",
"AGM_BTC = argoneum(AGM_BTC)"
},
CryptoImagePath = "imlegacy/argoneum.png",
DefaultSettings = BTCPayDefaultSettings.GetDefaultSettings(NetworkType),
CoinType = NetworkType == NetworkType.Mainnet ? new KeyPath("421'")
: new KeyPath("1'")
});
}
}
}

View File

@ -1,7 +1,4 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using NBitcoin;
using NBXplorer;
@ -24,19 +21,20 @@ namespace BTCPayServer
DefaultSettings = BTCPayDefaultSettings.GetDefaultSettings(NetworkType),
CoinType = NetworkType == NetworkType.Mainnet ? new KeyPath("0'") : new KeyPath("1'"),
SupportRBF = true,
SupportPayJoin = true,
//https://github.com/spesmilo/electrum/blob/11733d6bc271646a00b69ff07657119598874da4/electrum/constants.py
ElectrumMapping = NetworkType == NetworkType.Mainnet
? new Dictionary<uint, DerivationType>()
{
{0x0488b21eU, DerivationType.Legacy }, // xpub
{0x049d7cb2U, DerivationType.SegwitP2SH }, // ypub
{0x4b24746U, DerivationType.Segwit }, //zpub
{0x04b24746U, DerivationType.Segwit }, //zpub
}
: new Dictionary<uint, DerivationType>()
{
{0x043587cfU, DerivationType.Legacy},
{0x044a5262U, DerivationType.SegwitP2SH},
{0x045f1cf6U, DerivationType.Segwit}
{0x043587cfU, DerivationType.Legacy}, // tpub
{0x044a5262U, DerivationType.SegwitP2SH}, // upub
{0x045f1cf6U, DerivationType.Segwit} // vpub
}
});
}

View File

@ -1,4 +1,4 @@
using NBitcoin;
using NBitcoin;
namespace BTCPayServer
{

View File

@ -1,7 +1,3 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using NBitcoin;
using NBXplorer;

View File

@ -1,7 +1,3 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using NBitcoin;
using NBXplorer;

View File

@ -0,0 +1,33 @@
using NBitcoin;
namespace BTCPayServer
{
public partial class BTCPayNetworkProvider
{
public void InitChaincoin()
{
var nbxplorerNetwork = NBXplorerNetworkProvider.GetFromCryptoCode("CHC");
Add(new BTCPayNetwork()
{
CryptoCode = nbxplorerNetwork.CryptoCode,
DisplayName = "Chaincoin",
BlockExplorerLink = NetworkType == NetworkType.Mainnet
? "https://explorer.chaincoin.org/Explorer/Transaction/{0}"
: "https://test.explorer.chaincoin.org/Explorer/Transaction/tx/{0}",
NBXplorerNetwork = nbxplorerNetwork,
UriScheme = "chaincoin",
DefaultRateRules = new[]
{
"CHC_X = CHC_BTC * BTC_X",
"CHC_BTC = txbit(CHC_X)"
},
CryptoImagePath = "imlegacy/chaincoin.png",
DefaultSettings = BTCPayDefaultSettings.GetDefaultSettings(NetworkType),
//https://github.com/satoshilabs/slips/blob/master/slip-0044.md
CoinType = NetworkType == NetworkType.Mainnet ? new KeyPath("711'")
: new KeyPath("1'")
});
}
}
}

View File

@ -1,4 +1,4 @@
using NBitcoin;
using NBitcoin;
namespace BTCPayServer
{

View File

@ -1,7 +1,3 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using NBitcoin;
using NBXplorer;
@ -19,7 +15,7 @@ namespace BTCPayServer
BlockExplorerLink = NetworkType == NetworkType.Mainnet ? "https://dogechain.info/tx/{0}" : "https://dogechain.info/tx/{0}",
NBXplorerNetwork = nbxplorerNetwork,
UriScheme = "dogecoin",
DefaultRateRules = new[]
DefaultRateRules = new[]
{
"DOGE_X = DOGE_BTC * BTC_X",
"DOGE_BTC = bittrex(DOGE_BTC)"

View File

@ -1,7 +1,3 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using NBitcoin;
using NBXplorer;
@ -19,7 +15,7 @@ namespace BTCPayServer
BlockExplorerLink = NetworkType == NetworkType.Mainnet ? "https://explorer.feathercoin.com/tx/{0}" : "https://explorer.feathercoin.com/tx/{0}",
NBXplorerNetwork = nbxplorerNetwork,
UriScheme = "feathercoin",
DefaultRateRules = new[]
DefaultRateRules = new[]
{
"FTC_X = FTC_BTC * BTC_X",
"FTC_BTC = bittrex(FTC_BTC)"

View File

@ -1,7 +1,3 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using NBitcoin;
namespace BTCPayServer
@ -28,7 +24,9 @@ namespace BTCPayServer
CryptoImagePath = "imlegacy/groestlcoin.png",
LightningImagePath = "imlegacy/groestlcoin-lightning.svg",
DefaultSettings = BTCPayDefaultSettings.GetDefaultSettings(NetworkType),
CoinType = NetworkType == NetworkType.Mainnet ? new KeyPath("17'") : new KeyPath("1'")
CoinType = NetworkType == NetworkType.Mainnet ? new KeyPath("17'") : new KeyPath("1'"),
SupportRBF = true,
SupportPayJoin = true
});
}
}

View File

@ -1,7 +1,4 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using NBitcoin;
using NBXplorer;

View File

@ -1,7 +1,3 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using NBitcoin;
using NBXplorer;
@ -19,7 +15,7 @@ namespace BTCPayServer
BlockExplorerLink = NetworkType == NetworkType.Mainnet ? "https://mona.insight.monaco-ex.org/insight/tx/{0}" : "https://testnet-mona.insight.monaco-ex.org/insight/tx/{0}",
NBXplorerNetwork = nbxplorerNetwork,
UriScheme = "monacoin",
DefaultRateRules = new[]
DefaultRateRules = new[]
{
"MONA_X = MONA_BTC * BTC_X",
"MONA_BTC = bittrex(MONA_BTC)"

View File

@ -1,7 +1,3 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using NBitcoin;
using NBXplorer;

View File

@ -1,7 +1,3 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using NBitcoin;
using NBXplorer;
@ -19,7 +15,7 @@ namespace BTCPayServer
BlockExplorerLink = NetworkType == NetworkType.Mainnet ? "https://chainz.cryptoid.info/ufo/tx.dws?{0}" : "https://chainz.cryptoid.info/ufo/tx.dws?{0}",
NBXplorerNetwork = nbxplorerNetwork,
UriScheme = "ufo",
DefaultRateRules = new[]
DefaultRateRules = new[]
{
"UFO_X = UFO_BTC * BTC_X",
"UFO_BTC = coinexchange(UFO_BTC)"

View File

@ -1,7 +1,3 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using NBitcoin;
using NBXplorer;

View File

@ -1,8 +1,6 @@
using System;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using NBitcoin;
using NBXplorer;
@ -10,7 +8,7 @@ namespace BTCPayServer
{
public partial class BTCPayNetworkProvider
{
Dictionary<string, BTCPayNetworkBase> _Networks = new Dictionary<string, BTCPayNetworkBase>();
readonly Dictionary<string, BTCPayNetworkBase> _Networks = new Dictionary<string, BTCPayNetworkBase>();
private readonly NBXplorerNetworkProvider _NBXplorerNetworkProvider;
@ -31,7 +29,7 @@ namespace BTCPayServer
cryptoCodes = cryptoCodes.Select(c => c.ToUpperInvariant()).ToArray();
foreach (var network in unfiltered._Networks)
{
if(cryptoCodes.Contains(network.Key))
if (cryptoCodes.Contains(network.Key))
{
_Networks.Add(network.Key, network.Value);
}
@ -60,11 +58,13 @@ namespace BTCPayServer
InitViacoin();
InitMonero();
InitPolis();
InitChaincoin();
InitArgoneum();
// Assume that electrum mappings are same as BTC if not specified
foreach (var network in _Networks.Values.OfType<BTCPayNetwork>())
{
if(network.ElectrumMapping.Count == 0)
if (network.ElectrumMapping.Count == 0)
{
network.ElectrumMapping = GetNetwork<BTCPayNetwork>("BTC").ElectrumMapping;
if (!network.NBitcoinNetwork.Consensus.SupportSegwit)
@ -119,11 +119,11 @@ namespace BTCPayServer
{
return GetNetwork<BTCPayNetworkBase>(cryptoCode.ToUpperInvariant());
}
public T GetNetwork<T>(string cryptoCode) where T: BTCPayNetworkBase
public T GetNetwork<T>(string cryptoCode) where T : BTCPayNetworkBase
{
if (cryptoCode == null)
throw new ArgumentNullException(nameof(cryptoCode));
if(!_Networks.TryGetValue(cryptoCode.ToUpperInvariant(), out BTCPayNetworkBase network))
if (!_Networks.TryGetValue(cryptoCode.ToUpperInvariant(), out BTCPayNetworkBase network))
{
if (cryptoCode == "XBT")
return GetNetwork<T>("BTC");

View File

@ -1,7 +1,3 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using NBitcoin;
using NBitcoin.Altcoins;
using NBitcoin.Altcoins.Elements;
@ -16,7 +12,7 @@ namespace BTCPayServer
var nbxplorerNetwork = NBXplorerNetworkProvider.GetFromCryptoCode("LBTC");
Add(new ElementsBTCPayNetwork()
{
AssetId = NetworkType == NetworkType.Mainnet ? ElementsParams<Liquid>.PeggedAssetId: ElementsParams<Liquid.LiquidRegtest>.PeggedAssetId,
AssetId = NetworkType == NetworkType.Mainnet ? ElementsParams<Liquid>.PeggedAssetId : ElementsParams<Liquid.LiquidRegtest>.PeggedAssetId,
CryptoCode = "LBTC",
NetworkCryptoCode = "LBTC",
DisplayName = "Liquid Bitcoin",

View File

@ -1,4 +1,4 @@
using NBitcoin;
using NBitcoin;
namespace BTCPayServer
{
@ -26,9 +26,10 @@ namespace BTCPayServer
CryptoImagePath = "imlegacy/liquid-tether.svg",
DefaultSettings = BTCPayDefaultSettings.GetDefaultSettings(NetworkType),
CoinType = NetworkType == NetworkType.Mainnet ? new KeyPath("1776'") : new KeyPath("1'"),
SupportRBF = true
SupportRBF = true,
SupportLightning = false
});
Add(new ElementsBTCPayNetwork()
{
CryptoCode = "ETB",
@ -36,7 +37,7 @@ namespace BTCPayServer
ShowSyncSummary = false,
DefaultRateRules = new[]
{
"ETB_X = ETB_BTC * BTC_X",
"ETB_BTC = bitpay(ETB_BTC)"
},
@ -49,7 +50,31 @@ namespace BTCPayServer
CryptoImagePath = "imlegacy/etb.png",
DefaultSettings = BTCPayDefaultSettings.GetDefaultSettings(NetworkType),
CoinType = NetworkType == NetworkType.Mainnet ? new KeyPath("1776'") : new KeyPath("1'"),
SupportRBF = true
SupportRBF = true,
SupportLightning = false
});
Add(new ElementsBTCPayNetwork()
{
CryptoCode = "LCAD",
NetworkCryptoCode = "LBTC",
ShowSyncSummary = false,
DefaultRateRules = new[]
{
"LCAD_CAD = 1",
"LCAD_X = CAD_BTC * BTC_X",
"LCAD_BTC = bylls(CAD_BTC)",
},
AssetId = new uint256("0e99c1a6da379d1f4151fb9df90449d40d0608f6cb33a5bcbfc8c265f42bab0a"),
DisplayName = "Liquid CAD",
BlockExplorerLink = NetworkType == NetworkType.Mainnet ? "https://blockstream.info/liquid/tx/{0}" : "https://blockstream.info/testnet/liquid/tx/{0}",
NBXplorerNetwork = nbxplorerNetwork,
UriScheme = "liquidnetwork",
CryptoImagePath = "imlegacy/lcad.png",
DefaultSettings = BTCPayDefaultSettings.GetDefaultSettings(NetworkType),
CoinType = NetworkType == NetworkType.Mainnet ? new KeyPath("1776'") : new KeyPath("1'"),
SupportRBF = true,
SupportLightning = false
});
}
}

View File

@ -23,9 +23,38 @@ namespace BTCPayServer
});
}
public override GetTransactionsResponse FilterValidTransactions(GetTransactionsResponse response)
{
TransactionInformationSet Filter(TransactionInformationSet transactionInformationSet)
{
return new TransactionInformationSet()
{
Transactions =
transactionInformationSet.Transactions.FindAll(information =>
information.Outputs.Any(output =>
output.Value is AssetMoney assetMoney && assetMoney.AssetId == AssetId) ||
information.Inputs.Any(output =>
output.Value is AssetMoney assetMoney && assetMoney.AssetId == AssetId))
};
}
return new GetTransactionsResponse()
{
Height = response.Height,
ConfirmedTransactions = Filter(response.ConfirmedTransactions),
ReplacedTransactions = Filter(response.ReplacedTransactions),
UnconfirmedTransactions = Filter(response.UnconfirmedTransactions)
};
}
public override string GenerateBIP21(string cryptoInfoAddress, Money cryptoInfoDue)
{
return $"{base.GenerateBIP21(cryptoInfoAddress, cryptoInfoDue)}&assetid={AssetId}";
//precision 0: 10 = 0.00000010
//precision 2: 10 = 0.00001000
//precision 8: 10 = 10
var money = new Money(cryptoInfoDue.ToDecimal(MoneyUnit.BTC) / decimal.Parse("1".PadRight(1 + 8 - Divisibility, '0')), MoneyUnit.BTC);
return $"{base.GenerateBIP21(cryptoInfoAddress, money)}&assetid={AssetId}";
}
}
}

View File

@ -46,7 +46,7 @@ namespace BTCPayServer.Services.Altcoins.Monero.RPC
Convert.ToBase64String(Encoding.Default.GetBytes($"{_username}:{_password}")));
var rawResult = await _httpClient.SendAsync(httpRequest, cts);
var rawJson = await rawResult.Content.ReadAsStringAsync();
rawResult.EnsureSuccessStatusCode();
JsonRpcResult<TResponse> response;
@ -68,7 +68,7 @@ namespace BTCPayServer.Services.Altcoins.Monero.RPC
Error = response.Error
};
}
return response.Result;
}
@ -92,7 +92,7 @@ namespace BTCPayServer.Services.Altcoins.Monero.RPC
}
internal class JsonRpcResult<T>
{
[JsonProperty("result")] public T Result { get; set; }
[JsonProperty("error")] public JsonRpcResultError Error { get; set; }

View File

@ -14,7 +14,6 @@ namespace BTCPayServer.Services.Altcoins.Monero.RPC.Models
[JsonProperty("amount")] public long Amount { get; set; }
[JsonProperty("confirmations")] public long Confirmations { get; set; }
[JsonProperty("double_spend_seen")] public bool DoubleSpendSeen { get; set; }
[JsonProperty("fee")] public long Fee { get; set; }
[JsonProperty("height")] public long Height { get; set; }
[JsonProperty("note")] public string Note { get; set; }
[JsonProperty("payment_id")] public string PaymentId { get; set; }

View File

@ -18,7 +18,6 @@ namespace BTCPayServer.Services.Altcoins.Monero.RPC.Models
[JsonProperty("amount")] public long Amount { get; set; }
[JsonProperty("confirmations")] public long Confirmations { get; set; }
[JsonProperty("double_spend_seen")] public bool DoubleSpendSeen { get; set; }
[JsonProperty("fee")] public long Fee { get; set; }
[JsonProperty("height")] public long Height { get; set; }
[JsonProperty("note")] public string Note { get; set; }
[JsonProperty("payment_id")] public string PaymentId { get; set; }

View File

@ -10,7 +10,8 @@ namespace BTCPayServer.Services.Altcoins.Monero.RPC.Models
public override object ReadJson(JsonReader reader, Type t, object existingValue, JsonSerializer serializer)
{
if (reader.TokenType == JsonToken.Null) return null;
if (reader.TokenType == JsonToken.Null)
return null;
var value = serializer.Deserialize<string>(reader);
long l;
if (Int64.TryParse(value, out l))

View File

@ -1,12 +1,10 @@
using System;
using System.Collections;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using NBitcoin;
using NBXplorer;
using NBXplorer.Models;
using Newtonsoft.Json;
namespace BTCPayServer
{
@ -33,7 +31,7 @@ namespace BTCPayServer
}
}
static Dictionary<NetworkType, BTCPayDefaultSettings> _Settings;
static readonly Dictionary<NetworkType, BTCPayDefaultSettings> _Settings;
public static BTCPayDefaultSettings GetDefaultSettings(NetworkType chainType)
{
@ -45,22 +43,25 @@ namespace BTCPayServer
public int DefaultPort { get; set; }
}
public class BTCPayNetwork:BTCPayNetworkBase
public class BTCPayNetwork : BTCPayNetworkBase
{
public Network NBitcoinNetwork { get { return NBXplorerNetwork?.NBitcoinNetwork; } }
public Network NBitcoinNetwork { get { return NBXplorerNetwork?.NBitcoinNetwork; } }
public NBXplorer.NBXplorerNetwork NBXplorerNetwork { get; set; }
public bool SupportRBF { get; internal set; }
public string LightningImagePath { get; set; }
public BTCPayDefaultSettings DefaultSettings { get; set; }
public KeyPath CoinType { get; internal set; }
public Dictionary<uint, DerivationType> ElectrumMapping = new Dictionary<uint, DerivationType>();
public virtual bool WalletSupported { get; set; } = true;
public virtual bool ReadonlyWallet{ get; set; } = false;
public virtual bool ReadonlyWallet { get; set; } = false;
public int MaxTrackedConfirmation { get; internal set; } = 6;
public string UriScheme { get; internal set; }
public bool SupportPayJoin { get; set; } = false;
public bool SupportLightning { get; set; } = true;
public KeyPath GetRootKeyPath(DerivationType type)
{
KeyPath baseKey;
@ -117,6 +118,11 @@ namespace BTCPayServer
{
return $"{UriScheme}:{cryptoInfoAddress}?amount={cryptoInfoDue.ToString(false, true)}";
}
public virtual GetTransactionsResponse FilterValidTransactions(GetTransactionsResponse response)
{
return response;
}
}
public abstract class BTCPayNetworkBase

View File

@ -4,6 +4,6 @@
<ItemGroup>
<FrameworkReference Include="Microsoft.AspNetCore.App" />
<PackageReference Include="NBXplorer.Client" Version="3.0.2" />
<PackageReference Include="NBXplorer.Client" Version="3.0.16" />
</ItemGroup>
</Project>

View File

@ -1,6 +1,5 @@
using System;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
@ -9,12 +8,12 @@ namespace BTCPayServer
{
public class CustomThreadPool : IDisposable
{
CancellationTokenSource _Cancel = new CancellationTokenSource();
TaskCompletionSource<bool> _Exited;
readonly CancellationTokenSource _Cancel = new CancellationTokenSource();
readonly TaskCompletionSource<bool> _Exited;
int _ExitedCount = 0;
Thread[] _Threads;
readonly Thread[] _Threads;
Exception _UnhandledException;
BlockingCollection<(Action, TaskCompletionSource<object>)> _Actions = new BlockingCollection<(Action, TaskCompletionSource<object>)>(new ConcurrentQueue<(Action, TaskCompletionSource<object>)>());
readonly BlockingCollection<(Action, TaskCompletionSource<object>)> _Actions = new BlockingCollection<(Action, TaskCompletionSource<object>)>(new ConcurrentQueue<(Action, TaskCompletionSource<object>)>());
public CustomThreadPool(int threadCount, string threadName)
{

View File

@ -1,6 +1,4 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace BTCPayServer
{

View File

@ -1,4 +1,4 @@
using System;
using System;
using System.Collections.Concurrent;
using System.Runtime.InteropServices;
using System.Text;
@ -13,7 +13,7 @@ namespace BTCPayServer.Logging
{
public class CustomConsoleLogProvider : ILoggerProvider
{
ConsoleLoggerProcessor _Processor;
readonly ConsoleLoggerProcessor _Processor;
public CustomConsoleLogProvider(ConsoleLoggerProcessor processor)
{
_Processor = processor;

View File

@ -1,9 +1,6 @@
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Logging.Abstractions;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Logging.Abstractions;
namespace BTCPayServer.Logging
{
@ -43,7 +40,7 @@ namespace BTCPayServer.Logging
public class FuncLoggerFactory : ILoggerFactory
{
private Func<string, ILogger> createLogger;
private readonly Func<string, ILogger> createLogger;
public FuncLoggerFactory(Func<string, ILogger> createLogger)
{
this.createLogger = createLogger;

View File

@ -4,9 +4,6 @@
using System;
using System.IO;
using System.Text;
using System.Collections;
using System.Collections.Generic;
using Newtonsoft.Json;
namespace Microsoft.Extensions.Logging.Console.Internal
@ -128,7 +125,7 @@ namespace Microsoft.Extensions.Logging.Console.Internal
}
}
internal class AnsiSystemConsole : IAnsiSystemConsole
internal class AnsiSystemConsole : IAnsiSystemConsole
{
private readonly TextWriter _textWriter;
@ -151,13 +148,13 @@ namespace Microsoft.Extensions.Logging.Console
{
void Write(string message);
}
public interface IConsole
public interface IConsole
{
void Write(string message, ConsoleColor? background, ConsoleColor? foreground);
void WriteLine(string message, ConsoleColor? background, ConsoleColor? foreground);
void Flush();
}
internal class WindowsLogConsole : IConsole
internal class WindowsLogConsole : IConsole
{
private readonly TextWriter _textWriter;

View File

@ -1,9 +1,6 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System;
using System.Runtime.CompilerServices;
using System.Threading;
using System.Threading.Tasks;
namespace BTCPayServer
{

View File

@ -1,5 +1,3 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.IO.Compression;
using System.Text;

View File

@ -3,10 +3,16 @@
<Import Project="../Build/Common.csproj" />
<ItemGroup>
<FrameworkReference Include="Microsoft.AspNetCore.App" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="3.1.1" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="3.1.1" />
<PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="3.1.0" />
<PackageReference Include="Pomelo.EntityFrameworkCore.MySql" Version="3.1.0" />
<PackageReference Include="Microsoft.AspNetCore.Identity.EntityFrameworkCore" Version="3.1.1" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="3.1.4">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="3.1.4" />
<PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="3.1.4" />
<PackageReference Include="Pomelo.EntityFrameworkCore.MySql" Version="3.1.1" />
<PackageReference Include="Microsoft.AspNetCore.Identity.EntityFrameworkCore" Version="3.1.4" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\BTCPayServer.Client\BTCPayServer.Client.csproj" />
</ItemGroup>
</Project>

View File

@ -1,10 +1,5 @@
using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.EntityFrameworkCore;
namespace BTCPayServer.Data
{
@ -22,20 +17,35 @@ namespace BTCPayServer.Data
[MaxLength(50)] public string UserId { get; set; }
public APIKeyType Type { get; set; } = APIKeyType.Legacy;
public string Permissions { get; set; }
public byte[] Blob { get; set; }
public StoreData StoreData { get; set; }
public ApplicationUser User { get; set; }
public string Label { get; set; }
public string[] GetPermissions() { return Permissions?.Split(';') ?? new string[0]; }
public void SetPermissions(IEnumerable<string> permissions)
internal static void OnModelCreating(ModelBuilder builder)
{
Permissions = string.Join(';',
permissions?.Select(s => s.Replace(";", string.Empty)) ?? new string[0]);
builder.Entity<APIKeyData>()
.HasOne(o => o.StoreData)
.WithMany(i => i.APIKeys)
.HasForeignKey(i => i.StoreId).OnDelete(DeleteBehavior.Cascade);
builder.Entity<APIKeyData>()
.HasOne(o => o.User)
.WithMany(i => i.APIKeys)
.HasForeignKey(i => i.UserId).OnDelete(DeleteBehavior.Cascade);
builder.Entity<APIKeyData>()
.HasIndex(o => o.StoreId);
}
}
public class APIKeyBlob
{
public string[] Permissions { get; set; }
}
public enum APIKeyType
{
Legacy,

View File

@ -1,7 +1,5 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System;
using Microsoft.EntityFrameworkCore;
namespace BTCPayServer.Data
{
@ -32,5 +30,15 @@ namespace BTCPayServer.Data
get; set;
}
internal static void OnModelCreating(ModelBuilder builder)
{
builder.Entity<AddressInvoiceData>()
.HasOne(o => o.InvoiceData)
.WithMany(i => i.AddressInvoices).OnDelete(DeleteBehavior.Cascade);
builder.Entity<AddressInvoiceData>()
#pragma warning disable CS0618
.HasKey(o => o.Address);
#pragma warning restore CS0618
}
}
}

View File

@ -1,7 +1,5 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System;
using Microsoft.EntityFrameworkCore;
using Newtonsoft.Json;
namespace BTCPayServer.Data
@ -37,5 +35,14 @@ namespace BTCPayServer.Data
{
Settings = value == null ? null : JsonConvert.SerializeObject(value);
}
internal static void OnModelCreating(ModelBuilder builder)
{
builder.Entity<AppData>()
.HasOne(o => o.StoreData)
.WithMany(i => i.Apps).OnDelete(DeleteBehavior.Cascade);
builder.Entity<AppData>()
.HasOne(a => a.StoreData);
}
}
}

View File

@ -1,4 +1,4 @@
using System;
using System;
using System.Linq;
using Microsoft.AspNetCore.Identity.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore;
@ -11,15 +11,15 @@ namespace BTCPayServer.Data
{
public ApplicationDbContext CreateDbContext(string[] args)
{
var builder = new DbContextOptionsBuilder<ApplicationDbContext>();
builder.UseSqlite("Data Source=temp.db");
return new ApplicationDbContext(builder.Options, true);
}
}
public class ApplicationDbContext : IdentityDbContext<ApplicationUser>
{
private readonly bool _designTime;
@ -34,88 +34,35 @@ namespace BTCPayServer.Data
{
get; set;
}
public DbSet<AppData> Apps
{
get; set;
}
public DbSet<InvoiceEventData> InvoiceEvents
{
get; set;
}
public DbSet<HistoricalAddressInvoiceData> HistoricalAddressInvoices
{
get; set;
}
public DbSet<PendingInvoiceData> PendingInvoices
{
get; set;
}
public DbSet<RefundAddressesData> RefundAddresses
{
get; set;
}
public DbSet<PaymentData> Payments
{
get; set;
}
public DbSet<PaymentRequestData> PaymentRequests
public DbSet<RefundData> Refunds
{
get; set;
}
public DbSet<PlannedTransaction> PlannedTransactions { get; set; }
public DbSet<PayjoinLock> PayjoinLocks { get; set; }
public DbSet<AppData> Apps { get; set; }
public DbSet<InvoiceEventData> InvoiceEvents { get; set; }
public DbSet<OffchainTransactionData> OffchainTransactions { get; set; }
public DbSet<HistoricalAddressInvoiceData> HistoricalAddressInvoices { get; set; }
public DbSet<PendingInvoiceData> PendingInvoices { get; set; }
public DbSet<PaymentData> Payments { get; set; }
public DbSet<PaymentRequestData> PaymentRequests { get; set; }
public DbSet<PullPaymentData> PullPayments { get; set; }
public DbSet<PayoutData> Payouts { get; set; }
public DbSet<WalletData> Wallets { get; set; }
public DbSet<WalletTransactionData> WalletTransactions { get; set; }
public DbSet<StoreData> Stores { get; set; }
public DbSet<UserStore> UserStore { get; set; }
public DbSet<AddressInvoiceData> AddressInvoices { get; set; }
public DbSet<SettingData> Settings { get; set; }
public DbSet<PairingCodeData> PairingCodes { get; set; }
public DbSet<PairedSINData> PairedSINData { get; set; }
public DbSet<APIKeyData> ApiKeys { get; set; }
public DbSet<StoredFile> Files { get; set; }
public DbSet<U2FDevice> U2FDevices { get; set; }
public DbSet<NotificationData> Notifications { get; set; }
public DbSet<StoreData> Stores
{
get; set;
}
public DbSet<UserStore> UserStore
{
get; set;
}
public DbSet<AddressInvoiceData> AddressInvoices
{
get; set;
}
public DbSet<SettingData> Settings
{
get; set;
}
public DbSet<PairingCodeData> PairingCodes
{
get; set;
}
public DbSet<PairedSINData> PairedSINData
{
get; set;
}
public DbSet<APIKeyData> ApiKeys
{
get; set;
}
public DbSet<StoredFile> Files
{
get; set;
}
public DbSet<U2FDevice> U2FDevices { get; set; }
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
var isConfigured = optionsBuilder.Options.Extensions.OfType<RelationalOptionsExtension>().Any();
@ -126,140 +73,44 @@ namespace BTCPayServer.Data
protected override void OnModelCreating(ModelBuilder builder)
{
base.OnModelCreating(builder);
builder.Entity<InvoiceData>()
.HasOne(o => o.StoreData)
.WithMany(a => a.Invoices).OnDelete(DeleteBehavior.Cascade);
builder.Entity<InvoiceData>().HasIndex(o => o.StoreDataId);
NotificationData.OnModelCreating(builder);
InvoiceData.OnModelCreating(builder);
PaymentData.OnModelCreating(builder);
Data.UserStore.OnModelCreating(builder);
APIKeyData.OnModelCreating(builder);
AppData.OnModelCreating(builder);
AddressInvoiceData.OnModelCreating(builder);
PairingCodeData.OnModelCreating(builder);
PendingInvoiceData.OnModelCreating(builder);
Data.PairedSINData.OnModelCreating(builder);
HistoricalAddressInvoiceData.OnModelCreating(builder);
InvoiceEventData.OnModelCreating(builder);
PaymentRequestData.OnModelCreating(builder);
WalletTransactionData.OnModelCreating(builder);
PullPaymentData.OnModelCreating(builder);
PayoutData.OnModelCreating(builder);
RefundData.OnModelCreating(builder);
builder.Entity<PaymentData>()
.HasOne(o => o.InvoiceData)
.WithMany(i => i.Payments).OnDelete(DeleteBehavior.Cascade);
builder.Entity<PaymentData>()
.HasIndex(o => o.InvoiceDataId);
builder.Entity<RefundAddressesData>()
.HasOne(o => o.InvoiceData)
.WithMany(i => i.RefundAddresses).OnDelete(DeleteBehavior.Cascade);
builder.Entity<RefundAddressesData>()
.HasIndex(o => o.InvoiceDataId);
builder.Entity<UserStore>()
.HasOne(o => o.StoreData)
.WithMany(i => i.UserStores).OnDelete(DeleteBehavior.Cascade);
builder.Entity<UserStore>()
.HasKey(t => new
{
t.ApplicationUserId,
t.StoreDataId
});
builder.Entity<APIKeyData>()
.HasOne(o => o.StoreData)
.WithMany(i => i.APIKeys)
.HasForeignKey(i => i.StoreId).OnDelete(DeleteBehavior.Cascade);
builder.Entity<APIKeyData>()
.HasOne(o => o.User)
.WithMany(i => i.APIKeys)
.HasForeignKey(i => i.UserId).OnDelete(DeleteBehavior.Cascade);
builder.Entity<APIKeyData>()
.HasIndex(o => o.StoreId);
builder.Entity<AppData>()
.HasOne(o => o.StoreData)
.WithMany(i => i.Apps).OnDelete(DeleteBehavior.Cascade);
builder.Entity<AppData>()
.HasOne(a => a.StoreData);
builder.Entity<UserStore>()
.HasOne(pt => pt.ApplicationUser)
.WithMany(p => p.UserStores)
.HasForeignKey(pt => pt.ApplicationUserId);
builder.Entity<UserStore>()
.HasOne(pt => pt.StoreData)
.WithMany(t => t.UserStores)
.HasForeignKey(pt => pt.StoreDataId);
builder.Entity<AddressInvoiceData>()
.HasOne(o => o.InvoiceData)
.WithMany(i => i.AddressInvoices).OnDelete(DeleteBehavior.Cascade);
builder.Entity<AddressInvoiceData>()
#pragma warning disable CS0618
.HasKey(o => o.Address);
#pragma warning restore CS0618
builder.Entity<PairingCodeData>()
.HasKey(o => o.Id);
builder.Entity<PendingInvoiceData>()
.HasOne(o => o.InvoiceData)
.WithMany(o => o.PendingInvoices)
.HasForeignKey(o => o.Id).OnDelete(DeleteBehavior.Cascade);
builder.Entity<PairedSINData>()
.HasOne(o => o.StoreData)
.WithMany(i => i.PairedSINs).OnDelete(DeleteBehavior.Cascade);
builder.Entity<PairedSINData>(b =>
if (Database.IsSqlite() && !_designTime)
{
b.HasIndex(o => o.SIN);
b.HasIndex(o => o.StoreDataId);
});
builder.Entity<HistoricalAddressInvoiceData>()
.HasOne(o => o.InvoiceData)
.WithMany(i => i.HistoricalAddressInvoices).OnDelete(DeleteBehavior.Cascade);
builder.Entity<HistoricalAddressInvoiceData>()
.HasKey(o => new
// SQLite does not have proper support for DateTimeOffset via Entity Framework Core, see the limitations
// here: https://docs.microsoft.com/en-us/ef/core/providers/sqlite/limitations#query-limitations
// To work around this, when the Sqlite database provider is used, all model properties of type DateTimeOffset
// use the DateTimeOffsetToBinaryConverter
// Based on: https://github.com/aspnet/EntityFrameworkCore/issues/10784#issuecomment-415769754
// This only supports millisecond precision, but should be sufficient for most use cases.
foreach (var entityType in builder.Model.GetEntityTypes())
{
o.InvoiceDataId,
#pragma warning disable CS0618
o.Address
#pragma warning restore CS0618
});
builder.Entity<InvoiceEventData>()
.HasOne(o => o.InvoiceData)
.WithMany(i => i.Events).OnDelete(DeleteBehavior.Cascade);
builder.Entity<InvoiceEventData>()
.HasKey(o => new
{
o.InvoiceDataId,
#pragma warning disable CS0618
o.UniqueId
#pragma warning restore CS0618
});
builder.Entity<PaymentRequestData>()
.HasOne(o => o.StoreData)
.WithMany(i => i.PaymentRequests)
.OnDelete(DeleteBehavior.Cascade);
builder.Entity<PaymentRequestData>()
.Property(e => e.Created)
.HasDefaultValue(new DateTimeOffset(1970, 1, 1, 0, 0, 0, TimeSpan.Zero));
builder.Entity<PaymentRequestData>()
.HasIndex(o => o.Status);
builder.Entity<WalletTransactionData>()
.HasKey(o => new
{
o.WalletDataId,
#pragma warning disable CS0618
o.TransactionId
#pragma warning restore CS0618
});
builder.Entity<WalletTransactionData>()
.HasOne(o => o.WalletData)
.WithMany(w => w.WalletTransactions).OnDelete(DeleteBehavior.Cascade);
var properties = entityType.ClrType.GetProperties().Where(p => p.PropertyType == typeof(DateTimeOffset));
foreach (var property in properties)
{
builder
.Entity(entityType.Name)
.Property(property.Name)
.HasConversion(new Microsoft.EntityFrameworkCore.Storage.ValueConversion.DateTimeOffsetToBinaryConverter());
}
}
}
}
}

View File

@ -1,13 +1,9 @@
using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata;
using Microsoft.EntityFrameworkCore.Migrations;
using Npgsql.EntityFrameworkCore.PostgreSQL.Migrations;
using JetBrains.Annotations;
using Npgsql.EntityFrameworkCore.PostgreSQL.Migrations.Operations;
using Microsoft.EntityFrameworkCore.Metadata;
namespace BTCPayServer.Data
{
@ -19,8 +15,8 @@ namespace BTCPayServer.Data
}
public class ApplicationDbContextFactory
{
string _ConnectionString;
DatabaseType _Type;
readonly string _ConnectionString;
readonly DatabaseType _Type;
public ApplicationDbContextFactory(DatabaseType type, string connectionString)
{
_ConnectionString = connectionString ?? throw new ArgumentNullException(nameof(connectionString));
@ -45,7 +41,7 @@ namespace BTCPayServer.Data
class CustomNpgsqlMigrationsSqlGenerator : NpgsqlMigrationsSqlGenerator
{
public CustomNpgsqlMigrationsSqlGenerator(MigrationsSqlGeneratorDependencies dependencies, IMigrationsAnnotationProvider annotations, Npgsql.EntityFrameworkCore.PostgreSQL.Infrastructure.Internal.INpgsqlOptions opts) : base(dependencies, annotations, opts)
public CustomNpgsqlMigrationsSqlGenerator(MigrationsSqlGeneratorDependencies dependencies, IMigrationsAnnotationProvider annotations, Npgsql.EntityFrameworkCore.PostgreSQL.Infrastructure.Internal.INpgsqlOptions opts) : base(dependencies, annotations, opts)
{
}

View File

@ -1,15 +1,12 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Identity;
using BTCPayServer.Data;
namespace BTCPayServer.Data
{
// Add profile data for application users by adding properties to the ApplicationUser class
public class ApplicationUser : IdentityUser
{
public List<NotificationData> Notifications { get; set; }
public List<UserStore> UserStores
{
get;
@ -26,7 +23,7 @@ namespace BTCPayServer.Data
get;
set;
}
public List<U2FDevice> U2FDevices { get; set; }
public List<APIKeyData> APIKeys { get; set; }
}

View File

@ -1,7 +1,5 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System;
using Microsoft.EntityFrameworkCore;
namespace BTCPayServer.Data
{
@ -40,5 +38,20 @@ namespace BTCPayServer.Data
{
get; set;
}
internal static void OnModelCreating(ModelBuilder builder)
{
builder.Entity<HistoricalAddressInvoiceData>()
.HasOne(o => o.InvoiceData)
.WithMany(i => i.HistoricalAddressInvoices).OnDelete(DeleteBehavior.Cascade);
builder.Entity<HistoricalAddressInvoiceData>()
.HasKey(o => new
{
o.InvoiceDataId,
#pragma warning disable CS0618
o.Address
#pragma warning restore CS0618
});
}
}
}

View File

@ -1,7 +1,7 @@
using System;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.ComponentModel.DataAnnotations.Schema;
using Microsoft.EntityFrameworkCore;
namespace BTCPayServer.Data
{
@ -25,7 +25,6 @@ namespace BTCPayServer.Data
{
get; set;
}
public List<PaymentData> Payments
{
get; set;
@ -36,11 +35,6 @@ namespace BTCPayServer.Data
get; set;
}
public List<RefundAddressesData> RefundAddresses
{
get; set;
}
public List<HistoricalAddressInvoiceData> HistoricalAddressInvoices
{
get; set;
@ -79,6 +73,20 @@ namespace BTCPayServer.Data
{
get; set;
}
public bool Archived { get; set; }
public List<PendingInvoiceData> PendingInvoices { get; set; }
public List<RefundData> Refunds { get; set; }
public string CurrentRefundId { get; set; }
[ForeignKey("Id,CurrentRefundId")]
public RefundData CurrentRefund { get; set; }
internal static void OnModelCreating(ModelBuilder builder)
{
builder.Entity<InvoiceData>()
.HasOne(o => o.StoreData)
.WithMany(a => a.Invoices).OnDelete(DeleteBehavior.Cascade);
builder.Entity<InvoiceData>().HasIndex(o => o.StoreDataId);
builder.Entity<InvoiceData>()
.HasOne(o => o.CurrentRefund);
}
}
}

View File

@ -1,7 +1,5 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System;
using Microsoft.EntityFrameworkCore;
namespace BTCPayServer.Data
{
@ -22,5 +20,20 @@ namespace BTCPayServer.Data
}
public string Message { get; set; }
internal static void OnModelCreating(ModelBuilder builder)
{
builder.Entity<InvoiceEventData>()
.HasOne(o => o.InvoiceData)
.WithMany(i => i.Events).OnDelete(DeleteBehavior.Cascade);
builder.Entity<InvoiceEventData>()
.HasKey(o => new
{
o.InvoiceDataId,
#pragma warning disable CS0618
o.UniqueId
#pragma warning restore CS0618
});
}
}
}

View File

@ -0,0 +1,30 @@
using System;
using System.ComponentModel.DataAnnotations;
using Microsoft.EntityFrameworkCore;
namespace BTCPayServer.Data
{
public class NotificationData
{
[MaxLength(36)]
public string Id { get; set; }
public DateTimeOffset Created { get; set; }
[MaxLength(50)]
[Required]
public string ApplicationUserId { get; set; }
public ApplicationUser ApplicationUser { get; set; }
[MaxLength(100)]
[Required]
public string NotificationType { get; set; }
public bool Seen { get; set; }
public byte[] Blob { get; set; }
internal static void OnModelCreating(ModelBuilder builder)
{
builder.Entity<NotificationData>()
.HasOne(o => o.ApplicationUser)
.WithMany(n => n.Notifications)
.HasForeignKey(k => k.ApplicationUserId).OnDelete(DeleteBehavior.Cascade);
}
}
}

View File

@ -0,0 +1,12 @@
using System.ComponentModel.DataAnnotations;
namespace BTCPayServer.Data
{
public class OffchainTransactionData
{
[Key]
[MaxLength(32 * 2)]
public string Id { get; set; }
public byte[] Blob { get; set; }
}
}

View File

@ -1,7 +1,5 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System;
using Microsoft.EntityFrameworkCore;
namespace BTCPayServer.Data
{
@ -33,5 +31,17 @@ namespace BTCPayServer.Data
{
get; set;
}
internal static void OnModelCreating(ModelBuilder builder)
{
builder.Entity<PairedSINData>()
.HasOne(o => o.StoreData)
.WithMany(i => i.PairedSINs).OnDelete(DeleteBehavior.Cascade);
builder.Entity<PairedSINData>(b =>
{
b.HasIndex(o => o.SIN);
b.HasIndex(o => o.StoreDataId);
});
}
}
}

View File

@ -1,7 +1,5 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System;
using Microsoft.EntityFrameworkCore;
namespace BTCPayServer.Data
{
@ -46,5 +44,11 @@ namespace BTCPayServer.Data
get;
set;
}
internal static void OnModelCreating(ModelBuilder builder)
{
builder.Entity<PairingCodeData>()
.HasKey(o => o.Id);
}
}
}

View File

@ -0,0 +1,16 @@
using System.ComponentModel.DataAnnotations;
namespace BTCPayServer.Data
{
/// <summary>
/// We represent the locks of the PayjoinRepository
/// with this table. (Both, our utxo we locked as part of a payjoin
/// and the utxo of the payer which were used to pay us)
/// </summary>
public class PayjoinLock
{
[Key]
[MaxLength(100)]
public string Id { get; set; }
}
}

View File

@ -1,7 +1,4 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.EntityFrameworkCore;
namespace BTCPayServer.Data
{
@ -29,5 +26,14 @@ namespace BTCPayServer.Data
{
get; set;
}
internal static void OnModelCreating(ModelBuilder builder)
{
builder.Entity<PaymentData>()
.HasOne(o => o.InvoiceData)
.WithMany(i => i.Payments).OnDelete(DeleteBehavior.Cascade);
builder.Entity<PaymentData>()
.HasIndex(o => o.InvoiceDataId);
}
}
}

View File

@ -1,6 +1,5 @@
using System;
using System.Collections.Generic;
using System.Text;
using System;
using Microsoft.EntityFrameworkCore;
namespace BTCPayServer.Data
{
@ -12,34 +11,25 @@ namespace BTCPayServer.Data
get; set;
}
public string StoreDataId { get; set; }
public bool Archived { get; set; }
public StoreData StoreData { get; set; }
public PaymentRequestStatus Status { get; set; }
public Client.Models.PaymentRequestData.PaymentRequestStatus Status { get; set; }
public byte[] Blob { get; set; }
public class PaymentRequestBlob
internal static void OnModelCreating(ModelBuilder builder)
{
public decimal Amount { get; set; }
public string Currency { get; set; }
public DateTime? ExpiryDate { get; set; }
public string Title { get; set; }
public string Description { get; set; }
public string Email { get; set; }
public string EmbeddedCSS { get; set; }
public string CustomCSSLink { get; set; }
public bool AllowCustomPaymentAmounts { get; set; }
}
public enum PaymentRequestStatus
{
Pending = 0,
Completed = 1,
Expired = 2
builder.Entity<PaymentRequestData>()
.HasOne(o => o.StoreData)
.WithMany(i => i.PaymentRequests)
.OnDelete(DeleteBehavior.Cascade);
builder.Entity<PaymentRequestData>()
.Property(e => e.Created)
.HasDefaultValue(new DateTimeOffset(1970, 1, 1, 0, 0, 0, TimeSpan.Zero));
builder.Entity<PaymentRequestData>()
.HasIndex(o => o.Status);
}
}
}

View File

@ -0,0 +1,62 @@
using System;
using System.ComponentModel.DataAnnotations;
using Microsoft.EntityFrameworkCore;
using NBitcoin;
namespace BTCPayServer.Data
{
public class PayoutData
{
[Key]
[MaxLength(30)]
public string Id { get; set; }
public DateTimeOffset Date { get; set; }
public string PullPaymentDataId { get; set; }
public PullPaymentData PullPaymentData { get; set; }
[MaxLength(20)]
public PayoutState State { get; set; }
[MaxLength(20)]
[Required]
public string PaymentMethodId { get; set; }
public string Destination { get; set; }
public byte[] Blob { get; set; }
public byte[] Proof { get; set; }
public bool IsInPeriod(PullPaymentData pp, DateTimeOffset now)
{
var period = pp.GetPeriod(now);
if (period is { } p)
{
return p.Start <= Date && (p.End is DateTimeOffset end ? Date < end : true);
}
else
{
return false;
}
}
internal static void OnModelCreating(ModelBuilder builder)
{
builder.Entity<PayoutData>()
.HasOne(o => o.PullPaymentData)
.WithMany(o => o.Payouts).OnDelete(DeleteBehavior.Cascade);
builder.Entity<PayoutData>()
.Property(o => o.State)
.HasConversion<string>();
builder.Entity<PayoutData>()
.HasIndex(o => o.Destination)
.IsUnique();
builder.Entity<PayoutData>()
.HasIndex(o => o.State);
}
}
public enum PayoutState
{
AwaitingApproval,
AwaitingPayment,
InProgress,
Completed,
Cancelled
}
}

Some files were not shown because too many files have changed in this diff Show More