Compare commits

..

374 Commits

Author SHA1 Message Date
d18246bfbe Do not enable receipts for payment requests
Payment requests have a receipt-ish style by default. Receipts for each individual invoice of a payment request can be quite confusing as individually they do not prove the pay request was settled.
2022-11-24 15:21:28 +01:00
bb60c2ac48 Checkout v2: Minor fixes (#4345)
* Do not show remaining amount for topup invoices in expiry message

As [reported by @petzsch](https://chat.btcpayserver.org/btcpayserver/pl/gg1zy8t5h3dq7nme1nom93migo).

* Fix links on result page in Checkout Classic

Closes #4344.

* Better way to exclude Lightning if BIP21 is active and we have both PMs


Unify margins
2022-11-24 23:14:56 +09:00
a4ee1e9805 Checkout v2 finetuning (#4276)
* Indent all JSON files with two spaces

* Upgrade Vue.js

* Cheat mode improvements

* Show payment details in case of expired invoice

* Add logo size recommendation

* Show clipboard copy hint cursor

* Improve info area and wording

* Update BIP21 wording

* Invoice details adjustments

* Remove form; switch payment methods via AJAX

* UI updates

* Decrease paddings to gain space

* Tighten up padding between logo mark and the store title text

* Add drop-shadow to the containers

* Wording

* Cheating improvements

* Improve footer spacing

* Cheating improvements

* Display addresses

* More improvements

* Expire invoices

* Customize invoice expiry

* Footer improvements

* Remove theme switch

* Remove non-existing sourcemap references

* Move inline JS to checkout.js file

* Plugin compatibility

See Kukks/btcpayserver#8

* Test fix

* Upgrade vue-i18next

* Extract translations into a separate file

* Round QR code borders

* Remove "Pay with Bitcoin" title in BIP21 case

* Add copy hint to payment details

* Cheating: Reduce margins

* Adjust dt color

* Hide addresses for first iteration

* Improve View Details button

* Make info section collapsible

* Revert original en locale file

* Checkout v2 tests

* Result view link fixes

* Fix BIP21 + lazy payment methods case

* More result page link improvements

* minor visual improvements

* Update clipboard code

Remove fallback for old browsers. https://caniuse.com/?search=navigator.clipboard

* Transition copy symbol

* Update info text color

* Invert dark neutral colors

Simplifies the dark theme quite a bit.

* copy adjustments

* updates QR border-radius

* Add option to remove logo

* More checkout v2 test cases

* JS improvements

* Remove leftovers

* Update test

* Fix links

* Update tests

* Update plugins integration

* Remove obsolete url code

* Minor view update

* Update JS to not use arrow functions

* Remove FormId from Checkout Appearance settings

* Add English-only hint and feedback link

* Checkout Appearance: Make options clearer, remove Custom CSS for v2

* Clipboard copy full URL instead of just address/BOLT11

* Upgrade JS libs, add content checks

* Add test for BIP21 setting with zero amount invoice

Co-authored-by: dstrukt <gfxdsign@gmail.com>
2022-11-24 08:53:32 +09:00
bf0a8c1e62 Fix flaky test ln payout (#4334) 2022-11-23 21:02:47 +09:00
d2b10ef4e6 CanUseTorClient fail no more 2022-11-22 21:58:15 +09:00
9f3fca8fd7 Show the git commit of the current build of BTCPay (#4320)
* Show the git commit of the current build of BTCPay

* Fix build

Co-authored-by: d11n <mail@dennisreimann.de>
2022-11-22 21:37:07 +09:00
9404819dbe Fix flaky test (#4330)
* Fix flaky test

* Update BTCPayServer/PayoutProcessors/BaseAutomatedPayoutProcessor.cs

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

Co-authored-by: d11n <mail@dennisreimann.de>
2022-11-22 12:17:29 +01:00
d959f5096b Add documentation link to plugins (#4329)
* Add documentation link to plugins

* Minor UI updates

Co-authored-by: Dennis Reimann <mail@dennisreimann.de>
2022-11-22 11:06:23 +01:00
bd3710a60f Merge pull request #4327 from btcpayserver/dennisreimann-patch-1 2022-11-22 06:58:10 +01:00
3d43f3a2b3 Change confirmed to settled. (#4328) 2022-11-22 11:10:21 +09:00
6194c156bd Server Settings: Update Policies page (#4326)
Handles the multiple submit buttons on that page and closes #4319.

Contains some UI unifications with other pages and also shows the block explorers without needing to toggle the section via JS.
2022-11-22 10:27:27 +09:00
850c26dc13 POS: Fix null pointer
Introduced in #4307, the referenced object needs to be `itemChoice` instead of `choice`.
2022-11-21 22:07:46 +01:00
eda0f7327e fix monero issue 2022-11-21 19:55:19 +01:00
bf597495ff Fix: If reverse proxy wasn't well configured, and error message should have been displayed (#4322) 2022-11-21 19:32:19 +01:00
20025f254c Use the plugin builder website instead of docker to fetch plugins (#4285) 2022-11-21 10:23:25 +09:00
ec76acd3a6 Code analysis (#4293)
* Enable NETAnalyzers for whole project

- remove obsolete analyzers so that the .NET Core SDK NETAnalyzers can be used
- enable NETAnalyzers for all projects so that developers can use them by defining the AnalysisMode on individual projects

This is because if we set AnalysisMode to minimal, recommended or all it would spam with warning.
The idea is to be able to turn them on during development to fix recommended stuff without polluting the build output.

Following commits will implement some of the Code Analysis findings

* Performance hints for using char overloads for single characters (CA1834 and CA1847)

CA1834: Use StringBuilder.Append(char) for single character strings
CA1847: Use string.Contains(char) instead of string.Contains(string) with single characters
2022-11-20 17:42:36 +09:00
1e2acfb296 Disable internal node options if no internal node configured (#4315) 2022-11-20 14:22:36 +09:00
2bd4a680ad Fix tests 2022-11-20 14:19:48 +09:00
4ce504a1e1 Add index to WalletObjects + allow additional queries 2022-11-19 23:39:41 +09:00
d2f071b8b2 Make store creation field same width (#4311)
* Make store creation field same width

Closes #4306.

* Update CreateStore.cshtml
2022-11-19 11:29:34 +01:00
fdbd7b977a Merge pull request #4312 from btcpayserver/non-admin-wallet-warning
Refine non-admin wallet warning copy
2022-11-19 09:44:22 +01:00
d19961b7a0 Refine non-admin wallet warning copy
As [discussed on Mattermost](https://chat.btcpayserver.org/btcpayserver/pl/us4kscqsw7rzmnng7aarxczd5r).
2022-11-18 22:12:53 +01:00
c156254600 Validate cart cost with explicit amount 2022-11-18 16:50:26 +01:00
9b5c6ece90 Refactor walletobj API, make wallet object graph directionless (#4297) 2022-11-19 00:04:46 +09:00
bf91efc756 Add Lightning Service Torq (#4296) 2022-11-18 12:19:01 +01:00
a253fd5001 Small doc improve 2022-11-18 14:22:59 +09:00
52af129c8b Add crowdfund app create endpoint (#4068)
* Add crowdfund app create endpoint

* replace DateTimeJsonConverter with NBitcoin.JsonConverters.DateTimeToUnixTimeConverter

* Use DateTimeOffset instead of DateTime

* Use array instead of CSV

* update "startDate" and "endDate" docs definition

* update docs
2022-11-18 14:20:07 +09:00
3942463ac9 UI: Unify payment request list with invoices (#4294)
Some quick win updates to the payment requests list that unify the display with the invoices list:

- Status is displayed as badge
- Amount is properly formatted
- Expiry date format and ability to switch to relative date
2022-11-18 13:24:57 +09:00
ff572eef7f Use constants rather than magic strings in transaction attachments 2022-11-17 10:24:49 +09:00
2740dfea87 Greenfield: Wallet Objects (#4274)
Co-authored-by: Nicolas Dorier <nicolas.dorier@gmail.com>
2022-11-16 12:11:17 +09:00
324112b73b Receipts: Fix amount paid discrepancy (#4287)
Displays the actual amount paid instead of the total invoice price. Fixes #4242.
2022-11-16 11:35:49 +09:00
1d7dee8314 Fix NRE and do nto activate onchain if node unavailable even when lazy payments (#4291)
fixes #4289
2022-11-16 09:04:51 +09:00
2d23819944 Greenfield: Allow marking payout status and payment proofs (#4244)
This allows external services to integrate with the payouts system to process payouts. This is also  a step to allow plugins to provide payout processors.

* It provides the payment proof through the greenfield payoust api.
* It allows you to set the state of a payout outside of the usual flow:
  * When state is awaiting payment, allow setting to In progess or completed
  * When state is in progress, allow setting back to awaiting payment
2022-11-15 18:40:57 +09:00
17f3b4125b Add option to customize the instance logo (#4258)
* Add option to customize the instance logo


Custom logo for BTCPay instances

* Incorporate SVGUse helper
2022-11-14 22:29:23 +09:00
c8a1024e24 Remove dead shitcoin MUE 2022-11-14 15:59:41 +09:00
9a2d2e2d89 Confirm modal: Prevent form submit without confirmation (#4262)
Fixes https://github.com/btcpayserver/btcpayserver/issues/4259
2022-11-13 12:38:13 +01:00
b7af234427 Payment Request: Fix invoice creation
Fix and test for a regression introduced with #4243: As the `PayPaymentRequest` action allows anonymous access, the `CookieAuthorizationHandler` isn;t run and hence the `GetCurrentStore` returns `null`.

This leads to an exception when creating the invoice. Store needs to be fetched seperately - like [before](4bbc7d9662 (diff-bdc264670a171e862d09fdf1a1c9f3ca14b41982a3c4c8e66d4f780cdde9f21dL241)).
2022-11-10 18:23:41 +01:00
a374e351e2 Use PluginLoader in the Plugin packer to prevent conflicts (#4277) 2022-11-09 15:28:16 +01:00
562f88555c Lightning: Better handling for non-public nodes (#4263)
Fixes #4246. 

`LightningLikePaymentHandler.GetNodeInfo` needed the `throws` argument to handle the cases as previously, otherwise the catch case in `ShowLightningNodeInfo` never occured.

State with this PR: A node can be available, but not have any public addresses. The latter will now be reported when testing the connection and on the public node info page.
2022-11-05 12:21:24 +01:00
167c5297fa Merge pull request #4268 from dennisreimann/supporters
Supporters: Remove Nomics; add SVGs for README
2022-11-05 12:17:11 +01:00
b281d09694 Bumping LND to 0.15.4-beta-1 (#4271)
* Bumping LND to 0.15.4-beta-1

* Bump LND in Altcoin docker-compose

Co-authored-by: Dennis Reimann <mail@dennisreimann.de>
2022-11-05 12:15:04 +01:00
853a0ac5ea Remove old/unused images 2022-11-03 21:58:53 +01:00
ea948cfc3f Optimize SVGs 2022-11-03 21:55:11 +01:00
fdd13390fb Merge pull request #4267 from dennisreimann/fix-4266
Fix wording
2022-11-03 19:57:34 +01:00
b2f6f8b3c1 Supporters: Remove Nomics; add SVGs for README
The `img/readme` directory contains SVGs for the README, so that we can from now on use one markup for the supporters in all README files across our repositories. 

With these, we could finally get rid of the table layout for the supporters section in the README. This will make it much easier to maintain those.
2022-11-03 19:37:13 +01:00
cd12162b6f Fix wording
Closes #4266.
2022-11-03 13:13:03 +01:00
79717d1d64 Sync modal improvements (#4260) 2022-11-02 16:55:05 +01:00
e56cbf0baa Greenfield: Graceful return for in-flight HTLCs (#4252)
* Greenfield: Graceful return for in-flight HTLCs

Based on btcpayserver/BTCPayServer.Lightning#106 this closes #3781.

* Update descriptions
2022-11-02 21:03:34 +09:00
05232414ad Improve LN balance details toggle (#4253) 2022-11-02 18:48:23 +09:00
4bbc7d9662 [Greenfield] Can create an invoice for a payment request via Greenfield (#4243)
* [Greenfield] Can create an invoice for a payment request via Greenfield

* Add allowPendingInvoiceReuse so payment request invoices can be reused

* Add PayPaymentRequest to the LocalBTCPayServerClient

* Allow amount to be specified if same as PR amount
2022-11-02 18:41:19 +09:00
3805b7f287 Checkout v2 (#4157)
* Opt-in for new checkout

* Update wording

* Create invoice view update

* Remove jQuery from checkout testing code

* Checkout v2 basics

* WIP

* WIP 2

* Updates and fixes

* Updates

* Design updates

* More design updates

* Cheating and JS fixes

* Use checkout form id whenever invoices get created

* Improve email form handling

* Cleanups

* Payment method exclusion cases for Lightning and LNURL

TODO: Cases and implementation need to be discussed

* Introduce CheckoutType in API and replace UseNewCheckout in backend

Co-authored-by: nicolas.dorier <nicolas.dorier@gmail.com>
2022-11-02 18:21:33 +09:00
63620409a9 Allow config to set default block explorer link (#4249)
This logic can potentially be inside BlockExplorerLinkStartupTask instead but it's not a big deal imo
2022-10-31 11:41:31 +09:00
ba423a79e3 Fix Public Node Info View
As the Node Info was used as an ID, this didn't work with IPv6 addresses, as those contain characters not suitable for HTML IDs.

Fixes #4245.

Also: Simplify the head section of that view by reusing the existing partial.
2022-10-30 11:23:09 +01:00
8806ba76eb Fix: On some circumstances, clicking on cancel invoice and pay button in PaymentRequest would throw an exception 2022-10-27 15:50:35 +09:00
9e73260230 Fix: Invoice's orderId equals to payreq id shouldn't appear part of the payreq 2022-10-27 13:17:18 +09:00
c0125b83d1 UI: Improve access token pairing (#4237)
Closes #4133.
2022-10-27 08:57:54 +09:00
1fa297fb73 Add donate link (#4239)
* Add donate link

Closes #4173.

* Simplify wording
2022-10-27 08:56:44 +09:00
57557748e2 Greenfield: Fix missing payment data (#4233)
* Greenfield: Fix missing payment data

Fixes #4229.

* Client: Return payment data from PayLightningInvoice

* Add test for PayLightningInvoice response
2022-10-27 08:56:24 +09:00
8b79212a6e [Greenfield] Fix: The route to connect to a peer lightning node was always crashing 2022-10-26 13:35:04 +09:00
f4af4ec4dc Fix OpenAPI 3.0 validation errors and warnings (#4235) 2022-10-25 20:37:36 +09:00
2e150f4bf4 Checkout: Fix Order ID text overflow (#4232)
Fixes #4230. Thanks for the pointer @handsomelatino!
2022-10-25 10:46:00 +09:00
4f4aa051c9 Add missing route parameter in /api/v1/stores/{storeId}/users swagger (See #4231) 2022-10-24 16:33:42 +09:00
da1dd7448e Add warnings in btcpay vault page for safari and brave (Fix https://github.com/btcpayserver/BTCPayServer.Vault/issues/54) (#4226)
* Add warnings in btcpay vault page for safari and brave (Fix https://github.com/btcpayserver/BTCPayServer.Vault/issues/54)

* Apply suggestions from code review

Co-authored-by: d11n <mail@dennisreimann.de>
2022-10-21 09:13:36 +02:00
0fd47eeee0 Asset-bundle cleanups (#4225)
Some cleanups in addition to #4222.
2022-10-21 09:17:06 +09:00
54c9d7283a Fix: PayjoinController could throw HTTP 500 of a few corner cases (#4215) 2022-10-20 11:19:48 +09:00
848db5f7de Remove the bundle minifier (#4222) 2022-10-20 11:17:42 +09:00
5fb32fe0e9 Remove some debug code 2022-10-19 13:06:15 +09:00
adf5b4ca0c Fix sync modal z-index 2022-10-18 21:00:54 +02:00
16bfb1dbfe Bump libraries (#4219) 2022-10-18 23:58:28 +09:00
e5421b8a9f Add script to create a regtest multisig wallet for testing (#4204)
* Add script to create a regtest multisig wallet for testing

* Unload wallets to prevent having to specify wallet in BTCPay, NBXplorer
2022-10-17 20:57:09 +09:00
f9f1a22e3b Store settings: Add branding options (#4131)
* Add logo upload

* Add brand color definition

* Cleanups

* Add logo to store selector

* Improve brand color handling

* Update color input

* Add logo dimensions hint

* Fixes

* Fix pattern and warning in js logs for color validation

* Fix condition, add test

Co-authored-by: nicolas.dorier <nicolas.dorier@gmail.com>
2022-10-17 12:16:29 +02:00
9533809631 Bump NBitcoin (Fix #4212) 2022-10-17 18:47:49 +09:00
6d7c11f1b1 Greenfield: Get Lightning invoices (#4180)
* Greenfield: Get Lightning invoices

Matching the data added in btcpayserver/BTCPayServer.Lightning#98 and btcpayserver/BTCPayServer.Lightning#99.

* Small adjustments

Co-authored-by: nicolas.dorier <nicolas.dorier@gmail.com>
2022-10-17 09:51:15 +02:00
0286c72256 Do not crash startup if ssh settings aren't correct 2022-10-14 14:51:05 +09:00
763aaa2926 UI: Fix checkbox flex-shrink (#4209)
Closes #4207.
2022-10-13 22:48:45 +09:00
ae4af7dd13 Bumping LND to 0.15.2-beta (#4211) 2022-10-13 09:40:07 +02:00
4ae2ea32e9 UI: Fix missing timezone in browser dates (#4210)
Fix for an issue brought up by @petzsch in todays dev meeting.
2022-10-13 09:29:30 +02:00
434298cba6 Greenfield: Store Rates Config (#3931)
* Greenfield: Store Rates Config

* FIX SWAGGER

* rebase fix

* Apply suggestions from code review

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

* Update BTCPayServer/wwwroot/swagger/v1/swagger.template.stores-rates-config.json

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

* Fix: Spread isn't converted from/to percentage, rename some fields, and move some routes

* Fix error handling

Co-authored-by: d11n <mail@dennisreimann.de>
Co-authored-by: nicolas.dorier <nicolas.dorier@gmail.com>
2022-10-12 22:19:33 +09:00
a2fa688cde Refactor labels (#4179)
* Create new tables

* wip

* wip

* Refactor LegacyLabel

* Remove LabelFactory

* Add migration

* wip

* wip

* Add pull-payment attachment to tx

* Address kukks points
2022-10-11 17:34:29 +09:00
895462ac7f Import xpub: Surface error details (#4205)
Checks if the input is an output descriptor and explicitely handles that case instead of catching any errors. This allows us to display more detailed information about why an import might fail.
2022-10-11 12:19:10 +09:00
e883714446 Do not hide errors happening in tasks spawned by BaseAsyncService 2022-10-08 12:46:26 +09:00
e1a235b4e8 Changelog and bump (#4201) 2022-10-08 12:42:46 +09:00
ffa2c59df7 POS: Fix keypad view without custom amount (#4185)
The custom amount option was disabled by default in #4126. This requires some additional adaptations in the post action as otherwise the invoice won't be generated.

Fixes #4183.
2022-10-08 12:41:56 +09:00
3f19dc55fa Add "{Invoice.OrderId}" to list of supported email interpolation strings (#4202)
close #4112
2022-10-07 14:29:56 +02:00
66c2148a63 Increase tor test timeout 2022-10-07 16:04:22 +09:00
28850f534c Fix test warning 2022-10-07 15:05:11 +09:00
c40c11a822 bump ms aspnet packages (#4166)
* bump ms aspnet packages

* Bump .NET SDK in Dockerfile

* bump more packages

Co-authored-by: Dennis Reimann <mail@dennisreimann.de>
Co-authored-by: nicolas.dorier <nicolas.dorier@gmail.com>
2022-10-07 14:53:30 +09:00
b334e1aa00 Date display improvements (#4191)
Fixes styling issues introduced in #4074, because the `max-width` was to small for localized dates.

Also adds the ability to choose the prefered initial display format, which can be the localized or relative date.
2022-10-07 13:29:03 +09:00
b48986bfd6 Update default value for "showCustomAmount" in Swagger docs (#4200) 2022-10-07 13:27:10 +09:00
ced63baed6 fix custodian Swagger docs missing some path parameters (#4196) 2022-10-06 12:03:39 +02:00
880635d615 Make sure string is valid URL before rendering it as such in invoice details POS data section (#4197) 2022-10-06 10:43:18 +02:00
d9f8c8d3b1 Always show overpaid amount if invoice is overpaid (#4192)
close #4146
2022-10-06 12:59:05 +09:00
8155841a1d Fix receipts for Lightning Address invoices
`AdditionalData` needs to be null-checked, because it isn't set for invoices generated via Lightning Address. 

Fixes #4169.
2022-10-01 07:13:57 +02:00
30f83d8f3f Remove direct and temp link functionality from the File Storage (#4177) 2022-09-29 12:40:00 +02:00
96c86160df Fix warning error when rebooting the server caused by some shitcoin currency pair format 2022-09-29 15:45:27 +09:00
b7ea128132 Old Payout labels weren't displayed properly 2022-09-29 15:42:01 +09:00
4bee8e9bfe Greenfield: Extend LN GetInfo data (#4167)
Matching the data added in btcpayserver/BTCPayServer.Lightning#97.
2022-09-28 09:34:34 +09:00
bc195e771e Update WalletTransactions pagination default settings (#4074)
* Update WalletTransactions pagination default settings

Remove the numeric page selection and add displaying data of last 30 days by default.

* Update WalletTransactions to show txs based on Days

* Update text formatting on WalletTransactions view

Keeps the logic changes. Just undo the formatting of the file from previous commit

* Update WalletTransactions to show all after second load

Utilize Model.Days instead of new variables
Moved javascript code to PageFootContent section

* Update WalletTransactions to use ajax for infinite scroll

* Cleanups

* Apply skip and count only when not prefiltering

* Infinite scroll mode

* Improve datetime formatting and switching

* Upgrade NBXplorer to include get_wallets_recent bugfix

* Revert "Upgrade NBXplorer to include get_wallets_recent bugfix"

This reverts commit b390d942d74d88bb1da3ab8e3407184a527175ef.

* JS fixes

* Upgrade ChromeDriver and BundleMinifier

Co-authored-by: Dennis Reimann <mail@dennisreimann.de>
2022-09-27 21:24:53 +09:00
0bc3e94052 bump 2022-09-26 22:51:49 +09:00
3eb3523b52 Changelog for v1.6.11 (#4130)
* Changelog for v1.6.11

* Update Changelog.md

Co-authored-by: Nicolas Dorier <nicolas.dorier@gmail.com>

* Update Changelog.md

Co-authored-by: Nicolas Dorier <nicolas.dorier@gmail.com>

* Update changelog

* Update changelog

Co-authored-by: Nicolas Dorier <nicolas.dorier@gmail.com>
2022-09-26 22:50:59 +09:00
8e2f84a989 Upgrade Lightning libraries (#4164) 2022-09-26 22:48:47 +09:00
143ec7463f Fix crash on migration from old install (Fix #4162) 2022-09-26 22:00:49 +09:00
4a5fd08e51 Footer: Improve responsive display (#4163)
Enhancement in addition to #4160.
2022-09-26 10:29:35 +02:00
0306635a45 Merge pull request #4160 from daviogg/enhancement/4158-add-telegram-url
Add telegram icon and url on footer
2022-09-26 09:07:50 +02:00
0a4d32cdb5 Merge pull request #4161 from Bangalisch/SmallPageUpdate
Small update to Security.md
2022-09-26 09:07:33 +02:00
d590992d1d Fix crash on migration from old install (Fix #4162) 2022-09-26 10:31:04 +09:00
e8766946dd Improve currency selection (#4155)
Removes the current value on focus, so that the user gets to see the available options. If no selection or change is made, the value is reset to the previous value on blur.

Closes #4154.
2022-09-26 10:26:13 +09:00
8c35189b37 Small update to Security.md
Yo yo

Added title to page and ran it through Grammarly to slightly update the text.
2022-09-25 00:17:52 +02:00
e6390cde97 Add telegram icon and url on footer 2022-09-24 23:32:28 +02:00
db976a6408 Fix unit test and build warning 2022-09-23 16:41:51 +02:00
031c3ed055 Update README 2022-09-23 19:41:09 +09:00
cb391f08b9 Remove redundant exception status from invoice state label (#4151) 2022-09-23 15:17:50 +09:00
5387a6287e Fix pagination of wallet's transactions (#4150) 2022-09-22 10:39:48 +09:00
0e4544b2da POS - CustomAmount disabled by default also for App 2022-09-20 13:10:42 +02:00
e0cbb7bede POS - CustomAmount disabled by default 2022-09-20 13:10:42 +02:00
ed45b73274 Dashboard: Fix links in app tiles
Fixes #4144.
2022-09-20 10:10:54 +02:00
cadcb586a7 Fix settigs sidebar activation (#4138)
* Fix settigs sidebar activation

* remove active payout from settings

* Fix Store Settings nav highlight

Fixes #4134.

Co-authored-by: Dennis Reimann <mail@dennisreimann.de>
2022-09-20 10:05:55 +02:00
9e31270459 Improve "Advanced Settings" button (#4140)
* Improve "Advanced Settings" button

Closes #4132.

* Use collapse toggle for multi-sig examples
2022-09-20 09:50:59 +02:00
dc07f046f2 Improve PayButton error page (#4129)
As this is a public page we should embed it in the non-navigation layout. Also improves the error display.
2022-09-19 21:56:42 +02:00
5032bbafb1 Consistent switch UI on Create Wallet views (#4135)
* ui+wallet: consistent switch ui update

* Cleanups

* Improve CTA wording

Co-authored-by: Dennis Reimann <mail@dennisreimann.de>
2022-09-19 21:56:16 +02:00
1540bfb3a1 Merge pull request #4128 from bolatovumar/fix/4125 2022-09-17 09:38:54 +02:00
f3f5851118 Add missing store ID to invoice links
close #4125
2022-09-16 21:04:56 -07:00
9810edcd1a Fix Monero and Zcash nav extensions
They failed with an `System.NullReferenceException: Object reference not set to an instance of an object.` when navigating to a LNbank page, because LNbank uses Razor Pages and the controller part wan't defined. Brought up [on Mattermost](https://chat.btcpayserver.org/btcpayserver/pl/x3iohhct97nateyq4y1c4hp9mw).
2022-09-16 11:51:14 +02:00
e334b9162a Fix: Lnurl Max is set to min when item type is minmum
fixes #4108
2022-09-16 09:20:49 +02:00
836c676057 Upgrade Lightning lib 2022-09-15 16:57:57 +02:00
1abadd9c5d Update BTCPayServer/Storage/Services/FileService.cs 2022-09-15 16:26:22 +02:00
e8bd1d8237 FileService: Sanitize filename for downloaded files
Replaces invalid characters in filenames of files which are retrieved via URL.
2022-09-15 16:26:22 +02:00
8a7470500a Do not show set up wallet link in dashboard
fixes #4116
2022-09-13 16:14:46 +02:00
75689c665d Update source for urlib.min.js 2022-09-13 10:17:12 +02:00
d84f4f676b Document wider wallet import support 2022-09-13 10:17:12 +02:00
c97b859963 Refactor QR functionality
Based on the `ur-registry` upgrade I refactored the `CameraScanner` and `ShowQR` partials: Besides general code changes, the main change is that most of the configuration and result handling now happens on the outer view.
Those partials and functions are now generalized and don't know about their purpose (like handling PSBTs): They can be instantiated with simple data (e.g. for displaying a plain QR code) or different modes (like showing a static and the UR version of a QR code) and the result handling is done via callback.

The callbacks can now also distinguish between the different results (data as plain string vs. UR-type objects for wallet data or PSBT) and also handle the specific type of data. For instance: Before it wasn't possible to strip the leading derivation path from an xpub when scanning the QR code, because the scanner didn't know about the type of data it was handling. Now that the data is handled in the callback, we can implement that functionality for the scan view only.
2022-09-13 10:17:12 +02:00
6b8f4ee1d5 Remove bc-ur and upgrade ur-registry
Up to now we were supporting two versions of the UR standard: The legacy one implemented in `bc-ur` and the current version in `ur-registry`.
@Kukks forked a separate version of bc-ur for our web-bundle ([some more details](https://github.com/CoboVault/cobo-vault-blockchain-base/pull/8)), but it got hard to maintain the custom build, because the web-bundle needed manual assembly. We decided to get rid of the support for the legacy version and bc-ur, so that we can continue with the current version, which seems to be implemented across modern wallets (if they support UR at all). This way we can continue with only the `ur-registry` as a dependency, which handles encoding and decoding. 

I needed to make some modifications for the browser version of `ur-registry`. So I [forked their module to our org](https://github.com/btcpayserver/ur-registry) and I submitted the [modifications as PRs](https://github.com/KeystoneHQ/ur-registry/pulls) — hopefully we can eliminate our fork once those changes get merged. We are in contact with them and maintaining that fork wouldn't be as hard as the bc-ur one, because at least it has a working and automated build.
2022-09-13 10:17:12 +02:00
3532789c35 Improve Lightning Node setup examples (#4033)
* Catch connection string ToString errors

LNDhub connection string error fixed in btcpayserver/BTCPayServer.Lightning#92.

* Add Eclair bitcoin-host example

* Document LNDhub integration
2022-09-09 23:01:20 +09:00
267905b5e7 Reduce confusion 2022-09-09 13:49:24 +02:00
1626bd7a18 Show iframe when showing invoice in Shopify plugin
Close #4105
2022-09-09 13:49:24 +02:00
7106830be9 Make sure end date is after start date in Crowdfund app (#4084)
* Make sure end date is after start date in Crowdfund app

* Add null checks

* Add test case

Co-authored-by: Dennis Reimann <mail@dennisreimann.de>
2022-09-09 19:26:11 +09:00
3b1946d65c bump lightning libs 2022-09-09 16:46:39 +09:00
6dedf4d44f Upgrade Lightning library to 1.4.1 (#4093)
This enables new feature of specifying `certfilepath`

Closes #2182
2022-09-09 14:33:17 +09:00
fe5e2584b1 Use mempool as default block explorer (#4100) 2022-09-09 14:32:40 +09:00
8fae38deca Set explicit cursor style property on pay button with custom text (#4107)
We need to set "cursor: pointer;" explicitly on pay buttons with custom text because the <button> HTML tag default pointer is not a cursor. This is not an issue for the default button because it uses the <input> tag which has "cursor: pointer;" by default in browsers.

Close #4104
2022-09-09 14:28:03 +09:00
7f8e322e9c Fixed text + simplification (#4109) 2022-09-09 14:27:49 +09:00
4d0f76f9e8 Update invoice amount description in Swagger template
Close #4067
2022-09-04 09:57:41 +03:00
5d2b42960b fix CanExportInvoicesJson 2022-08-30 09:16:17 +02:00
0098dacdff fix host in launchprofile 2022-08-30 09:16:17 +02:00
51666fbf0e fix CanUseInvoiceReceipts 2022-08-30 09:16:17 +02:00
defb9120fd Ensure apps can be deleted through UI
Bug was introduced by https://github.com/btcpayserver/btcpayserver/pull/3987
2022-08-26 11:23:00 +02:00
11ec72ce8c changelog and bump
(cherry picked from commit a661f08d7b97f44913221e3641f740274f8232b5)
2022-08-26 10:26:51 +02:00
f67bd69ecc do not try to mention payout ids/ pull payments if they were not saved for labels
fixes #4078
2022-08-26 09:41:48 +02:00
db2c29a6e1 PoS UI fix: scale-down item image (#4076) 2022-08-25 12:26:44 +02:00
e22e522245 LNURL: Fix missing route hints option
Fixes #4072.
2022-08-25 12:01:26 +02:00
7c8f4c0405 Allow specifing fee block target for onchain payout processor (#4065)
Co-authored-by: d11n <mail@dennisreimann.de>
2022-08-23 12:35:20 +02:00
01ab21e4c0 Dashboard: Fix app tiles
I broke this with #3987.
2022-08-23 12:07:18 +02:00
534a2912e1 Create dynamic manifest for pos apps (#4064)
Co-authored-by: Dennis Reimann <mail@dennisreimann.de>
2022-08-21 20:38:14 +02:00
1456f4e227 Enhance export function for invoices (#4060)
Co-authored-by: Andrew Camilleri <evilkukka@gmail.com>
2022-08-21 08:43:23 +02:00
63e11451ba Rename PutPointOfSaleApp to UpdatePointOfSaleApp 2022-08-21 08:41:04 +02:00
7f80674cf2 Update Swagger docs 2022-08-21 08:41:04 +02:00
16f4ca5fbf Add support for updating POS app through Greenfield API
Part of #3458
2022-08-21 08:41:04 +02:00
701ba59bd8 Convert public app parts 2022-08-21 08:38:25 +02:00
8c6705bccb Make POS and Crowdfund plugins 2022-08-21 08:38:25 +02:00
e4542c4ac4 Paybutton: Fix logo and URL
Fixes #4053.
2022-08-20 11:32:09 +02:00
45eea1d6de API docs: Fix server base path
Introduced in #4041. Fixes #4059.
2022-08-20 11:31:28 +02:00
4aa94d5a13 bump btcpay to revert bug 2022-08-18 13:21:21 +02:00
b0253e11bf Revert "Allow bind and port for http too (#4031)"
This reverts commit a51c9d2b2dfd1b78ce99cb9c527f17a559660e43.
2022-08-18 13:12:29 +02:00
1a4a3714c7 Changelog for 1.6.8 2022-08-18 08:16:22 +02:00
999090dbdb Add Yadio exchange rate provider
Yadio is a service which provides exchange rates for many currencies such as the Lebanese Pound which have the real exchange rate which differs from the official rate significantly (32,525 LBP for USD real rate vs 1,510 official rate).

See more details here: https://yadio.io/info.html

See discussions here:
https://github.com/btcpayserver/btcpayserver/discussions/4001
https://github.com/btcpayserver/btcpayserver/discussions/2489#discussioncomment-3102370
2022-08-18 08:08:55 +02:00
13e3b515c9 Cleanse objects from obsolete altcoins 2022-08-17 21:23:16 +02:00
b6062a94b9 Explicitly disable fsize limit for some routes (#4045) 2022-08-17 10:18:30 +02:00
d0b26e9f69 Refactor Payouts (#4032)
Co-authored-by: d11n <mail@dennisreimann.de>
2022-08-17 09:45:51 +02:00
d6ae34929e Update launchSettings.json
Remove `BTCPAY_BTCEXTERNALLNDGRPC` because it is unsupported and not used anywhere in the app.

Use `http` for `BTCPAY_BTCEXTERNALLNDREST` because the HTTPS connection cannot be established.
2022-08-17 09:28:46 +02:00
a51c9d2b2d Allow bind and port for http too (#4031) 2022-08-17 09:11:13 +02:00
6c45ccc73d Add no rate found error message in Invoices (#4039) 2022-08-16 09:04:13 +02:00
6459c7bfad fix altcoin only dashboard crash
closes #4038
2022-08-15 20:22:31 +02:00
e6c1b0cf54 Merge pull request #4041 from dennisreimann/swagger-validation 2022-08-15 17:27:30 +02:00
c8558810ad Fix swagger validation errors
Combined the files with the same approach as in the docs:

`jq -rs 'reduce .[] as $item ({}; . * $item)' swagger.template.* > openapi.json`

Afterwards the bundled version can be validated using these commands:

`npx swagger-cli validate openapi.json && npx @redocly/cli lint openapi.json`
2022-08-15 15:59:26 +02:00
b0eb0b1de7 Merge pull request #4034 from dennisreimann/lnurl-controller-refactoring 2022-08-15 10:00:50 +02:00
6bdf31efda API docs: Fix duplicate speed policy schema
See the additional discussion in #3877. As we merged the Swagger JSON files for the docs, the duplicate store speed policy schema overwrote the updated invoice speed policy schema. This is now fixed by using a unified schema.
2022-08-15 06:20:10 +02:00
3cd2971cec Remove link to article that is no longer available 2022-08-14 11:19:25 +02:00
58784ebbfc Update ChromeDriver 2022-08-13 12:54:18 +02:00
de24a6e71b LNURL controller refactoring
By moving the `amount is null` check up, this prevents cases in which the `paymentMethodDetails.GeneratedBoltAmount != amount` check fails because of amount being null.
2022-08-12 20:10:44 +02:00
8c8a5a4f5e Edit view for Pull Payments (#4016)
Co-authored-by: Dennis Reimann <mail@dennisreimann.de>
2022-08-11 14:30:42 +02:00
7f41a1ef09 bump and changelog for 1.6.7 2022-08-10 10:07:15 +02:00
15e1169f62 Fix Kraken rate provider 2022-08-10 08:20:41 +02:00
de92677b69 Custodian Account Deposit UI (#4024)
Co-authored-by: d11n <mail@dennisreimann.de>
2022-08-09 20:03:55 +02:00
377ed95130 Upgrade Lightning library 2022-08-09 19:57:43 +02:00
1b1c7ad3b1 Bind app server to 0.0.0.0 to make it accessible on the local network
This way it can be accessed with other devices on the local network. It helps test with mobile devices for instance.
2022-08-08 11:15:24 +02:00
e4e0fb0f35 Ensure store button shows up correctly before store is created
fix #3972
2022-08-07 20:44:28 +02:00
bf0cbf24e4 bump and changelog for 1.6.6 2022-08-06 17:07:41 +02:00
7d454a4c7b make sure entity state gets modified in payout processors 2022-08-06 17:05:29 +02:00
680f1470cf Update app store links, add Authy as two factor app 2022-08-04 12:49:53 +09:00
1854fd307f Fix tests and warnigns 2022-08-04 12:42:15 +09:00
6239f9da75 Bump 2022-08-04 12:11:21 +09:00
40e39b82e8 Fix several potential NullReferenceException (Fix #4017) 2022-08-04 12:08:13 +09:00
c71e671311 Added custodian account trade support (#3978)
* Added custodian account trade support

* UI updates

* Improved UI spacing and field sizes + Fixed input validation

* Reset error message when opening trade modal

* Better error handing + test + surface error in trade modal in UI

* Add delete confirmation modal

* Fixed duplicate ID in site nav

* Replace jQuery.ajax with fetch for onTradeSubmit

* Added support for minimumTradeQty to trading pairs

* Fixed LocalBTCPayServerClient after previous refactoring

* Handling dust amounts + minor API change

* Replaced jQuery with Fetch API + UX improvements + more TODOs

* Moved namespace because Rider was unhappy

* Major UI improvements when swapping or changing assets, fixed bugs in min trade qty, fixed initial qty after an asset change etc

* Commented out code for easier debugging

* Fixed missing default values

Co-authored-by: Dennis Reimann <mail@dennisreimann.de>
2022-08-04 11:38:49 +09:00
2ea6eb09e6 Update changelog 2022-08-03 21:41:39 +09:00
55c39a12bc Checkout UI fix (#4015)
* Fix checkout UI bottom padding for paid state

* Improve public receipt form spacings
2022-08-03 21:31:16 +09:00
14cb65eb6a Minor refactor 2022-08-03 18:36:25 +09:00
a753459a6d Fix update webhooks (#4011)
* Fix update webhooks

* Update swagger for webhook update
2022-08-03 18:35:31 +09:00
bbce4451aa Add ability to mark auth handle as successful
Without this, there is no way to let the handle finish with a successful state. I somehow missed to add this in #3977.
2022-08-02 11:55:31 +02:00
1e378dd986 Plugins: Add authorization hook (#3977)
* Plugins: Add authorization hook

Makes the `PolicyRequirement` available to plugins.
Adds a filter hook to the authorization handlers, so that plugins can extend and leverage the existing authorization policies and permissions.

* Update to pass back and forth handle class
2022-08-02 14:20:16 +09:00
3db2b60b92 Add loopback client for local webhooks to skip ssl 2022-08-01 16:14:50 +02:00
2317a7df55 Make InvoicePaymentSettled return correct afterExpiration value
fixes #3966
2022-08-01 11:16:26 +02:00
c53fcde12a Do not crash when BTC network not available
fixes #4007
2022-08-01 10:44:39 +02:00
4be5eb39ff Make tx label endpoint not error 2022-07-28 15:33:28 +02:00
5ef31a96ea Provide error when plugin gets disabled due to crash 2022-07-28 15:31:34 +02:00
0d017c30e2 Fix: Joule -> Alby 2022-07-27 16:12:37 +09:00
92d85fa8a7 Added Alby, as Joule has been delisted on Chrome (#3934)
* Added Alby, as Joule has been delisted on Chrome

* Add files via upload
2022-07-27 16:11:42 +09:00
c2a0daedeb Bump versions of various deps (#3998) 2022-07-27 15:55:37 +09:00
51642bc4cc Update ListInvoices to say Settled instead of Paid (#4000)
Updated ListInvoices to say Settled instead of Paid

Co-authored-by: The Bitcoin Developer  <96552652+theBitcoinDeveloper@users.noreply.github.com>
2022-07-27 15:55:23 +09:00
c821208b5d Bumping LND to 0.15.0-beta (#3999) 2022-07-26 20:09:56 +09:00
a3d536bd51 Changelog and bump 2022-07-23 20:39:15 +09:00
f7262d12e6 Update lang 2022-07-23 20:37:56 +09:00
bec888da19 Payjoin label fixes (#3986)
* Payjoin label fixes

* When a payjoin label was applied, coin selection filter would not work
* When a payjoin happened with a receive address wallet, the payjoin label was not applied
* Coin selection shows when a utxo is currently reserved for a payjoin. Applies both to UI and to GF API

* remove reserved label

* Update BTCPayServer/Payments/PayJoin/PayJoinEndpointController.cs
2022-07-23 20:26:13 +09:00
2e6246e385 Move TagHelpers to Abstractions (#3975)
* Move TagHelpers to Abstractions

Makes them available for use in plugins. Also cleans up the tag helper references in the view code: As we have it in the root view imports, the individual directives in the views are superfluous.

* Move CurrenciesSuggestionsTagHelper back

To get rid of the Rating dependency in Abstractions.
2022-07-22 21:58:25 +09:00
a9a0bf01ad Design updates (#3981)
Contains the following design system PRs:
- btcpayserver/btcpayserver-design#50
- btcpayserver/btcpayserver-design#51
- btcpayserver/btcpayserver-design#52
2022-07-22 21:53:13 +09:00
8dd3c76fa4 Make it work with decimal discount values 2022-07-22 13:31:41 +02:00
a7c22399d8 Minor JS improvements 2022-07-22 13:31:41 +02:00
04cb8a2fe0 Minor toggle improvement 2022-07-22 13:31:41 +02:00
494739f771 Add discount option for Keypad POS app type
See https://chat.btcpayserver.org/btcpayserver/pl/ju5bu6r8qjfe9mrxdri3kihpby for details
2022-07-22 13:31:41 +02:00
6fbcc9a244 Fix Crowdfund + additional issues (#3994)
* Show free when invoice is fixed and 0 amount in apps
* animations on crowdfund not enabled broke JS
* Perk expansion in crowdfund was broken
2022-07-22 20:30:39 +09:00
d016f59867 Coin Selection: Fix responsive display (#3992)
Fixes #3985.
2022-07-22 20:29:53 +09:00
88f8f3938c Make app invoices show link to app in receipt (#3995) 2022-07-22 20:29:34 +09:00
1322fd97f6 Revert "Redirect instead of show 404 on 0 amount invoices"
This reverts commit 7f617df4e851b296bb5181a1f99df066fa704727.
2022-07-22 06:21:41 +02:00
7f617df4e8 Redirect instead of show 404 on 0 amount invoices
fixes #3904
2022-07-21 14:33:39 +02:00
b02542f3be Do not crash on bad language file 2022-07-21 11:09:51 +02:00
5fd620556e Fix Local client
This cleans up the client factory for plugins so that it is less hectic looking. Additionally, it fixes a bug where if you reuse the factory after setting a store, the state might stick.
2022-07-20 18:20:14 +02:00
218d64d8df Update Changlog, and bump 2022-07-15 12:47:15 +09:00
e8291eb00e Move ConfirmModel to Abstractions (#3964)
To make it available to plugins.
2022-07-15 12:38:33 +09:00
f8619e382b Fix LN Address payouts (#3960)
* Fix LN Address payouts

LN Address was validated when creating the claim but the paying sdection did not support it.

* reuse code

* reuse code

* do not use mail directly

* fix email validator
2022-07-15 12:37:47 +09:00
83c35328ed Fix: No pager in the wallet transactions list 2022-07-15 12:35:57 +09:00
f548d78907 Merge pull request #3965 from dennisreimann/new-supporters
Supporters: Add Strike and HRF
2022-07-12 15:31:30 +02:00
5aca8b41af Supporters: Add Strike and HRF 2022-07-12 15:14:02 +02:00
a7b6f3fa19 Redirect to dashboard instead of apps list on app delete (#3941)
close #3898
2022-07-12 15:18:08 +09:00
afb989d72e Fix lnurl withdraw modal (#3955)
* Fix lnurl withdraw modal

fixes #3949

* Fix test
2022-07-12 15:17:44 +09:00
12c96c7a74 Fix webhook display bug (#3959)
Specific events list now displays correctly when modifying specific events webhook
2022-07-12 12:37:02 +09:00
79bfffd77b Invoice summary: Fix indentation and heading levels (#3956) 2022-07-12 12:35:19 +09:00
58d68e7e31 Update changelog 2022-07-11 23:42:15 +09:00
499352e51c Fix the ExchangeSharpRateProvider for some pairs 2022-07-11 23:39:11 +09:00
03fbd51fab bump 2022-07-11 23:13:35 +09:00
bd73cac1a1 Fix: For some asset pair the kraken rate was inverted (Fix #3957) 2022-07-11 23:09:35 +09:00
0c43fda86d Prevent stackoverflow exception when ripio is unavailable 2022-07-11 23:08:59 +09:00
a64b8fb310 Update test plugin with more data related functionality 2022-07-11 11:29:57 +02:00
316d39f24c Update Changelog 2022-07-09 11:29:33 +09:00
265e2930f1 bump 2022-07-08 16:54:35 +09:00
9511cf8d8a Update changelog (#3913) 2022-07-08 16:53:41 +09:00
b86f0a7d9c Make BTCPay ssh key using safe algo 2022-07-08 16:32:43 +09:00
19be847624 Do not use Renci.SSH in tests 2022-07-08 16:30:52 +09:00
15e45ac4ec Bump SSH.NET 2022-07-08 16:08:21 +09:00
86572635df Fix build 2022-07-08 16:05:40 +09:00
4a5c51d7a3 Update sln 2022-07-08 12:43:11 +09:00
8530cf3535 Make sure we do not expose lightning services if not admin 2022-07-08 12:42:36 +09:00
eec54831ef Update lightning lib, on-chain balance shouldn't be lightmoney (#3945) 2022-07-08 10:55:26 +09:00
a41e98910d Update langs 2022-07-08 10:41:43 +09:00
be985466a3 Add payouts docs link (#3942) 2022-07-08 10:27:04 +09:00
98fb46957a Add error message when invoice could not be created (#3943)
If user requested to create an invoice for a payment method which is not set up for their store we currently return a generic error. This PR updates the logic so that we return a more specific error in this case.

closes #3830
2022-07-08 10:23:26 +09:00
2abc35058b Custodian Account UI: CRUD (#3923)
* WIP New APIs for dealing with custodians/exchanges

* Simplified things

* More API refinements + index.html file for quick viewing

* Finishing touches on spec

* Switched cryptoCode to paymentMethod as this allows us to differentiate between onchain and lightning

* Moved draft API docs to "/docs-draft"

* WIP baby steps

* Added DB migration for CustodianAccountData

* Rough but working POST /v1/api/custodian-account + GET /v1/api/custodian

* WIP + early Kraken API client

* Moved service registration to proper location

* Working create + list custodian accounts + permissions + WIP Kraken client

* Kraken API Balances call is working

* Added asset balances to response

* List Custodian Accounts call does not load assetBalances by default, because it can fail. Can be requested when needed.

* Call to get the details of 1 specific custodian account

* Added permissions to swagger

* Added "tradableAssetPairs" to Kraken custodian response + cache the tradable pairs in memory for 24 hours

* Removed unused file

* WIP + Moved files to better locations

* Updated docs

* Working API endpoint to get info on a trade (same response as creating a new trade)

* Working API endpoints for Deposit + Trade + untested Withdraw

* Delete custodian account

* Trading works, better error handling, cleanup

* Working withdrawals + New endpoint for getting bid/ask prices

* Completed withdrawals + new endpoint for getting info on a past withdrawal to simplify testing, Enums are output as strings,

* Better error handling when withdrawing to a wrong destination

* WithdrawalAddressName in config is now a string per currency (dictionary)

* Added TODOs

* Only show the custodian account "config" to users who are allowed

* Added the new permissions to the API Keys UI

* Renamed KrakenClient to KrakenExchange

* WIP Kraken Config Form

* Removed files for UI again, will make separate PR later

* Fixed docs + Refactored to use PaymentMethod more + Added "name" to custodian account + Using cancelationToken everywhere

* Updated withdrawal info docs

* First unit test

* Complete tests for /api/v1/custodians and /api/v1/custodian-accounts endpoints + Various improvements and fixes

* Mock custodian and more exceptions

* Many more tests + cleanup, moved files to better locations

* More tests

* WIP more tests

* Greenfield API tests complete

* Added missing "Name" column

* Cleanup, TODOs and beginning of Kraken Tests

* Added Kraken tests using public endpoints + handling of "SATS" currency

* Added 1st mocked Kraken API call: GetAssetBalancesAsync

* Added assert for bad config

* Mocked more Kraken API responses + added CreationDate to withdrawal response

* pr review club changes

* Make Kraken Custodian a plugin

* Re-added User-Agent header as it is required

* Fixed bug in market trade on Kraken using a percentage as qty

* A short delay so Kraken has the time to execute the market order and we don't fetch the details too quickly.

* Merged the draft swagger into the main swagger since it didn't work anymore

* Fixed API permissions test

* Removed 2 TODOs

* Fixed unit test

* After a utxo rescan, the cached balance should be invalidated

* Fixed Kraken plugin build issues

* Added Kraken plugin to build

* WIP UI + config form

* Create custodian account almost working - only need to add in the config form

* Working form, but lacks refinement

* Viewing balances + Editing custodian account works, but cannot change the withdrawal destination config because that is an object using a name with [] in it

* cleanup

* Minor cleanup, comments

* Working: Delete custodian account

* Moved the MockCustodian used in tests to a new plugin + linked it to the tests

* WIP viewing custodian account balances

* Split the Mock custodian into a Mock + Fake, various UI improvements and minor fixes

* Minor UI fixes

* Removed broken link

* Removed links to anchors as they cannot pass the tests since they use JavaScript

* Removed non-existing link. Even though it was commented out, the test still broke?

* Added TODOs

* Now throwing BadConfigException if API key is invalid

* UI improvements

* Commented out unfinished API endpoints. Can be finished later.

* Show fiat value for fiat assets

* Removed Kraken plugin so I can make a PR


Removed more Kraken files

* Add experimental route on UICustodianAccountsControllre

* Removed unneeded code

* Cleanup code

* Processed Nicolas' feedback

Co-authored-by: Kukks <evilkukka@gmail.com>
Co-authored-by: nicolas.dorier <nicolas.dorier@gmail.com>
2022-07-07 22:42:50 +09:00
35f97a6013 Add link to the order id if there is a orderUrl 2022-07-07 21:55:00 +09:00
b8d509eb12 Show order id in invoice details even if orderUrl is not present 2022-07-07 21:54:45 +09:00
d6f13be95f Redirect to invoice details instead of list upon creation (#3936)
* Redirect to invoice details instead of list upon creation

close #3909

* fix tests
2022-07-07 21:47:59 +09:00
4dad27bb76 Add v1.6.0 to the What's New modal (#3932) 2022-07-07 12:41:13 +09:00
efe1686c05 Don't show "Set up a Lightning node" when LN is not supported (#3935)
See discussion here: https://github.com/btcpayserver/btcpayserver/discussions/3868
2022-07-07 10:38:51 +09:00
09462e6877 Enhance Store email capability (#3911)
* Enhance Store email capability

Currenty the new email rules can send an email when an invoice event occurs. However, there is currently no way to customize the email based on the invoice, making the feature a bit useless.

This PR:
* adds the rich text editor to the body input
* allows you to use some of the properties from the Invoice (based on greenfield api properties. I've taken a imple approach for now using just  a string.replace mechanism, but we can update this to a dynamic linq approach so that users can customize further (e.g. `{Invoice.Metadata["something"].ToString().ToUpper()}`)

NOT READY:
Since this all takes place as a background service, there is an issue around how to handle items such as the "checkout link", as we are not aware of the btcpay url at that moment. Thoughts? @nicolasdorier

* fix typo and make it simpler for now

* remove dditor
2022-07-06 22:17:33 +09:00
612a0397a7 Make LNURL enabled when only method (#3930)
* Make LNURL enabled when only method

This fixes the scenario where LNURL for standard invoices are disabled, but the POS Print view only shows LNURL, so the QR code would always error out. The fix is to bypass the setting when lnurl is the only enabled payment method on the invoice

* Make sure not to affect other flows

* fix
2022-07-06 22:09:05 +09:00
3576ebd14f Public Invoice receipt (#3612)
* Public Invoice receipt

* implement payment,s qr, better ui, and fix invoice bug

* General view updates

* Update admin details link

* Update view

* add missing check

* Refactor

* make payments and qr  shown by default
* move cusotmization options to own ReceiptOptions
* Make sure to sanitize values inside PosData partial

* Refactor

* Make sure that ReceiptOptions for the StoreData is never null, and that values are always set in API

* add receipt link to checkout and add tests

* add receipt  link to lnurl

* Use ReceiptOptions.Merge

* fix lnurl

* fix chrome

* remove i18n parameterization

* Fix swagger

* Update translations

* Fix warning

Co-authored-by: Dennis Reimann <mail@dennisreimann.de>
Co-authored-by: nicolas.dorier <nicolas.dorier@gmail.com>
2022-07-06 21:14:55 +09:00
2a190d579c Show lightning balances even of 0 2022-07-06 15:40:00 +09:00
67abc107c5 Do not prefilter if label filter in transaction view 2022-07-06 13:00:41 +09:00
9ec2052428 ui+stores: updates switches ui to be consistent with other switches (#3929) 2022-07-06 12:43:22 +09:00
657423207b Async dashboard (#3916)
* Dashboard: Load Lightning balance async, display default currency

* Simplify approach, improve views and scripts

* Async tiles


Async tiles

* Add period for app sales

* Fix missing keypad view sales

* Fix after rebase

* Fix awaited call

* Fix build

Co-authored-by: Nicolas Dorier <nicolas.dorier@gmail.com>
2022-07-06 12:40:16 +09:00
19aaff2345 Merge pull request #3928 from dennisreimann/build-warnings
Fix build warnings
2022-07-06 12:16:15 +09:00
8873c51f2b Merge pull request #3926 from NicolasDorier/improveperfbigwallet
Improve performance of on chain transaction listing for big wallets
2022-07-05 14:54:27 +09:00
2ba24ba56b Tests should use explorer.postgres 2022-07-05 14:39:50 +09:00
52f5d21480 Improve performance of on chain transaction listing for big wallets 2022-07-05 14:23:13 +09:00
0405cda9d6 Fix build warnings 2022-07-04 19:05:25 +02:00
b422e79896 Add test cases for wallet send wizard links (#3927) 2022-07-04 21:59:46 +09:00
181d4d5ea4 Improve wallet nav (#3921)
* Fix rescan nav highlighting

* Wallet send wizard

* Wallet receive wizard

* Consistent wizard back button behaviour
2022-07-04 13:20:08 +09:00
f30ddbf175 Fix spurious crash at shutdown 2022-07-04 13:17:36 +09:00
2c3b8d8925 Dashboard: Load Lightning balance async, display default currency (#3907)
* Dashboard: Load Lightning balance async, display default currency

* Simplify approach, improve views and scripts

* Remove LightMoney converters
2022-07-04 11:03:16 +09:00
2e2c6aef83 Fix warning 2022-07-02 20:39:34 +09:00
e511538ba6 Fix: Local client factory when no user is specified would fail on some edge case auth scenarios 2022-07-01 09:03:32 +02:00
c12e08ef01 Open public app views in new tab/window (#3920) 2022-07-01 13:31:11 +09:00
0970944ee4 Add refund badge to invoice lists (#3918)
* Add refund badge to invoice lists

* fix badge
2022-07-01 13:26:00 +09:00
4eabe91cee remove lnurl from crowdfund as per requests 2022-06-30 14:25:52 +02:00
cf747f1e07 Fix missing refund flow error message
Fixes #3919.
2022-06-30 14:25:15 +02:00
e5a1da7136 Fix: Refund flow failed when lnurl was the only payment method 2022-06-30 08:52:56 +02:00
27b6cf436b fix cheat mode when default payment is not onchain 2022-06-30 08:46:34 +02:00
e4866a8265 Can disable cert check for email server (#3908) 2022-06-29 23:38:44 +09:00
d90cc02e5a CI: Try docker-compose pull several times 2022-06-29 23:37:38 +09:00
23a1a8e3f5 Add title on link of ln services in the dashboard 2022-06-29 23:31:25 +09:00
b8f1c0df09 Create interface for providing store id to plugins (#3910) 2022-06-29 23:18:02 +09:00
ed1f249aaf Fix empty permissions case 2022-06-29 15:36:54 +02:00
eef7539c2d Fix selective stores case 2022-06-29 15:36:54 +02:00
1bb35bf545 Limit selection to one store 2022-06-29 15:36:54 +02:00
2b9cb4a257 Better handling of confirm case (existing API key) 2022-06-29 15:36:54 +02:00
209cff8888 View improvements 2022-06-29 15:36:54 +02:00
9e253ac7a3 Test improvements 2022-06-29 15:36:54 +02:00
27c5b16957 Improve views; fix tests 2022-06-29 15:36:54 +02:00
2f1df3be7d Autofocus confirm modal input 2022-06-29 15:36:54 +02:00
bb4a28ecd8 Refactor Authorize UI
Closes #2902.
2022-06-29 15:36:54 +02:00
54c20b26cc Fix NRE 2022-06-29 15:33:48 +02:00
4a71b952b6 Revert "Fix: If SMTP port is 25, SSL shouldn't be used"
This reverts commit 9423bc4ea71747809b029dadfdf3545d5a6d0b68.
2022-06-29 15:12:30 +09:00
3d7f628014 Support Lnurl Withdraw in pull payments (#3709)
* Support Lnurl Withdraw

* cleanup and small fixes

* remove putin brace
2022-06-28 23:02:17 +09:00
c63529ea99 Fix: Warnings and view build issues during dotnet publish (#3902) 2022-06-28 17:38:59 +09:00
d43bdcc1a2 UI: Fix cancel plugin command (#3903)
* UI: Fix cancel plugin command

As installing a plugin also adds the delete/uninstall command, we just select the last action, which is the one the user triggered. 

Fixes #3890.

* Apply suggestions from code review

https://stackoverflow.com/questions/50100688/check-if-value-tuple-is-default
2022-06-28 17:38:47 +09:00
a4aa6c5ab9 Fix email rule remove action (#3901)
It simply exited to early by returning the view. The updated rules didn't get saved afterwards.
2022-06-28 14:10:45 +09:00
6d3e1bb40a Dashboard: Add Point Of Sale data (#3897)
* Dashboard: Add Point Of Sale data

Closes #3675.

* LNURL: Add POS redirect URL

* POS: Fix invoices link

* Fix integration tests

* Simplify data aggregation

* Improve chart display
2022-06-28 14:05:02 +09:00
9428347cb6 Crowdfund finetuning (#3488)
* Update crowdfund defaults

* Crowdfund: Move sound, animation and discussion into additional options

* Update sound URLs

Fixes #3745.

* Update featured image URL label

* Improve the recurring goal section

* Crowdfund: Goal section finetuning
2022-06-28 12:03:13 +09:00
618666abf1 bump mailkit 2022-06-27 10:58:57 +09:00
9423bc4ea7 Fix: If SMTP port is 25, SSL shouldn't be used 2022-06-27 10:54:02 +09:00
95b9e4dfd9 Add basic Greenfield API Get and Delete operations for apps (#3894)
* Add basic Greenfield API Get and Delete operations for apps

Will follow-up with PATCH and also with GET which returns more than just basic data later. This sets up the basic stuff first.

* Add methods to LocalBTCPayServerClient
2022-06-27 10:14:16 +09:00
61c6a2ab57 Greenfield: Add balance endpoint (#3887)
* Greenfield: Add balance endpoint

* Remove superfluous try/catch
2022-06-23 13:42:28 +09:00
c89f7aaaed Improve email settings validation and UX (#3891) 2022-06-23 13:41:52 +09:00
c2d72e71aa Store Emails (#3611)
* Store Emails

* fix test

* Update email rules layout

* Cleanups

* Test cleanups

* Add back comments

* Update view; add test

* Show email rules link even if email settings aren't completed

* Validate email addresses

* No redirect, display warning

* Fix test

* Refactoring: Change email argument types to MailAddress

* Test fix

* Refactoring: Use MailboxAddress

* Parse emails properly in controllers and backend

Co-authored-by: Dennis Reimann <mail@dennisreimann.de>
Co-authored-by: nicolas.dorier <nicolas.dorier@gmail.com>
2022-06-22 12:05:32 +09:00
af93cf2adb Lightning balance: Handle null values (#3886)
* Lightning balance: Handle null values

* Upgrade Lightning lib
2022-06-21 16:09:18 +09:00
7a75a8c254 Fix nav height issue on mobile devices (#3888)
close #3807
2022-06-21 13:04:50 +09:00
0aa7dacbca Add spam rate limits for public invoice endpoints (Fix #3782) (#3889) 2022-06-21 12:33:20 +09:00
9d41a52d3b Remove Store ID from Store Settings & various minor UI tweaks (#3881)
* ui+layout: update main container padding

* ui+invoice: updates archive button

* ui+users: updates search input
2022-06-20 16:02:12 +09:00
c943303a45 Dashboard balance fixes (#3876)
* Fix wallet balance for case crypto code == default currency

* Handle old NBXplorer backend case

* Cleanup
2022-06-20 14:31:22 +09:00
b2a5b3c3c4 Fix tests 2022-06-20 13:36:01 +09:00
495d4b82cf Fix warning from CLI parser (#3875) 2022-06-20 13:07:58 +09:00
ea2a200302 Adding description to speedPolicy parameter. (#3877) 2022-06-20 13:07:24 +09:00
c531b26821 Updates Crowdfund & POS Modal (#3806)
* ui+cf: updates perks modal

* Toggle editor with Bootstrap

* Add currency info to app items

Co-authored-by: Dennis Reimann <mail@dennisreimann.de>
2022-06-20 11:55:47 +09:00
cade6c6c38 Move View action to the Name column in Payouts & Payment Requests (#3873)
* ui+paymentrequest: moves 'view' link to name

* ui+pull: moves 'view' link to name column

* Update links, fix tests

Co-authored-by: Dennis Reimann <mail@dennisreimann.de>
2022-06-20 11:52:12 +09:00
c56821300a Server Settings: Consolidate Storage and Files (#3863)
* Server Settings: Consolidate Storage and Files

* Improve storage options name display

* Remove file services from services page

* Remove more code
2022-06-15 21:06:16 +09:00
346821f0d6 Added toggle button to switch to store default currency (#3752)
* Added toggle button to switch to store default currency

* Replaced ["usd"] with the currency variable

* Fix indentation and improve JS part

* Update script and display

* Improve chart display

* Improve rate display

* Address code review comments

Co-authored-by: Dennis Reimann <mail@dennisreimann.de>
2022-06-15 16:33:24 +09:00
0da97c5da3 Report shopify errors to the UI (Fix #3853) 2022-06-15 14:12:47 +09:00
f0e013e1f8 Make Pay Button a plugin (#3862)
* Move files

* Fix potentially missing default payment method

Before, it got removed if any other value was changed besides the default payment method.

* Fix missing store data

* Update BTCPayServer/Plugins/PayButton/PayButtonPlugin.cs

Co-authored-by: Pavlenex <pavle@pavle.org>

* Update pay button warning

Closes #3535.

Co-authored-by: Pavlenex <pavle@pavle.org>
2022-06-15 11:32:46 +09:00
8a144f3c35 removes plugin (#3805) 2022-06-15 11:19:02 +09:00
f48bb5a40a Fix build warnings (#3870)
Fixes #3866.
2022-06-15 11:17:10 +09:00
3abde67671 Merge pull request #3865 from dennisreimann/fullynoded
Update Fully Noded link
2022-06-14 19:22:32 +02:00
59b2e2dba1 Update Fully Noded link 2022-06-14 10:01:10 +02:00
479f21f4f3 Dashboard: Add Lightning balances and services (#3838)
* Update Lightning lib

* Refactoring: Move Lightning methods and props to ExternalServices

* Rename Lightning services

* Add Lightning balance to dashboard

* Split Lightning dashboard tiles

* View updates
2022-06-14 14:36:22 +09:00
4a0f10ea99 Support LN connection string with onion http client (#3845)
I'm not sure if onion based ln conenction strings ever worked in btcpay? closes #1648
2022-06-13 16:22:26 +09:00
9a24e4ade1 Store Settings feature with own table (#3851)
* Store Settings feature with own table

* fix test

* Include the store settings to StoreRepository, remove caching stuff

Co-authored-by: nicolas.dorier <nicolas.dorier@gmail.com>
2022-06-13 13:36:47 +09:00
4691e896a1 Fix invoice index migration 2022-06-13 12:37:38 +09:00
869411a977 ui+dashboard: small margin tweaks (#3856) 2022-06-13 10:48:36 +09:00
68bd40d2a4 Improves Invoice Summary accordion view (#3859)
* ui+site: moves invoice css

* ui+invoice: improves invoice summary and partials
2022-06-13 10:47:26 +09:00
cb8fe24a77 Add new issue forms for filing Bug Reports (#3846)
* remove old .md template, add new issue form

* Update .github/ISSUE_TEMPLATE/bug_report.yml

Co-authored-by: Andrew Camilleri <evilkukka@gmail.com>

* Update .github/ISSUE_TEMPLATE/bug_report.yml

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

* change browser from drop down to textfield

* fix github yaml validation

* enable blank templates

* emoji consistency

Co-authored-by: Andrew Camilleri <evilkukka@gmail.com>
Co-authored-by: d11n <mail@dennisreimann.de>
2022-06-10 13:35:31 +02:00
eb65949b69 Mobile header improvements
- Moves the menu button to the left, besides the logo
- Improves width and text display of the store selector
 
Closes  #3826.
2022-06-10 09:11:26 +02:00
fdf6f68624 Remove unused "using" directive 2022-06-10 08:39:01 +02:00
d0e01768ab Allow excluding unconfirmed UTXOs when creating a new transaction with Greenfield API
See original request: https://github.com/btcpayserver/btcpayserver/discussions/3737
2022-06-10 08:39:01 +02:00
fd3d389557 Notifications: Fix mark all as seen return URL
Fixes the return URL for the case in which the dropdown content got replaced after a notification update: As the refresh request is done via AJAX, the return URL previously was `/notifications/getnotificationdropdownui` (the `Context.Request.GetCurrentPathWithQueryString()` value of the AJAX action).

We need to pass in the URL of the actual current page as the return URL.
2022-06-10 08:17:06 +02:00
3d63e12c9e fix test 2022-06-09 12:43:28 +02:00
ac6770bdff Add Buda rate provider for CLP
closes #3766
2022-06-09 12:01:40 +02:00
2ad2ce6c3b Fixed issue with users when disabling then setting admin
Concurrency issue; moved user update from controller to service
2022-06-07 13:04:21 +02:00
fcbe1dd8eb Fix: Local Client Factory was not properly handling the override for auth (#3799)
* Fix: Local Client Factory was not properly handling the override for auth

* implement nonimplemented method
2022-06-06 22:57:55 +09:00
df618d1aa2 Simple Notification Modal Improvement (#3784)
* ui+layout: updates notification modal overlay

* Update BTCPayServer/wwwroot/main/layout.css

Co-authored-by: d11n <mail@dennisreimann.de>
2022-06-06 18:58:57 +09:00
b846f16e6c ui+pos: update notification copy (#3801) 2022-06-06 18:58:32 +09:00
51ab9746de UI: Minor 2FA improvements (#3812)
Styles the "Remember me" checkbox on login and sets a proper width for the verification code field.
2022-06-06 18:57:42 +09:00
ae10d0c7fd Bump and fix rate providers (#3813)
* Bump and fix rate providers

* fix
2022-06-06 18:56:50 +09:00
a443426d83 Fix remove and enable issues with non-last-admin
"Remove" issue likely due to multiple context instances. "Enable" issue due to conditional check.

Discovered bug with users when first disabling, then marking as admin, which remains an issue.
2022-06-06 10:43:06 +02:00
f2aa4d4484 fix swagger test 2022-06-06 10:40:57 +02:00
4579dc9385 Update UIManageController.APIKeys.cs
Fixed grammar.
2022-06-06 10:36:17 +02:00
8ef8c97072 Refactoring: Bitpay Rate Controller
Some tweaks I did when working on #3752.
2022-06-06 10:34:52 +02:00
84fcd1c1b5 Add custom bg and border classes 2022-06-06 10:32:15 +02:00
d0e6bcd784 ui+payout: removes border 2022-06-06 10:32:15 +02:00
1142ff884e Update payment data partials 2022-06-06 09:41:23 +02:00
29080e9d7d Add Refunds list to Invoice details page
(this is missing the refunded badge and progress as I have another PR that makes this easier to compute to show)
2022-06-06 09:41:23 +02:00
04c3191795 Layout cleanups
Just some minor cleanups
2022-06-06 09:33:19 +02:00
9d75225bd5 Redirect create and edit payment request to list view upon completion
Create and edit now redirect to list view. Both actions use the same method. Also updated notification message.

Kept extraneous redirect value for xUnit tests. Update selenium test to account for redirect to list view.
2022-06-06 07:53:41 +02:00
ce85bd26df Fix change domain documentation link 2022-06-03 10:49:28 +02:00
ba0e46b465 Improve payouts UI (#3792)
* Improve payouts UI

* Display units

* Update badges

* Update badge background
2022-06-02 11:03:06 +02:00
5616b7550f Improve Refund Flow (#3731) 2022-06-02 10:08:55 +02:00
fcd6159b42 Merge pull request #3511 from bolatovumar/feat/api/apps
Add support for creating POS apps through Greenfield API
2022-06-02 14:13:25 +09:00
02e5e1bc1e Fix CheckNoDeadLink which can enter in infinite loop 2022-06-02 13:26:14 +09:00
6d83a00728 Rename tags of PoS API in swagger 2022-06-02 13:07:02 +09:00
d697c2ac9e Add fallback values for buttons 2022-05-31 22:27:03 -07:00
c917aec401 Add PosViewType enum 2022-05-31 22:25:04 -07:00
89c1b94a12 Dashboard: Do not display archived invoices in recent invoices
Fixes #3783.
2022-05-31 13:20:16 +02:00
46b9760179 Greenfield: Fix GetDepositAddress return type (#3790)
The local clients GetFromActionResult cannot handle the JValue return type, because it gets invoked with GetFromActionResult<string>.
2022-05-31 19:15:38 +09:00
ff66e66f21 PluginPacker: Shell fallback for macOS/Linux 2022-05-30 11:47:06 +02:00
b1f62f74cd Update language to explicitly request view-only wallet files
Right now the tooltips displayed do not specify using a view-only wallet, but there is no reason to upload full keys to BTCPay Server and view-only keys are actually the BTCPay Server recommendation.

Updated language in the UI to reflect that and made some minor improvements to the other language used in the UI here.
2022-05-29 12:12:55 +09:00
a0d0f1f98b Error when broadcasting transactions weren't shown in the UI 2022-05-28 21:36:42 +09:00
fca066fe52 Add endpoint for creating POS app 2022-05-17 21:26:33 -07:00
aa3c0346c8 Add GreenfieldAppsController 2022-05-17 21:26:33 -07:00
bafec0d974 Move PointOfSaleSettings class into own file 2022-05-17 21:26:33 -07:00
718 changed files with 24773 additions and 20961 deletions

View File

@ -41,9 +41,10 @@ jobs:
- run:
command: |
LATEST_TAG=${CIRCLE_TAG:1} #trim v from tag
GIT_COMMIT=$(git rev-parse HEAD)
#
sudo docker build --pull -t $DOCKERHUB_REPO:$LATEST_TAG-amd64 -f amd64.Dockerfile .
sudo docker build --pull --build-arg CONFIGURATION_NAME=Altcoins-Release -t $DOCKERHUB_REPO:$LATEST_TAG-altcoins-amd64 -f amd64.Dockerfile .
sudo docker build --build-arg GIT_COMMIT=${GIT_COMMIT} --pull -t $DOCKERHUB_REPO:$LATEST_TAG-amd64 -f amd64.Dockerfile .
sudo docker build --build-arg GIT_COMMIT=${GIT_COMMIT} --pull --build-arg CONFIGURATION_NAME=Altcoins-Release -t $DOCKERHUB_REPO:$LATEST_TAG-altcoins-amd64 -f amd64.Dockerfile .
sudo docker login --username=$DOCKERHUB_USER --password=$DOCKERHUB_PASS
sudo docker push $DOCKERHUB_REPO:$LATEST_TAG-amd64
sudo docker push $DOCKERHUB_REPO:$LATEST_TAG-altcoins-amd64
@ -57,9 +58,10 @@ jobs:
command: |
sudo docker run --rm --privileged multiarch/qemu-user-static:register --reset
LATEST_TAG=${CIRCLE_TAG:1} #trim v from tag
GIT_COMMIT=$(git rev-parse HEAD)
#
sudo docker build --pull -t $DOCKERHUB_REPO:$LATEST_TAG-arm32v7 -f arm32v7.Dockerfile .
sudo docker build --pull --build-arg CONFIGURATION_NAME=Altcoins-Release -t $DOCKERHUB_REPO:$LATEST_TAG-altcoins-arm32v7 -f arm32v7.Dockerfile .
sudo docker build --build-arg GIT_COMMIT=${GIT_COMMIT} --pull -t $DOCKERHUB_REPO:$LATEST_TAG-arm32v7 -f arm32v7.Dockerfile .
sudo docker build --build-arg GIT_COMMIT=${GIT_COMMIT} --pull --build-arg CONFIGURATION_NAME=Altcoins-Release -t $DOCKERHUB_REPO:$LATEST_TAG-altcoins-arm32v7 -f arm32v7.Dockerfile .
sudo docker login --username=$DOCKERHUB_USER --password=$DOCKERHUB_PASS
sudo docker push $DOCKERHUB_REPO:$LATEST_TAG-arm32v7
sudo docker push $DOCKERHUB_REPO:$LATEST_TAG-altcoins-arm32v7
@ -73,9 +75,10 @@ jobs:
command: |
sudo docker run --rm --privileged multiarch/qemu-user-static:register --reset
LATEST_TAG=${CIRCLE_TAG:1} #trim v from tag
GIT_COMMIT=$(git rev-parse HEAD)
#
sudo docker build --pull -t $DOCKERHUB_REPO:$LATEST_TAG-arm64v8 -f arm64v8.Dockerfile .
sudo docker build --build-arg CONFIGURATION_NAME=Altcoins-Release --pull -t $DOCKERHUB_REPO:$LATEST_TAG-altcoins-arm64v8 -f arm64v8.Dockerfile .
sudo docker build --build-arg GIT_COMMIT=${GIT_COMMIT} --pull -t $DOCKERHUB_REPO:$LATEST_TAG-arm64v8 -f arm64v8.Dockerfile .
sudo docker build --build-arg GIT_COMMIT=${GIT_COMMIT} --build-arg CONFIGURATION_NAME=Altcoins-Release --pull -t $DOCKERHUB_REPO:$LATEST_TAG-altcoins-arm64v8 -f arm64v8.Dockerfile .
sudo docker login --username=$DOCKERHUB_USER --password=$DOCKERHUB_PASS
sudo docker push $DOCKERHUB_REPO:$LATEST_TAG-arm64v8
sudo docker push $DOCKERHUB_REPO:$LATEST_TAG-altcoins-arm64v8

View File

@ -4,6 +4,15 @@ set -e
cd ../BTCPayServer.Tests
docker-compose -v
docker-compose -f "docker-compose.altcoins.yml" down --v
docker-compose -f "docker-compose.altcoins.yml" pull
# For some reason, docker-compose pull fails time to time, so we try several times
n=0
until [ "$n" -ge 10 ]
do
docker-compose -f "docker-compose.altcoins.yml" pull && break
n=$((n+1))
sleep 5
done
docker-compose -f "docker-compose.altcoins.yml" build
docker-compose -f "docker-compose.altcoins.yml" run -e "TEST_FILTERS=$1" tests

View File

@ -12,7 +12,7 @@ indent_style = space
indent_size = 4
charset = utf-8
[launchSettings.json]
[*.json]
indent_size = 2
# C# files

View File

@ -1,63 +0,0 @@
---
name: "\U0001F41B Bug report"
about: Report a bug or a technical issue
---
<!--
Thank you for reporting a technical issue.
This issue tracker is only for bug reports and problems.
For general questions please read our documentation docs.btcpayserver.org. You can ask technical questions in discussions https://github.com/btcpayserver/btcpayserver/discussions and general support on our community chat chat.btcpayserver.org
Please fill in as much of the template below as you're able.
-->
**Describe the bug**
A clear and concise description of what the bug is.
**To Reproduce the bug**
Steps to reproduce the reported bug:
1. Go to '...'
2. Click on '....'
3. Scroll down to '....'
4. See error
**Expected behavior**
<!--
A clear and concise description of what you expected to happen.
-->
**Screenshots**
<!--
If applicable, add screenshots to help explain your problem.
-->
**Your BTCPay Environment (please complete the following information):**
- BTCPay Server Version: <!--[available in the right bottom corner of footer] -->
- Deployment Method: <!--[e.g. Docker, Manual, Third-Party-host]-->
- Browser: <!--[e.g. Chrome, Safari]-->
**Logs (if applicable)**
<!--
Basic logs can be found in Server Settings > Logs.
More logs https://docs.btcpayserver.org/Troubleshooting/#2-looking-through-the-logs
-->
**Setup Parameters**
<!--
If you're reporting a deployment issue run `. btcpay-setup.sh -i` and paste the setup parameters here with your private information removed or obscured.
-->
**Additional context**
<!--
Add any other context about the problem here.
-->

68
.github/ISSUE_TEMPLATE/bug_report.yml vendored Normal file
View File

@ -0,0 +1,68 @@
name: 🐛 Bug Report
description: File a bug report
title: "[Bug]: "
labels: ["bug"]
body:
- type: markdown
attributes:
value: |
Thanks for taking the time to fill out this bug report! Please provide as much information as you can. It helps us better understand the problem and fix it faster.
- type: textarea
id: version
attributes:
label: What is your BTCPay version?
description: You can see the version in the footer's bottom right corner
placeholder: I'm running BTCPay v1.X.X.X
validations:
required: true
- type: textarea
id: deployment
attributes:
label: How did you deploy BTCPay Server?
description: Docker, manual, third-party host? Read more on deployment methods [here](https://docs.btcpayserver.org/Deployment/)
placeholder: I'm running BTCPay Server on a...
validations:
required: true
- type: textarea
id: what-happened
attributes:
label: What happened?
description: A clear and concise description of what the bug is.
placeholder: Tell us what you see!
validations:
required: true
- type: textarea
id: reproduce
attributes:
label: How did you encounter this bug?
description: Step by step describe how did you encounter the bug?
placeholder: 1. I clicked X 2. Then I clicked Y 3. See error
validations:
required: true
- type: textarea
id: logoutput
attributes:
label: Relevant log output
description: Please copy and paste any relevant log output. This will be automatically formatted into code, so no need for backticks. Logs can be found in Server Settings > Logs. Here's how you can [troubleshoot an issue](https://docs.btcpayserver.org/Troubleshooting/)
render: shell
- type: textarea
id: browser
attributes:
label: What browser do you use?
description: Provide your browser and it's version. If you replicated issues on multiple browsers, let us know which ones.
placeholder: For example Safari 15.00, Chrome 10.0, Tor, Edge, etc
validations:
required: false
- type: textarea
id: additonal
attributes:
label: Additional information
description: Feel free to provide additional information. Screenshots are always helpful.
- type: checkboxes
id: terms
attributes:
label: Are you sure this is a bug report?
description: By submitting this report, you agree that this is not a support or a feature request. For general questions please read our [documentation](https://docs.btcpayserver.org). You can ask questions in [discussions](https://github.com/btcpayserver/btcpayserver/discussions) and [on our community chat](https://chat.btcpayserver.org)
options:
- label: I confirm this is a bug report
required: true

View File

@ -1,11 +1,11 @@
blank_issues_enabled: false
contact_links:
- name: 🚀 Discussions
blank_issues_enabled: true
contact_links:
- name: 🚀 Discussions
url: https://github.com/btcpayserver/btcpayserver/discussions
about: Technical discussions, questions and feature requests
about: Technical discussions, questions and feature requests
- name: 📝 Official Documentation
url: https://docs.btcpayserver.org
about: Check our documentation for answers to common questions
- name: 💬 Community Support Chat
about: Check our documentation for answers to common questions
- name: 💬 Community Support Chat
url: https://chat.btcpayserver.org/
about: Ask general questions and get community support in real-time

6
.gitignore vendored
View File

@ -288,10 +288,6 @@ __pycache__/
*.xsd.cs
/BTCPayServer/Build/dockerfiles
# Bundling JS/CSS
BTCPayServer/wwwroot/bundles/*
!BTCPayServer/wwwroot/bundles/.gitignore
.vscode/*
!.vscode/launch.json
!.vscode/tasks.json
@ -300,3 +296,5 @@ BTCPayServer/testpwd
.DS_Store
Packed Plugins
Plugins/packed
BTCPayServer/wwwroot/swagger/v1/openapi.json

View File

@ -32,10 +32,10 @@
</ItemGroup>
<ItemGroup>
<PackageReference Include="HtmlSanitizer" Version="5.0.372" />
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="6.0.1" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="6.0.1" />
<PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="6.0.3" />
<PackageReference Include="Pomelo.EntityFrameworkCore.MySql" Version="6.0.0" />
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="6.0.9" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="6.0.9" />
<PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="6.0.7" />
<PackageReference Include="Pomelo.EntityFrameworkCore.MySql" Version="6.0.1" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\BTCPayServer.Client\BTCPayServer.Client.csproj" />

View File

@ -25,7 +25,7 @@ namespace BTCPayServer.Abstractions.Contracts
class CustomNpgsqlMigrationsSqlGenerator : NpgsqlMigrationsSqlGenerator
{
#pragma warning disable EF1001 // Internal EF Core API usage.
public CustomNpgsqlMigrationsSqlGenerator(MigrationsSqlGeneratorDependencies dependencies, Npgsql.EntityFrameworkCore.PostgreSQL.Infrastructure.Internal.INpgsqlOptions opts) : base(dependencies, opts)
public CustomNpgsqlMigrationsSqlGenerator(MigrationsSqlGeneratorDependencies dependencies, Npgsql.EntityFrameworkCore.PostgreSQL.Infrastructure.Internal.INpgsqlSingletonOptions opts) : base(dependencies, opts)
#pragma warning restore EF1001 // Internal EF Core API usage.
{
}

View File

@ -0,0 +1,7 @@
#nullable enable
namespace BTCPayServer.Abstractions.Contracts;
public interface IScopeProvider
{
string? GetCurrentStoreId();
}

View File

@ -0,0 +1,12 @@
#nullable enable
using System.Collections.Generic;
using System.Threading.Tasks;
namespace BTCPayServer.Abstractions.Contracts;
public interface IStoreRepository
{
Task<T?> GetSettingAsync<T>(string storeId, string name) where T : class;
Task<Dictionary<string, T?>> GetSettingsAsync<T>(string name) where T : class;
Task UpdateSetting<T>(string storeId, string name, T obj) where T : class;
}

View File

@ -0,0 +1,13 @@
using System.Collections.Generic;
using System.Threading.Tasks;
using NBitcoin;
namespace BTCPayServer.Payments.PayJoin;
public interface IUTXOLocker
{
Task<bool> TryLock(OutPoint outpoint);
Task<bool> TryUnlock(params OutPoint[] outPoints);
Task<bool> TryLockInputs(OutPoint[] outPoints);
Task<HashSet<OutPoint>> FindLocks(OutPoint[] outpoints);
}

View File

@ -1,18 +1,19 @@
namespace BTCPayServer.Abstractions.Custodians;
namespace BTCPayServer.Abstractions.Custodians.Client;
public class AssetQuoteResult
{
public string FromAsset { get; }
public string ToAsset { get; }
public decimal Bid { get; }
public decimal Ask { get; }
public string FromAsset { get; set; }
public string ToAsset { get; set; }
public decimal Bid { get; set; }
public decimal Ask { get; set; }
public AssetQuoteResult() { }
public AssetQuoteResult(string fromAsset, string toAsset,decimal bid, decimal ask)
{
this.FromAsset = fromAsset;
this.ToAsset = toAsset;
this.Bid = bid;
this.Ask = ask;
FromAsset = fromAsset;
ToAsset = toAsset;
Bid = bid;
Ask = ask;
}
}

View File

@ -1,7 +1,7 @@
using System.Collections.Generic;
using BTCPayServer.Client.Models;
namespace BTCPayServer.Abstractions.Custodians;
namespace BTCPayServer.Abstractions.Custodians.Client;
/**
* The result of a market trade. Used as a return type for custodians implementing ICanTrade

View File

@ -2,7 +2,7 @@ using System;
using System.Collections.Generic;
using BTCPayServer.Client.Models;
namespace BTCPayServer.Abstractions.Custodians;
namespace BTCPayServer.Abstractions.Custodians.Client;
public class WithdrawResult
{

View File

@ -1,6 +1,7 @@
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using BTCPayServer.Abstractions.Custodians.Client;
using BTCPayServer.Client.Models;
using Newtonsoft.Json.Linq;

View File

@ -1,5 +1,6 @@
using System.Threading;
using System.Threading.Tasks;
using BTCPayServer.Abstractions.Custodians.Client;
using Newtonsoft.Json.Linq;
namespace BTCPayServer.Abstractions.Custodians;

View File

@ -1,6 +1,7 @@
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using BTCPayServer.Client.Models;
using Newtonsoft.Json.Linq;
namespace BTCPayServer.Abstractions.Custodians;
@ -18,4 +19,8 @@ public interface ICustodian
* Get a list of assets and their qty in custody.
*/
Task<Dictionary<string, decimal>> GetAssetBalancesAsync(JObject config, CancellationToken cancellationToken);
public Task<Form.Form> GetConfigForm(JObject config, string locale,
CancellationToken cancellationToken = default);
}

View File

@ -0,0 +1,14 @@
#nullable enable
using System.Collections.Generic;
using System.Linq;
using BTCPayServer.Abstractions.Custodians;
namespace BTCPayServer.Abstractions.Extensions;
public static class CustodianExtensions
{
public static ICustodian? GetCustodianByCode(this IEnumerable<ICustodian> custodians, string code)
{
return custodians.FirstOrDefault(custodian => custodian.Code == code);
}
}

View File

@ -1,5 +1,7 @@
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using Microsoft.AspNetCore.Html;
using Microsoft.AspNetCore.Mvc.ViewFeatures;
@ -10,6 +12,13 @@ namespace BTCPayServer.Abstractions.Extensions
private const string ACTIVE_CATEGORY_KEY = "ActiveCategory";
private const string ACTIVE_PAGE_KEY = "ActivePage";
private const string ACTIVE_ID_KEY = "ActiveId";
private const string ActivePageClass = "active";
public enum DateDisplayFormat
{
Localized,
Relative
}
public static void SetActivePage<T>(this ViewDataDictionary viewData, T activePage, string title = null, string activeId = null)
where T : IConvertible
@ -52,7 +61,7 @@ namespace BTCPayServer.Abstractions.Extensions
var activeCategory = viewData[ACTIVE_CATEGORY_KEY]?.ToString();
var categoryMatch = category.Equals(activeCategory, StringComparison.InvariantCultureIgnoreCase);
var idMatch = id == null || activeId == null || id.Equals(activeId);
return categoryMatch && idMatch ? "active" : null;
return categoryMatch && idMatch ? ActivePageClass : null;
}
public static string IsActivePage<T>(this ViewDataDictionary viewData, T page, object id = null)
@ -60,6 +69,14 @@ namespace BTCPayServer.Abstractions.Extensions
{
return IsActivePage(viewData, page.ToString(), page.GetType().ToString(), id);
}
public static string IsActivePage<T>(this ViewDataDictionary viewData, IEnumerable<T> pages, object id = null)
where T : IConvertible
{
return pages.Any(page => IsActivePage(viewData, page.ToString(), page.GetType().ToString(), id) == ActivePageClass)
? ActivePageClass
: null;
}
public static string IsActivePage(this ViewDataDictionary viewData, string page, string category, object id = null)
{
@ -72,29 +89,32 @@ namespace BTCPayServer.Abstractions.Extensions
var activeCategory = viewData[ACTIVE_CATEGORY_KEY]?.ToString();
var categoryAndPageMatch = (category == null || activeCategory.Equals(category, StringComparison.InvariantCultureIgnoreCase)) && page.Equals(activePage, StringComparison.InvariantCultureIgnoreCase);
var idMatch = id == null || activeId == null || id.Equals(activeId);
return categoryAndPageMatch && idMatch ? "active" : null;
return categoryAndPageMatch && idMatch ? ActivePageClass : null;
}
public static HtmlString ToBrowserDate(this DateTimeOffset date)
public static HtmlString ToBrowserDate(this DateTimeOffset date, DateDisplayFormat format = DateDisplayFormat.Localized)
{
var displayDate = date.ToString("o", CultureInfo.InvariantCulture);
return new HtmlString($"<span class='localizeDate'>{displayDate}</span>");
var relative = date.ToTimeAgo();
var initial = format.ToString().ToLower();
var dateTime = date.ToString("o", CultureInfo.InvariantCulture);
var displayDate = format == DateDisplayFormat.Relative ? relative : date.ToString("g", CultureInfo.InvariantCulture);
return new HtmlString($"<time datetime=\"{dateTime}\" data-relative=\"{relative}\" data-initial=\"{initial}\">{displayDate}</time>");
}
public static HtmlString ToBrowserDate(this DateTime date)
public static HtmlString ToBrowserDate(this DateTime date, DateDisplayFormat format = DateDisplayFormat.Localized)
{
var displayDate = date.ToString("o", CultureInfo.InvariantCulture);
return new HtmlString($"<span class='localizeDate'>{displayDate}</span>");
var relative = date.ToTimeAgo();
var initial = format.ToString().ToLower();
var dateTime = date.ToString("o", CultureInfo.InvariantCulture);
var displayDate = format == DateDisplayFormat.Relative ? relative : date.ToString("g", CultureInfo.InvariantCulture);
return new HtmlString($"<time datetime=\"{dateTime}\" data-relative=\"{relative}\" data-initial=\"{initial}\">{displayDate}</time>");
}
public static string ToTimeAgo(this DateTimeOffset date)
{
var diff = DateTimeOffset.UtcNow - date;
var formatted = diff.TotalSeconds > 0
? $"{diff.TimeString()} ago"
: $"in {diff.Negate().TimeString()}";
return formatted;
}
public static string ToTimeAgo(this DateTimeOffset date) => (DateTimeOffset.UtcNow - date).ToTimeAgo();
public static string ToTimeAgo(this DateTime date) => (DateTimeOffset.UtcNow - date).ToTimeAgo();
public static string ToTimeAgo(this TimeSpan diff) => diff.TotalSeconds > 0 ? $"{diff.TimeString()} ago" : $"in {diff.Negate().TimeString()}";
public static string TimeString(this TimeSpan timeSpan)
{
@ -106,16 +126,14 @@ namespace BTCPayServer.Abstractions.Extensions
{
return $"{(int)timeSpan.TotalMinutes} minute{Plural((int)timeSpan.TotalMinutes)}";
}
if (timeSpan.Days < 1)
{
return $"{(int)timeSpan.TotalHours} hour{Plural((int)timeSpan.TotalHours)}";
}
return $"{(int)timeSpan.TotalDays} day{Plural((int)timeSpan.TotalDays)}";
return timeSpan.Days < 1
? $"{(int)timeSpan.TotalHours} hour{Plural((int)timeSpan.TotalHours)}"
: $"{(int)timeSpan.TotalDays} day{Plural((int)timeSpan.TotalDays)}";
}
private static string Plural(int value)
{
return value > 1 ? "s" : string.Empty;
return value == 1 ? string.Empty : "s";
}
}
}

View File

@ -0,0 +1,37 @@
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
namespace BTCPayServer.Abstractions.Form;
public class AlertMessage
{
// Corresponds to the Bootstrap CSS "alert alert-xxx" messages:
// Success = green
// Warning = orange
// Danger = red
// Info = blue
public enum AlertMessageType
{
Success,
Warning,
Danger,
Info
}
[JsonConverter(typeof(StringEnumConverter))]
public AlertMessageType Type;
// The translated message to be shown to the user
public string Message;
public AlertMessage()
{
}
public AlertMessage(AlertMessageType type, string message)
{
this.Type = type;
this.Message = message;
}
}

View File

@ -0,0 +1,35 @@
using System.Collections.Generic;
namespace BTCPayServer.Abstractions.Form;
public abstract class Field
{
// HTML5 compatible type string like "text", "textarea", "email", "password", etc. Each type is a class and may contain more fields (i.e. "select" would have options).
public string Type;
// The name of the HTML5 node. Should be used as the key for the posted data.
public string Name;
// The translated label of the field.
public string Label;
// The value field is what is currently in the DB or what the user entered, but possibly not saved yet due to validation errors.
// If this is the first the user sees the form, then value and original value are the same. Value changes as the user starts interacting with the form.
public string Value;
// The original value is the value that is currently saved in the backend. A "reset" button can be used to revert back to this. Should only be set from the constructor.
public string OriginalValue;
// A useful note shown below the field or via a tooltip / info icon. Should be translated for the user.
public string HelpText;
// The field is considered "valid" if there are no validation errors
public List<string> ValidationErrors = new List<string>();
public bool Required = false;
public bool IsValid()
{
return ValidationErrors.Count == 0;
}
}

View File

@ -0,0 +1,14 @@
using System.Collections.Generic;
namespace BTCPayServer.Abstractions.Form;
public class Fieldset
{
public Fieldset()
{
this.Fields = new List<Field>();
}
public string Label { get; set; }
public List<Field> Fields { get; set; }
}

View File

@ -0,0 +1,60 @@
using System.Collections.Generic;
namespace BTCPayServer.Abstractions.Form;
public class Form
{
// Messages to be shown at the top of the form indicating user feedback like "Saved successfully" or "Please change X because of Y." or a warning, etc...
public List<AlertMessage> TopMessages { get; set; } = new();
// Groups of fields in the form
public List<Fieldset> Fieldsets { get; set; } = new();
// Are all the fields valid in the form?
public bool IsValid()
{
foreach (var fieldset in Fieldsets)
{
foreach (var field in fieldset.Fields)
{
if (!field.IsValid())
{
return false;
}
}
}
return true;
}
public Field GetFieldByName(string name)
{
foreach (var fieldset in Fieldsets)
{
foreach (var field in fieldset.Fields)
{
if (name.Equals(field.Name))
{
return field;
}
}
}
return null;
}
public List<string> GetAllNames()
{
var names = new List<string>();
foreach (var fieldset in Fieldsets)
{
foreach (var field in fieldset.Fields)
{
names.Add(field.Name);
}
}
return names;
}
}

View File

@ -0,0 +1,19 @@
namespace BTCPayServer.Abstractions.Form;
public class TextField : Field
{
public TextField(string label, string name, string value, bool required, string helpText)
{
this.Label = label;
this.Name = name;
this.Value = value;
this.OriginalValue = value;
this.Required = required;
this.HelpText = helpText;
this.Type = "text";
}
// TODO JSON parsing from string to objects again probably won't work out of the box because of the different field types.
}

View File

@ -1,6 +1,6 @@
using System;
namespace BTCPayServer.Models
namespace BTCPayServer.Abstractions.Models
{
public class ConfirmModel
{

View File

@ -0,0 +1,27 @@
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http;
namespace BTCPayServer.Security;
public class AuthorizationFilterHandle
{
public AuthorizationHandlerContext Context { get; }
public PolicyRequirement Requirement { get; }
public HttpContext HttpContext { get; }
public bool Success { get; private set; }
public AuthorizationFilterHandle(
AuthorizationHandlerContext context,
PolicyRequirement requirement,
HttpContext httpContext)
{
Context = context;
Requirement = requirement;
HttpContext = httpContext;
}
public void MarkSuccessful()
{
Success = true;
}
}

View File

@ -1,7 +1,8 @@
using System;
using BTCPayServer.Security;
using Microsoft.AspNetCore.Razor.TagHelpers;
namespace BTCPayServer.TagHelpers;
namespace BTCPayServer.Abstractions.TagHelpers;
/// <summary>
/// Add sha256- to allow inline event handlers in a:href=javascript:

View File

@ -2,8 +2,8 @@ using System.Collections.Generic;
using System.Linq;
using BTCPayServer.Security;
using Microsoft.AspNetCore.Razor.TagHelpers;
namespace BTCPayServer.TagHelpers;
namespace BTCPayServer.Abstractions.TagHelpers;
/// <summary>
/// Add 'unsafe-hashes' and sha256- to allow inline event handlers in CSP

View File

@ -1,8 +1,8 @@
using BTCPayServer.Security;
using Microsoft.AspNetCore.Razor.TagHelpers;
using NBitcoin;
namespace BTCPayServer.TagHelpers;
namespace BTCPayServer.Abstractions.TagHelpers;
/// <summary>
/// Add a nonce-* so the inline-script can pass CSP rule when they are rendered server-side

View File

@ -1,7 +1,8 @@
using System.Threading.Tasks;
using BTCPayServer.Security;
using Microsoft.AspNetCore.Razor.TagHelpers;
namespace BTCPayServer.TagHelpers;
namespace BTCPayServer.Abstractions.TagHelpers;
/// <summary>
/// Add sha256- to allow inline event handlers in CSP

View File

@ -3,8 +3,8 @@ using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Razor.TagHelpers;
using Microsoft.Extensions.Logging;
namespace BTCPayServer.TagHelpers;
namespace BTCPayServer.Abstractions.TagHelpers;
[HtmlTargetElement(Attributes = nameof(Permission))]
public class PermissionTagHelper : TagHelper

View File

@ -1,11 +1,10 @@
using System.Text.Encodings.Web;
using Microsoft.AspNetCore.Mvc.Razor.TagHelpers;
using Microsoft.AspNetCore.Mvc.Rendering;
using Microsoft.AspNetCore.Mvc.Routing;
using Microsoft.AspNetCore.Mvc.ViewFeatures;
using Microsoft.AspNetCore.Razor.TagHelpers;
namespace BTCPayServer.TagHelpers;
namespace BTCPayServer.Abstractions.TagHelpers;
// Make sure that <svg><use href=/ are correctly working if rootpath is present
[HtmlTargetElement("use", Attributes = "href")]

View File

@ -1,9 +1,9 @@
using BTCPayServer.Abstractions.Services;
using BTCPayServer.Security;
using BTCPayServer.Services;
using Microsoft.AspNetCore.Razor.TagHelpers;
using NBitcoin;
namespace BTCPayServer.TagHelpers;
namespace BTCPayServer.Abstractions.TagHelpers;
[HtmlTargetElement("srv-model")]
public class SrvModel : TagHelper

View File

@ -28,8 +28,8 @@
<PackageReference Include="Microsoft.SourceLink.GitHub" Version="1.0.0" PrivateAssets="All" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="BTCPayServer.Lightning.Common" Version="1.3.4" />
<PackageReference Include="NBitcoin" Version="7.0.1" />
<PackageReference Include="BTCPayServer.Lightning.Common" Version="1.3.15" />
<PackageReference Include="NBitcoin" Version="7.0.14" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
</ItemGroup>
<ItemGroup>

View File

@ -0,0 +1,65 @@
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<PointOfSaleAppData> CreatePointOfSaleApp(string storeId,
CreatePointOfSaleAppRequest request, CancellationToken token = default)
{
if (request == null)
throw new ArgumentNullException(nameof(request));
var response = await _httpClient.SendAsync(
CreateHttpRequest($"api/v1/stores/{storeId}/apps/pos", bodyPayload: request,
method: HttpMethod.Post), token);
return await HandleResponse<PointOfSaleAppData>(response);
}
public virtual async Task<CrowdfundAppData> CreateCrowdfundApp(string storeId,
CreateCrowdfundAppRequest request, CancellationToken token = default)
{
if (request == null)
throw new ArgumentNullException(nameof(request));
var response = await _httpClient.SendAsync(
CreateHttpRequest($"api/v1/stores/{storeId}/apps/crowdfund", bodyPayload: request,
method: HttpMethod.Post), token);
return await HandleResponse<CrowdfundAppData>(response);
}
public virtual async Task<PointOfSaleAppData> UpdatePointOfSaleApp(string appId,
CreatePointOfSaleAppRequest request, CancellationToken token = default)
{
if (request == null)
throw new ArgumentNullException(nameof(request));
var response = await _httpClient.SendAsync(
CreateHttpRequest($"api/v1/apps/pos/{appId}", bodyPayload: request,
method: HttpMethod.Put), token);
return await HandleResponse<PointOfSaleAppData>(response);
}
public virtual async Task<AppDataBase> GetApp(string appId, CancellationToken token = default)
{
if (appId == null)
throw new ArgumentNullException(nameof(appId));
var response = await _httpClient.SendAsync(
CreateHttpRequest($"api/v1/apps/{appId}",
method: HttpMethod.Get), token);
return await HandleResponse<AppDataBase>(response);
}
public virtual async Task DeleteApp(string appId, CancellationToken token = default)
{
if (appId == null)
throw new ArgumentNullException(nameof(appId));
var response = await _httpClient.SendAsync(
CreateHttpRequest($"api/v1/apps/{appId}",
method: HttpMethod.Delete), token);
await HandleResponse(response);
}
}
}

View File

@ -56,9 +56,14 @@ namespace BTCPayServer.Client
return await HandleResponse<DepositAddressData>(response);
}
public virtual async Task<MarketTradeResponseData> TradeMarket(string storeId, string accountId, TradeRequestData request, CancellationToken token = default)
public virtual async Task<MarketTradeResponseData> MarketTradeCustodianAccountAsset(string storeId, string accountId, TradeRequestData request, CancellationToken token = default)
{
var response = await _httpClient.SendAsync(CreateHttpRequest($"api/v1/stores/{storeId}/custodian-accounts/{accountId}/trades/market", bodyPayload: request, method: HttpMethod.Post), token);
//var response = await _httpClient.SendAsync(CreateHttpRequest("api/v1/users", null, request, HttpMethod.Post), token);
//return await HandleResponse<ApplicationUserData>(response);
var internalRequest = CreateHttpRequest($"api/v1/stores/{storeId}/custodian-accounts/{accountId}/trades/market", null,
request, HttpMethod.Post);
var response = await _httpClient.SendAsync(internalRequest, token);
return await HandleResponse<MarketTradeResponseData>(response);
}
@ -73,7 +78,6 @@ namespace BTCPayServer.Client
var queryPayload = new Dictionary<string, object>();
queryPayload.Add("fromAsset", fromAsset);
queryPayload.Add("toAsset", toAsset);
var response = await _httpClient.SendAsync(CreateHttpRequest($"api/v1/stores/{storeId}/custodian-accounts/{accountId}/trades/quote", queryPayload), token);
return await HandleResponse<TradeQuoteResponseData>(response);
}

View File

@ -17,6 +17,15 @@ namespace BTCPayServer.Client
method: HttpMethod.Get), token);
return await HandleResponse<LightningNodeInformationData>(response);
}
public virtual async Task<LightningNodeBalanceData> GetLightningNodeBalance(string cryptoCode,
CancellationToken token = default)
{
var response = await _httpClient.SendAsync(
CreateHttpRequest($"api/v1/server/lightning/{cryptoCode}/balance",
method: HttpMethod.Get), token);
return await HandleResponse<LightningNodeBalanceData>(response);
}
public virtual async Task ConnectToLightningNode(string cryptoCode, ConnectToNodeRequest request,
CancellationToken token = default)
@ -86,6 +95,24 @@ namespace BTCPayServer.Client
method: HttpMethod.Get), token);
return await HandleResponse<LightningInvoiceData>(response);
}
public virtual async Task<LightningInvoiceData[]> GetLightningInvoices(string cryptoCode,
bool? pendingOnly = null, long? offsetIndex = null, CancellationToken token = default)
{
var queryPayload = new Dictionary<string, object>();
if (pendingOnly is bool v)
{
queryPayload.Add("pendingOnly", v.ToString());
}
if (offsetIndex is > 0)
{
queryPayload.Add("offsetIndex", offsetIndex);
}
var response = await _httpClient.SendAsync(
CreateHttpRequest($"api/v1/server/lightning/{cryptoCode}/invoices", queryPayload), token);
return await HandleResponse<LightningInvoiceData[]>(response);
}
public virtual async Task<LightningInvoiceData> CreateLightningInvoice(string cryptoCode, CreateLightningInvoiceRequest request,
CancellationToken token = default)

View File

@ -17,6 +17,15 @@ namespace BTCPayServer.Client
method: HttpMethod.Get), token);
return await HandleResponse<LightningNodeInformationData>(response);
}
public virtual async Task<LightningNodeBalanceData> GetLightningNodeBalance(string storeId, string cryptoCode,
CancellationToken token = default)
{
var response = await _httpClient.SendAsync(
CreateHttpRequest($"api/v1/stores/{storeId}/lightning/{cryptoCode}/balance",
method: HttpMethod.Get), token);
return await HandleResponse<LightningNodeBalanceData>(response);
}
public virtual async Task ConnectToLightningNode(string storeId, string cryptoCode, ConnectToNodeRequest request,
CancellationToken token = default)
@ -56,7 +65,7 @@ namespace BTCPayServer.Client
return await HandleResponse<string>(response);
}
public virtual async Task PayLightningInvoice(string storeId, string cryptoCode, PayLightningInvoiceRequest request,
public virtual async Task<LightningPaymentData> PayLightningInvoice(string storeId, string cryptoCode, PayLightningInvoiceRequest request,
CancellationToken token = default)
{
if (request == null)
@ -64,7 +73,7 @@ namespace BTCPayServer.Client
var response = await _httpClient.SendAsync(
CreateHttpRequest($"api/v1/stores/{storeId}/lightning/{cryptoCode}/invoices/pay", bodyPayload: request,
method: HttpMethod.Post), token);
await HandleResponse(response);
return await HandleResponse<LightningPaymentData>(response);
}
public virtual async Task<LightningPaymentData> GetLightningPayment(string storeId, string cryptoCode,
@ -88,6 +97,24 @@ namespace BTCPayServer.Client
method: HttpMethod.Get), token);
return await HandleResponse<LightningInvoiceData>(response);
}
public virtual async Task<LightningInvoiceData[]> GetLightningInvoices(string storeId, string cryptoCode,
bool? pendingOnly = null, long? offsetIndex = null, CancellationToken token = default)
{
var queryPayload = new Dictionary<string, object>();
if (pendingOnly is bool v)
{
queryPayload.Add("pendingOnly", v.ToString());
}
if (offsetIndex is > 0)
{
queryPayload.Add("offsetIndex", offsetIndex);
}
var response = await _httpClient.SendAsync(
CreateHttpRequest($"api/v1/stores/{storeId}/lightning/{cryptoCode}/invoices", queryPayload), token);
return await HandleResponse<LightningInvoiceData[]>(response);
}
public virtual async Task<LightningInvoiceData> CreateLightningInvoice(string storeId, string cryptoCode,
CreateLightningInvoiceRequest request, CancellationToken token = default)

View File

@ -0,0 +1,82 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Threading;
using System.Threading.Tasks;
using BTCPayServer.Client.Models;
using NBitcoin;
namespace BTCPayServer.Client
{
public partial class BTCPayServerClient
{
public virtual async Task<OnChainWalletObjectData> GetOnChainWalletObject(string storeId, string cryptoCode, OnChainWalletObjectId objectId, bool? includeNeighbourData = null, CancellationToken token = default)
{
Dictionary<string, object> parameters = new Dictionary<string, object>();
if (includeNeighbourData is bool v)
parameters.Add("includeNeighbourData", v);
var response =
await _httpClient.SendAsync(
CreateHttpRequest($"api/v1/stores/{storeId}/payment-methods/onchain/{cryptoCode}/wallet/objects/{objectId.Type}/{objectId.Id}", parameters, method: HttpMethod.Get), token);
try
{
return await HandleResponse<OnChainWalletObjectData>(response);
}
catch (GreenfieldAPIException err) when (err.APIError.Code == "wallet-object-not-found")
{
return null;
}
}
public virtual async Task<OnChainWalletObjectData[]> GetOnChainWalletObjects(string storeId, string cryptoCode, GetWalletObjectsRequest query = null, CancellationToken token = default)
{
Dictionary<string, object> parameters = new Dictionary<string, object>();
if (query?.Type is string s)
parameters.Add("type", s);
if (query?.Ids is string[] ids)
parameters.Add("ids", ids);
if (query?.IncludeNeighbourData is bool v)
parameters.Add("includeNeighbourData", v);
var response =
await _httpClient.SendAsync(
CreateHttpRequest($"api/v1/stores/{storeId}/payment-methods/onchain/{cryptoCode}/wallet/objects", parameters, method:HttpMethod.Get), token);
return await HandleResponse<OnChainWalletObjectData[]>(response);
}
public virtual async Task RemoveOnChainWalletObject(string storeId, string cryptoCode, OnChainWalletObjectId objectId,
CancellationToken token = default)
{
var response =
await _httpClient.SendAsync(
CreateHttpRequest($"api/v1/stores/{storeId}/payment-methods/onchain/{cryptoCode}/wallet/objects/{objectId.Type}/{objectId.Id}", method:HttpMethod.Delete), token);
await HandleResponse(response);
}
public virtual async Task<OnChainWalletObjectData> AddOrUpdateOnChainWalletObject(string storeId, string cryptoCode, AddOnChainWalletObjectRequest request,
CancellationToken token = default)
{
var response =
await _httpClient.SendAsync(
CreateHttpRequest($"api/v1/stores/{storeId}/payment-methods/onchain/{cryptoCode}/wallet/objects", method:HttpMethod.Post, bodyPayload: request), token);
return await HandleResponse<OnChainWalletObjectData>(response);
}
public virtual async Task AddOrUpdateOnChainWalletLink(string storeId, string cryptoCode,
OnChainWalletObjectId objectId,
AddOnChainWalletObjectLinkRequest request = null,
CancellationToken token = default)
{
var response =
await _httpClient.SendAsync(
CreateHttpRequest($"api/v1/stores/{storeId}/payment-methods/onchain/{cryptoCode}/wallet/objects/{objectId.Type}/{objectId.Id}/links", method:HttpMethod.Post, bodyPayload: request), token);
await HandleResponse(response);
}
public virtual async Task RemoveOnChainWalletLinks(string storeId, string cryptoCode,
OnChainWalletObjectId objectId,
OnChainWalletObjectId link,
CancellationToken token = default)
{
var response =
await _httpClient.SendAsync(
CreateHttpRequest($"api/v1/stores/{storeId}/payment-methods/onchain/{cryptoCode}/wallet/objects/{objectId.Type}/{objectId.Id}/links/{link.Type}/{link.Id}", method:HttpMethod.Delete), token);
await HandleResponse(response);
}
}
}

View File

@ -85,11 +85,14 @@ namespace BTCPayServer.Client
public virtual async Task<OnChainWalletTransactionData> PatchOnChainWalletTransaction(
string storeId, string cryptoCode, string transactionId,
PatchOnChainTransactionRequest request,
CancellationToken token = default)
bool force = false, CancellationToken token = default)
{
var response =
await _httpClient.SendAsync(
CreateHttpRequest($"api/v1/stores/{storeId}/payment-methods/onchain/{cryptoCode}/wallet/transactions/{transactionId}", queryPayload: null, bodyPayload: request, HttpMethod.Patch), token);
CreateHttpRequest($"api/v1/stores/{storeId}/payment-methods/onchain/{cryptoCode}/wallet/transactions/{transactionId}", queryPayload: new Dictionary<string, object>()
{
{"force", force}
}, bodyPayload: request, HttpMethod.Patch), token);
return await HandleResponse<OnChainWalletTransactionData>(response);
}

View File

@ -37,6 +37,20 @@ namespace BTCPayServer.Client
await HandleResponse(response);
}
public virtual async Task<Client.Models.InvoiceData> PayPaymentRequest(string storeId, string paymentRequestId, PayPaymentRequestRequest request, CancellationToken token = default)
{
if (request == null)
throw new ArgumentNullException(nameof(request));
if (storeId is null)
throw new ArgumentNullException(nameof(storeId));
if (paymentRequestId is null)
throw new ArgumentNullException(nameof(paymentRequestId));
var response = await _httpClient.SendAsync(
CreateHttpRequest($"api/v1/stores/{storeId}/payment-requests/{paymentRequestId}/pay", bodyPayload: request,
method: HttpMethod.Post), token);
return await HandleResponse<Client.Models.InvoiceData>(response);
}
public virtual async Task<PaymentRequestData> CreatePaymentRequest(string storeId,
CreatePaymentRequestRequest request, CancellationToken token = default)
{

View File

@ -53,6 +53,16 @@ namespace BTCPayServer.Client
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 virtual async Task<PayoutData> GetPullPaymentPayout(string pullPaymentId, string payoutId, CancellationToken cancellationToken = default)
{
var response = await _httpClient.SendAsync(CreateHttpRequest($"api/v1/pull-payments/{HttpUtility.UrlEncode(pullPaymentId)}/payouts/{payoutId}", method: HttpMethod.Get), cancellationToken);
return await HandleResponse<PayoutData>(response);
}
public virtual async Task<PayoutData> GetStorePayout(string storeId, string payoutId, CancellationToken cancellationToken = default)
{
var response = await _httpClient.SendAsync(CreateHttpRequest($"api/v1/stores/{storeId}/payouts/{payoutId}", method: HttpMethod.Get), cancellationToken);
return await HandleResponse<PayoutData>(response);
}
public virtual async Task<PayoutData> CreatePayout(string storeId, CreatePayoutThroughStoreRequest payoutRequest, CancellationToken cancellationToken = default)
{
var response = await _httpClient.SendAsync(CreateHttpRequest($"api/v1/stores/{storeId}/payouts", bodyPayload: payoutRequest, method: HttpMethod.Post), cancellationToken);
@ -69,7 +79,7 @@ namespace BTCPayServer.Client
return await HandleResponse<PayoutData>(response);
}
public async Task MarkPayoutPaid(string storeId, string payoutId,
public virtual async Task MarkPayoutPaid(string storeId, string payoutId,
CancellationToken cancellationToken = default)
{
var response = await _httpClient.SendAsync(
@ -78,5 +88,14 @@ namespace BTCPayServer.Client
method: HttpMethod.Post), cancellationToken);
await HandleResponse(response);
}
public virtual async Task MarkPayout(string storeId, string payoutId, MarkPayoutRequest request,
CancellationToken cancellationToken = default)
{
var response = await _httpClient.SendAsync(
CreateHttpRequest(
$"api/v1/stores/{HttpUtility.UrlEncode(storeId)}/payouts/{HttpUtility.UrlEncode(payoutId)}/mark",
method: HttpMethod.Post, bodyPayload: request), cancellationToken);
await HandleResponse(response);
}
}
}

View File

@ -0,0 +1,53 @@
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<StoreRateConfiguration> GetStoreRateConfiguration(string storeId,
CancellationToken token = default)
{
using var response = await _httpClient.SendAsync(
CreateHttpRequest($"api/v1/stores/{storeId}/rates/configuration", method: HttpMethod.Get),
token);
return await HandleResponse<StoreRateConfiguration>(response);
}
public virtual async Task<List<RateSource>> GetRateSources(
CancellationToken token = default)
{
using var response = await _httpClient.SendAsync(
CreateHttpRequest($"misc/rate-sources", method: HttpMethod.Get),
token);
return await HandleResponse<List<RateSource>>(response);
}
public virtual async Task<StoreRateConfiguration> UpdateStoreRateConfiguration(string storeId,
StoreRateConfiguration request,
CancellationToken token = default)
{
using var response = await _httpClient.SendAsync(
CreateHttpRequest($"api/v1/stores/{storeId}/rates/configuration", bodyPayload: request,
method: HttpMethod.Put),
token);
return await HandleResponse<StoreRateConfiguration>(response);
}
public virtual async Task<List<StoreRatePreviewResult>> PreviewUpdateStoreRateConfiguration(string storeId,
StoreRateConfiguration request,
string[] currencyPair,
CancellationToken token = default)
{
using var response = await _httpClient.SendAsync(
CreateHttpRequest($"api/v1/stores/{storeId}/rates/configuration/preview", bodyPayload: request,
queryPayload: new Dictionary<string, object>() {{"currencyPair", currencyPair}},
method: HttpMethod.Post),
token);
return await HandleResponse<List<StoreRatePreviewResult>>(response);
}
}
}

View File

@ -1,22 +1,32 @@
using Newtonsoft.Json;
namespace BTCPayServer.Client.Models;
[JsonObject(MemberSerialization.OptIn)]
public class AssetPairData
{
public AssetPairData()
{
}
public AssetPairData(string AssetBought, string AssetSold)
public AssetPairData(string assetBought, string assetSold, decimal minimumTradeQty)
{
this.AssetBought = AssetBought;
this.AssetSold = AssetSold;
AssetBought = assetBought;
AssetSold = assetSold;
MinimumTradeQty = minimumTradeQty;
}
[JsonProperty]
public string AssetBought { set; get; }
[JsonProperty]
public string AssetSold { set; get; }
public string ToString()
[JsonProperty]
public decimal MinimumTradeQty { set; get; }
public override string ToString()
{
return AssetBought + "/" + AssetSold;
}

View File

@ -0,0 +1,84 @@
using System;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
namespace BTCPayServer.Client.Models
{
public enum PosViewType
{
Static,
Cart,
Light,
Print
}
public class CreateAppRequest
{
public string AppName { get; set; }
public string AppType { get; set; }
}
public class CreatePointOfSaleAppRequest : CreateAppRequest
{
public string Currency { get; set; } = null;
public string Title { get; set; } = null;
public string Description { get; set; } = null;
public string Template { get; set; } = null;
[JsonConverter(typeof(StringEnumConverter))]
public PosViewType DefaultView { get; set; }
public bool ShowCustomAmount { get; set; } = false;
public bool ShowDiscount { get; set; } = true;
public bool EnableTips { get; set; } = true;
public string CustomAmountPayButtonText { get; set; } = null;
public string FixedAmountPayButtonText { get; set; } = null;
public string TipText { get; set; } = null;
public string CustomCSSLink { get; set; } = null;
public string NotificationUrl { get; set; } = null;
public string RedirectUrl { get; set; } = null;
public bool? RedirectAutomatically { get; set; } = null;
public bool? RequiresRefundEmail { get; set; } = null;
public string CheckoutFormId { get; set; } = null;
public string EmbeddedCSS { get; set; } = null;
public CheckoutType? CheckoutType { get; set; } = null;
}
public enum CrowdfundResetEvery
{
Never,
Hour,
Day,
Month,
Year
}
public class CreateCrowdfundAppRequest : CreateAppRequest
{
public string Title { get; set; } = null;
public bool? Enabled { get; set; } = null;
public bool? EnforceTargetAmount { get; set; } = null;
[JsonConverter(typeof(NBitcoin.JsonConverters.DateTimeToUnixTimeConverter))]
public DateTimeOffset? StartDate { get; set; } = null;
public string TargetCurrency { get; set; } = null;
public string Description { get; set; } = null;
[JsonConverter(typeof(NBitcoin.JsonConverters.DateTimeToUnixTimeConverter))]
public DateTimeOffset? EndDate { get; set; } = null;
public decimal? TargetAmount { get; set; } = null;
public string CustomCSSLink { get; set; } = null;
public string MainImageUrl { get; set; } = null;
public string EmbeddedCSS { get; set; } = null;
public string NotificationUrl { get; set; } = null;
public string Tagline { get; set; } = null;
public string PerksTemplate { get; set; } = null;
public bool? SoundsEnabled { get; set; } = null;
public string DisqusShortname { get; set; } = null;
public bool? AnimationsEnabled { get; set; } = null;
public int? ResetEveryAmount { get; set; } = null;
[JsonConverter(typeof(StringEnumConverter))]
public CrowdfundResetEvery ResetEvery { get; set; } = CrowdfundResetEvery.Never;
public bool? DisplayPerksValue { get; set; } = null;
public bool? DisplayPerksRanking { get; set; } = null;
public bool? SortPerksByPopularity { get; set; } = null;
public string[] Sounds { get; set; } = null;
public string[] AnimationColors { get; set; } = null;
}
}

View File

@ -26,5 +26,6 @@ namespace BTCPayServer.Client.Models
public List<CreateOnChainTransactionRequestDestination> Destinations { get; set; }
[JsonProperty("rbf")]
public bool? RBF { get; set; } = null;
public bool ExcludeUnconfirmed { get; set; } = false;
}
}

View File

@ -1,10 +1,12 @@
using System.Collections.Generic;
namespace BTCPayServer.Client.Models;
public class CustodianData
{
public string Code { get; set; }
public string Name { get; set; }
public string[] TradableAssetPairs { get; set; }
public Dictionary<string, AssetPairData> TradableAssetPairs { get; set; }
public string[] WithdrawablePaymentMethods { get; set; }
public string[] DepositablePaymentMethods { get; set; }

View File

@ -1,4 +1,4 @@
namespace BTCPayServer.Client.Models;
namespace BTCPayServer.Client.Models;
public class EmailSettingsData
{
@ -21,13 +21,9 @@ public class EmailSettingsData
{
get; set;
}
public string FromDisplay
{
get; set;
}
public string From
{
get; set;
}
public bool DisableCertificateCheck { get; set; }
}

View File

@ -1,4 +1,5 @@
using System;
using System.Collections.Generic;
using BTCPayServer.Client.JsonConverters;
using BTCPayServer.JsonConverters;
using Newtonsoft.Json;
@ -19,6 +20,48 @@ namespace BTCPayServer.Client.Models
public string Currency { get; set; }
public JObject Metadata { get; set; }
public CheckoutOptions Checkout { get; set; } = new CheckoutOptions();
public ReceiptOptions Receipt { get; set; } = new ReceiptOptions();
public class ReceiptOptions
{
public bool? Enabled { get; set; }
public bool? ShowQR { get; set; }
public bool? ShowPayments { get; set; }
[JsonExtensionData]
public IDictionary<string, JToken> AdditionalData { get; set; }
#nullable enable
/// <summary>
/// Make sure that the return has all values set by order of priority: invoice/store/default
/// </summary>
/// <param name="storeLevelOption"></param>
/// <param name="invoiceLevelOption"></param>
/// <returns></returns>
public static ReceiptOptions Merge(ReceiptOptions? storeLevelOption, ReceiptOptions? invoiceLevelOption)
{
storeLevelOption ??= new ReceiptOptions();
invoiceLevelOption ??= new ReceiptOptions();
var store = JObject.FromObject(storeLevelOption);
var inv = JObject.FromObject(invoiceLevelOption);
var result = JObject.FromObject(CreateDefault());
var mergeSettings = new JsonMergeSettings() { MergeNullValueHandling = MergeNullValueHandling.Ignore };
result.Merge(store, mergeSettings);
result.Merge(inv, mergeSettings);
var options = result.ToObject<ReceiptOptions>()!;
return options;
}
public static ReceiptOptions CreateDefault()
{
return new ReceiptOptions()
{
ShowQR = true,
Enabled = true,
ShowPayments = true
};
}
#nullable restore
}
public class CheckoutOptions
{
@ -42,6 +85,9 @@ namespace BTCPayServer.Client.Models
public bool? RedirectAutomatically { get; set; }
public bool? RequiresRefundEmail { get; set; } = null;
public string DefaultLanguage { get; set; }
[JsonProperty("checkoutFormId")]
public string CheckoutFormId { get; set; }
public CheckoutType? CheckoutType { get; set; }
}
}
public class InvoiceData : InvoiceDataBase

View File

@ -1,9 +1,11 @@
using System;
using System.Collections.Generic;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
namespace BTCPayServer.Client.Models
{
[Obsolete]
public class LabelData
{
public string Type { get; set; }

View File

@ -1,4 +1,5 @@
using System;
using System.Collections.Generic;
using BTCPayServer.Client.JsonConverters;
using BTCPayServer.Lightning;
using Newtonsoft.Json;
@ -26,5 +27,8 @@ namespace BTCPayServer.Client.Models
[JsonConverter(typeof(LightMoneyJsonConverter))]
public LightMoney AmountReceived { get; set; }
[JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
public Dictionary<ulong, string> CustomRecords { get; set; }
}
}

View File

@ -0,0 +1,53 @@
using BTCPayServer.Client.JsonConverters;
using BTCPayServer.Lightning;
using NBitcoin;
using Newtonsoft.Json;
namespace BTCPayServer.Client.Models
{
public class LightningNodeBalanceData
{
[JsonProperty("onchain")]
public OnchainBalanceData OnchainBalance { get; set; }
[JsonProperty("offchain")]
public OffchainBalanceData OffchainBalance { get; set; }
public LightningNodeBalanceData()
{
}
public LightningNodeBalanceData(OnchainBalanceData onchain, OffchainBalanceData offchain)
{
OnchainBalance = onchain;
OffchainBalance = offchain;
}
}
public class OnchainBalanceData
{
[JsonConverter(typeof(JsonConverters.MoneyJsonConverter))]
public Money Confirmed { get; set; }
[JsonConverter(typeof(JsonConverters.MoneyJsonConverter))]
public Money Unconfirmed { get; set; }
[JsonConverter(typeof(JsonConverters.MoneyJsonConverter))]
public Money Reserved { get; set; }
}
public class OffchainBalanceData
{
[JsonConverter(typeof(LightMoneyJsonConverter))]
public LightMoney Opening { get; set; }
[JsonConverter(typeof(LightMoneyJsonConverter))]
public LightMoney Local { get; set; }
[JsonConverter(typeof(LightMoneyJsonConverter))]
public LightMoney Remote { get; set; }
[JsonConverter(typeof(LightMoneyJsonConverter))]
public LightMoney Closing { get; set; }
}
}

View File

@ -9,6 +9,13 @@ namespace BTCPayServer.Client.Models
[JsonProperty("nodeURIs", ItemConverterType = typeof(NodeUriJsonConverter))]
public NodeInfo[] NodeURIs { get; set; }
public int BlockHeight { get; set; }
public string Alias { get; set; }
public string Color { get; set; }
public string Version { get; set; }
public long? PeersCount { get; set; }
public long? ActiveChannelsCount { get; set; }
public long? InactiveChannelsCount { get; set; }
public long? PendingChannelsCount { get; set; }
}
public class LightningChannelData

View File

@ -0,0 +1,14 @@
#nullable enable
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
using Newtonsoft.Json.Linq;
namespace BTCPayServer.Client.Models;
public class MarkPayoutRequest
{
[JsonConverter(typeof(StringEnumConverter))]
public PayoutState State { get; set; } = PayoutState.Completed;
public JObject? PaymentProof { get; set; }
}

View File

@ -10,4 +10,6 @@ public class OnChainAutomatedPayoutSettings
[JsonConverter(typeof(TimeSpanJsonConverter.Seconds))]
public TimeSpan IntervalSeconds { get; set; }
public int? FeeBlockTarget { get; set; }
}

View File

@ -4,16 +4,94 @@ using BTCPayServer.JsonConverters;
using NBitcoin;
using NBitcoin.JsonConverters;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
namespace BTCPayServer.Client.Models
{
public class OnChainWalletObjectId
{
public OnChainWalletObjectId()
{
}
public OnChainWalletObjectId(string type, string id)
{
Type = type;
Id = id;
}
public string Type { get; set; }
public string Id { get; set; }
}
public class AddOnChainWalletObjectLinkRequest : OnChainWalletObjectId
{
public AddOnChainWalletObjectLinkRequest()
{
}
public AddOnChainWalletObjectLinkRequest(string objectType, string objectId) : base(objectType, objectId)
{
}
public JObject Data { get; set; }
}
public class GetWalletObjectsRequest
{
public string Type { get; set; }
public string[] Ids { get; set; }
public bool? IncludeNeighbourData { get; set; }
}
public class AddOnChainWalletObjectRequest : OnChainWalletObjectId
{
public AddOnChainWalletObjectRequest()
{
}
public AddOnChainWalletObjectRequest(string objectType, string objectId) : base(objectType, objectId)
{
}
public JObject Data { get; set; }
}
public class OnChainWalletObjectData : OnChainWalletObjectId
{
public OnChainWalletObjectData()
{
}
public OnChainWalletObjectData(string type, string id) : base(type, id)
{
}
public class OnChainWalletObjectLink : OnChainWalletObjectId
{
public OnChainWalletObjectLink()
{
}
public OnChainWalletObjectLink(string type, string id) : base(type, id)
{
}
public JObject LinkData { get; set; }
public JObject ObjectData { get; set; }
}
public JObject Data { get; set; }
public OnChainWalletObjectLink[] Links { get; set; }
}
public class OnChainWalletTransactionData
{
[JsonConverter(typeof(UInt256JsonConverter))]
public uint256 TransactionHash { get; set; }
public string Comment { get; set; }
#pragma warning disable CS0612 // Type or member is obsolete
public Dictionary<string, LabelData> Labels { get; set; } = new Dictionary<string, LabelData>();
#pragma warning restore CS0612 // Type or member is obsolete
[JsonConverter(typeof(NumericStringJsonConverter))]
public decimal Amount { get; set; }

View File

@ -15,7 +15,9 @@ namespace BTCPayServer.Client.Models
[JsonConverter(typeof(OutpointJsonConverter))]
public OutPoint Outpoint { get; set; }
public string Link { get; set; }
#pragma warning disable CS0612 // Type or member is obsolete
public Dictionary<string, LabelData> Labels { get; set; }
#pragma warning restore CS0612 // Type or member is obsolete
[JsonConverter(typeof(DateTimeToUnixTimeConverter))]
public DateTimeOffset Timestamp { get; set; }
[JsonConverter(typeof(KeyPathJsonConverter))]

View File

@ -1,3 +1,4 @@
using System;
using BTCPayServer.Client.JsonConverters;
using BTCPayServer.JsonConverters;
using BTCPayServer.Lightning;
@ -19,5 +20,8 @@ namespace BTCPayServer.Client.Models
[JsonConverter(typeof(LightMoneyJsonConverter))]
public LightMoney Amount { get; set; }
[JsonConverter(typeof(TimeSpanJsonConverter.Seconds))]
public TimeSpan? SendTimeout { get; set; }
}
}

View File

@ -0,0 +1,15 @@
using System;
using System.Collections.Generic;
using System.Text;
using BTCPayServer.JsonConverters;
using Newtonsoft.Json;
namespace BTCPayServer.Client.Models
{
public class PayPaymentRequestRequest
{
[JsonConverter(typeof(NumericStringJsonConverter))]
public decimal? Amount { get; set; }
public bool? AllowPendingInvoiceReuse { get; set; }
}
}

View File

@ -2,6 +2,7 @@ using System;
using BTCPayServer.JsonConverters;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
using Newtonsoft.Json.Linq;
namespace BTCPayServer.Client.Models
{
@ -29,5 +30,6 @@ namespace BTCPayServer.Client.Models
[JsonConverter(typeof(StringEnumConverter))]
public PayoutState State { get; set; }
public int Revision { get; set; }
public JObject PaymentProof { get; set; }
}
}

View File

@ -0,0 +1,25 @@
using System;
using Newtonsoft.Json;
namespace BTCPayServer.Client.Models
{
public class AppDataBase
{
public string Id { get; set; }
public string AppType { get; set; }
public string Name { get; set; }
public string StoreId { get; set; }
[JsonConverter(typeof(NBitcoin.JsonConverters.DateTimeToUnixTimeConverter))]
public DateTimeOffset Created { get; set; }
}
public class PointOfSaleAppData : AppDataBase
{
// We can add POS specific things here later
}
public class CrowdfundAppData : AppDataBase
{
// We can add Crowdfund specific things here later
}
}

View File

@ -0,0 +1,7 @@
namespace BTCPayServer.Client.Models;
public class RateSource
{
public string Id { get; set; }
public string Name { get; set; }
}

View File

@ -31,6 +31,10 @@ namespace BTCPayServer.Client.Models
public bool AnyoneCanCreateInvoice { get; set; }
public string DefaultCurrency { get; set; }
public bool RequiresRefundEmail { get; set; }
public string CheckoutFormId { get; set; }
[JsonConverter(typeof(StringEnumConverter))]
public CheckoutType CheckoutType { get; set; }
public bool LightningAmountInSatoshi { get; set; }
public bool LightningPrivateRouteHints { get; set; }
public bool OnChainWithLnInvoiceFallback { get; set; }
@ -58,12 +62,20 @@ namespace BTCPayServer.Client.Models
public NetworkFeeMode NetworkFeeMode { get; set; } = NetworkFeeMode.Never;
public bool PayJoinEnabled { get; set; }
public InvoiceData.ReceiptOptions Receipt { get; set; }
[JsonExtensionData]
public IDictionary<string, JToken> AdditionalData { get; set; }
}
public enum CheckoutType
{
V1,
V2
}
public enum NetworkFeeMode
{
MultiplePaymentsOnly,

View File

@ -0,0 +1,10 @@
namespace BTCPayServer.Client.Models
{
public class StoreRateConfiguration
{
public decimal Spread { get; set; }
public bool IsCustomScript { get; set; }
public string EffectiveScript { get; set; }
public string PreferredSource { get; set; }
}
}

View File

@ -0,0 +1,10 @@
using System.Collections.Generic;
namespace BTCPayServer.Client.Models;
public class StoreRatePreviewResult
{
public string CurrencyPair { get; set; }
public decimal? Rate { get; set; }
public List<string> Errors { get; set; }
}

View File

@ -0,0 +1,7 @@
namespace BTCPayServer.Client.Models;
public class StoreRateResult
{
public string CurrencyPair { get; set; }
public decimal Rate { get; set; }
}

View File

@ -3,7 +3,6 @@ namespace BTCPayServer.Client.Models
public enum TransactionStatus
{
Unconfirmed,
Confirmed,
Replaced
Confirmed
}
}

View File

@ -1,7 +1,3 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace BTCPayServer.Client.Models
{
public enum WebhookEventType

View File

@ -84,6 +84,10 @@ namespace BTCPayServer.Client
{
return policy.StartsWith("btcpay.server", StringComparison.OrdinalIgnoreCase);
}
public static bool IsPluginPolicy(string policy)
{
return policy.StartsWith("btcpay.plugin", StringComparison.OrdinalIgnoreCase);
}
}
public class Permission
{

View File

@ -1,28 +0,0 @@
using NBitcoin;
using NBXplorer;
namespace BTCPayServer
{
public partial class BTCPayNetworkProvider
{
public void InitMonetaryUnit()
{
var nbxplorerNetwork = NBXplorerNetworkProvider.GetFromCryptoCode("MUE");
Add(new BTCPayNetwork()
{
CryptoCode = nbxplorerNetwork.CryptoCode,
DisplayName = "MonetaryUnit",
BlockExplorerLink = NetworkType == ChainName.Mainnet ? "https://explorer.monetaryunit.org/#/MUE/mainnet/tx/{0}" : "https://explorer.monetaryunit.org/#/MUE/mainnet/tx/{0}",
NBXplorerNetwork = nbxplorerNetwork,
DefaultRateRules = new[]
{
"MUE_X = MUE_BTC * BTC_X",
"MUE_BTC = bittrex(MUE_BTC)"
},
CryptoImagePath = "imlegacy/monetaryunit.png",
DefaultSettings = BTCPayDefaultSettings.GetDefaultSettings(NetworkType),
CoinType = NetworkType == ChainName.Mainnet ? new KeyPath("31'") : new KeyPath("1'")
});
}
}
}

View File

@ -22,7 +22,7 @@ namespace BTCPayServer
"LBTC_X = LBTC_BTC * BTC_X",
"LBTC_BTC = 1",
},
BlockExplorerLink = NetworkType == ChainName.Mainnet ? "https://blockstream.info/liquid/tx/{0}" : "https://blockstream.info/testnet/liquid/tx/{0}",
BlockExplorerLink = NetworkType == ChainName.Mainnet ? "https://liquid.network/tx/{0}" : "https://liquid.network/testnet/tx/{0}",
NBXplorerNetwork = nbxplorerNetwork,
CryptoImagePath = "imlegacy/liquid.png",
DefaultSettings = BTCPayDefaultSettings.GetDefaultSettings(NetworkType),

View File

@ -21,7 +21,7 @@ namespace BTCPayServer
},
AssetId = new uint256("ce091c998b83c78bb71a632313ba3760f1763d9cfcffae02258ffa9865a37bd2"),
DisplayName = "Liquid Tether",
BlockExplorerLink = NetworkType == ChainName.Mainnet ? "https://blockstream.info/liquid/tx/{0}" : "https://blockstream.info/testnet/liquid/tx/{0}",
BlockExplorerLink = NetworkType == ChainName.Mainnet ? "https://liquid.network/tx/{0}" : "https://liquid.network/testnet/tx/{0}",
NBXplorerNetwork = nbxplorerNetwork,
CryptoImagePath = "imlegacy/liquid-tether.svg",
DefaultSettings = BTCPayDefaultSettings.GetDefaultSettings(NetworkType),
@ -44,7 +44,7 @@ namespace BTCPayServer
Divisibility = 2,
AssetId = new uint256("aa775044c32a7df391902b3659f46dfe004ccb2644ce2ddc7dba31e889391caf"),
DisplayName = "Ethiopian Birr",
BlockExplorerLink = NetworkType == ChainName.Mainnet ? "https://blockstream.info/liquid/tx/{0}" : "https://blockstream.info/testnet/liquid/tx/{0}",
BlockExplorerLink = NetworkType == ChainName.Mainnet ? "https://liquid.network/tx/{0}" : "https://liquid.network/testnet/tx/{0}",
NBXplorerNetwork = nbxplorerNetwork,
CryptoImagePath = "imlegacy/etb.png",
DefaultSettings = BTCPayDefaultSettings.GetDefaultSettings(NetworkType),
@ -66,7 +66,7 @@ namespace BTCPayServer
},
AssetId = new uint256("0e99c1a6da379d1f4151fb9df90449d40d0608f6cb33a5bcbfc8c265f42bab0a"),
DisplayName = "Liquid CAD",
BlockExplorerLink = NetworkType == ChainName.Mainnet ? "https://blockstream.info/liquid/tx/{0}" : "https://blockstream.info/testnet/liquid/tx/{0}",
BlockExplorerLink = NetworkType == ChainName.Mainnet ? "https://liquid.network/tx/{0}" : "https://liquid.network/testnet/tx/{0}",
NBXplorerNetwork = nbxplorerNetwork,
CryptoImagePath = "imlegacy/lcad.png",
DefaultSettings = BTCPayDefaultSettings.GetDefaultSettings(NetworkType),

View File

@ -137,6 +137,7 @@ namespace BTCPayServer
public string CryptoImagePath { get; set; }
public string[] DefaultRateRules { get; set; } = Array.Empty<string>();
public override string ToString()
{
return CryptoCode;

View File

@ -13,9 +13,9 @@ namespace BTCPayServer
{
CryptoCode = nbxplorerNetwork.CryptoCode,
DisplayName = "Bitcoin",
BlockExplorerLink = NetworkType == ChainName.Mainnet ? "https://blockstream.info/tx/{0}" :
NetworkType == Bitcoin.Instance.Signet.ChainName ? "https://explorer.bc-2.jp/tx/{0}"
: "https://blockstream.info/testnet/tx/{0}",
BlockExplorerLink = NetworkType == ChainName.Mainnet ? "https://mempool.space/tx/{0}" :
NetworkType == Bitcoin.Instance.Signet.ChainName ? "https://mempool.space/signet/tx/{0}"
: "https://mempool.space/testnet/tx/{0}",
NBXplorerNetwork = nbxplorerNetwork,
CryptoImagePath = "imlegacy/bitcoin.svg",
LightningImagePath = "imlegacy/bitcoin-lightning.svg",

View File

@ -58,7 +58,7 @@ namespace BTCPayServer
InitZcash();
InitChaincoin();
// InitArgoneum();//their rate source is down 9/15/20.
InitMonetaryUnit();
// InitMonetaryUnit(); Not supported from Bittrex from 11/23/2022, dead shitcoin
// Assume that electrum mappings are same as BTC if not specified
foreach (var network in _Networks.Values.OfType<BTCPayNetwork>())

View File

@ -4,7 +4,8 @@
<ItemGroup>
<FrameworkReference Include="Microsoft.AspNetCore.App" />
<PackageReference Include="NBXplorer.Client" Version="4.2.0" />
<PackageReference Include="NBXplorer.Client" Version="4.2.1" />
<PackageReference Include="NicolasDorier.StandardConfiguration" Version="1.0.0.18" />
</ItemGroup>
<ItemGroup Condition="'$(Altcoins)' != 'true'">
<Compile Remove="Altcoins\**\*.cs"></Compile>

View File

@ -180,7 +180,7 @@ namespace BTCPayServer.Logging
logBuilder.Append(": ");
var lenAfter = logBuilder.ToString().Length;
while (lenAfter++ < 18)
logBuilder.Append(" ");
logBuilder.Append(' ');
// scope information
GetScopeInformation(logBuilder);

View File

@ -106,9 +106,11 @@ namespace BTCPayServer
{
}
}
cancellationToken.ThrowIfCancellationRequested();
lock (_Queues)
{
if (_Queues.Count is 0)
return;
cancellationToken.ThrowIfCancellationRequested();
Cleanup();
}
}

View File

@ -53,12 +53,17 @@ namespace BTCPayServer.Data
public DbSet<PullPaymentData> PullPayments { get; set; }
public DbSet<RefundData> Refunds { get; set; }
public DbSet<SettingData> Settings { get; set; }
public DbSet<StoreSettingData> StoreSettings { get; set; }
public DbSet<StoreWebhookData> StoreWebhooks { get; set; }
public DbSet<StoreData> Stores { get; set; }
public DbSet<U2FDevice> U2FDevices { get; set; }
public DbSet<Fido2Credential> Fido2Credentials { get; set; }
public DbSet<UserStore> UserStore { get; set; }
[Obsolete]
public DbSet<WalletData> Wallets { get; set; }
public DbSet<WalletObjectData> WalletObjects { get; set; }
public DbSet<WalletObjectLinkData> WalletObjectLinks { get; set; }
[Obsolete]
public DbSet<WalletTransactionData> WalletTransactions { get; set; }
public DbSet<WebhookDeliveryData> WebhookDeliveries { get; set; }
public DbSet<WebhookData> Webhooks { get; set; }
@ -101,13 +106,18 @@ namespace BTCPayServer.Data
PullPaymentData.OnModelCreating(builder);
RefundData.OnModelCreating(builder);
//SettingData.OnModelCreating(builder);
StoreSettingData.OnModelCreating(builder, Database);
StoreWebhookData.OnModelCreating(builder);
//StoreData.OnModelCreating(builder);
U2FDevice.OnModelCreating(builder);
Fido2Credential.OnModelCreating(builder);
BTCPayServer.Data.UserStore.OnModelCreating(builder);
//WalletData.OnModelCreating(builder);
WalletObjectData.OnModelCreating(builder, Database);
WalletObjectLinkData.OnModelCreating(builder, Database);
#pragma warning disable CS0612 // Type or member is obsolete
WalletTransactionData.OnModelCreating(builder);
#pragma warning restore CS0612 // Type or member is obsolete
WebhookDeliveryData.OnModelCreating(builder);
LightningAddressData.OnModelCreating(builder);
PayoutProcessorData.OnModelCreating(builder);

View File

@ -3,11 +3,11 @@
<Import Project="../Build/Common.csproj" />
<ItemGroup>
<FrameworkReference Include="Microsoft.AspNetCore.App" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="6.0.1">
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="6.0.9">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.AspNetCore.Identity.EntityFrameworkCore" Version="6.0.1" />
<PackageReference Include="Microsoft.AspNetCore.Identity.EntityFrameworkCore" Version="6.0.9" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\BTCPayServer.Abstractions\BTCPayServer.Abstractions.csproj" />

View File

@ -15,7 +15,6 @@ namespace BTCPayServer.Data
public bool TagAllInvoices { get; set; }
public string Settings { get; set; }
internal static void OnModelCreating(ModelBuilder builder)
{
builder.Entity<AppData>()
@ -28,9 +27,7 @@ namespace BTCPayServer.Data
// utility methods
public T GetSettings<T>() where T : class, new()
{
if (String.IsNullOrEmpty(Settings))
return new T();
return JsonConvert.DeserializeObject<T>(Settings);
return string.IsNullOrEmpty(Settings) ? new T() : JsonConvert.DeserializeObject<T>(Settings);
}
public void SetSettings(object value)

View File

@ -19,6 +19,7 @@ public class CustodianAccountData
[MaxLength(50)]
public string CustodianCode { get; set; }
[Required]
[MaxLength(50)]
public string Name { get; set; }

View File

@ -51,12 +51,10 @@ namespace BTCPayServer.Data
var period = pp.GetPeriod(now);
if (period is { } p)
{
return p.Start <= Date && (p.End is DateTimeOffset end ? Date < end : true);
}
else
{
return false;
return p.Start <= Date && (p.End is not { } end || Date < end);
}
return false;
}
}
}

View File

@ -21,4 +21,9 @@ public class PayoutProcessorData
.HasOne(o => o.Store)
.WithMany(data => data.PayoutProcessors).OnDelete(DeleteBehavior.Cascade);
}
public override string ToString()
{
return $"{Processor} {PaymentMethod} {StoreId}";
}
}

View File

@ -47,5 +47,6 @@ namespace BTCPayServer.Data
public IEnumerable<PayoutProcessorData> PayoutProcessors { get; set; }
public IEnumerable<PayoutData> Payouts { get; set; }
public IEnumerable<CustodianAccountData> CustodianAccounts { get; set; }
public IEnumerable<StoreSettingData> Settings { get; set; }
}
}

View File

@ -0,0 +1,28 @@
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
namespace BTCPayServer.Data;
public class StoreSettingData
{
public string Name { get; set; }
public string StoreId { get; set; }
public string Value { get; set; }
public StoreData Store { get; set; }
public static void OnModelCreating(ModelBuilder builder, DatabaseFacade databaseFacade)
{
builder.Entity<StoreSettingData>().HasKey(data => new { data.StoreId, data.Name });
builder.Entity<StoreSettingData>()
.HasOne(o => o.Store)
.WithMany(o => o.Settings).OnDelete(DeleteBehavior.Cascade);
if (databaseFacade.IsNpgsql())
{
builder.Entity<StoreSettingData>()
.Property(o => o.Value)
.HasColumnType("JSONB");
}
}
}

View File

@ -1,7 +1,9 @@
using System;
using System.Collections.Generic;
namespace BTCPayServer.Data
{
[Obsolete]
public class WalletData
{
[System.ComponentModel.DataAnnotations.Key]

View File

@ -0,0 +1,87 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
namespace BTCPayServer.Data
{
public class WalletObjectData
{
public class Types
{
public const string Label = "label";
public const string Tx = "tx";
public const string Payjoin = "payjoin";
public const string Invoice = "invoice";
public const string PaymentRequest = "payment-request";
public const string App = "app";
public const string PayjoinExposed = "pj-exposed";
public const string Payout = "payout";
public const string PullPayment = "pull-payment";
}
public string WalletId { get; set; }
public string Type { get; set; }
public string Id { get; set; }
public string Data { get; set; }
public List<WalletObjectLinkData> ChildLinks { get; set; }
public List<WalletObjectLinkData> ParentLinks { get; set; }
public IEnumerable<(string type, string id, string linkdata, string objectdata)> GetLinks()
{
if (ChildLinks is not null)
foreach (var c in ChildLinks)
{
yield return (c.ChildType, c.ChildId, c.Data, c.Child?.Data);
}
if (ParentLinks is not null)
foreach (var c in ParentLinks)
{
yield return (c.ParentType, c.ParentId, c.Data, c.Parent?.Data);
}
}
public IEnumerable<WalletObjectData> GetNeighbours()
{
if (ChildLinks != null)
foreach (var c in ChildLinks)
{
if (c.Child != null)
yield return c.Child;
}
if (ParentLinks != null)
foreach (var c in ParentLinks)
{
if (c.Parent != null)
yield return c.Parent;
}
}
internal static void OnModelCreating(ModelBuilder builder, DatabaseFacade databaseFacade)
{
builder.Entity<WalletObjectData>().HasKey(o =>
new
{
o.WalletId,
o.Type,
o.Id,
});
builder.Entity<WalletObjectData>().HasIndex(o =>
new
{
o.Type,
o.Id
});
if (databaseFacade.IsNpgsql())
{
builder.Entity<WalletObjectData>()
.Property(o => o.Data)
.HasColumnType("JSONB");
}
}
}
}

View File

@ -0,0 +1,61 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
namespace BTCPayServer.Data
{
public class WalletObjectLinkData
{
public string WalletId { get; set; }
public string ParentType { get; set; }
public string ParentId { get; set; }
public string ChildType { get; set; }
public string ChildId { get; set; }
public string Data { get; set; }
public WalletObjectData Parent { get; set; }
public WalletObjectData Child { get; set; }
internal static void OnModelCreating(ModelBuilder builder, DatabaseFacade databaseFacade)
{
builder.Entity<WalletObjectLinkData>().HasKey(o =>
new
{
o.WalletId,
o.ParentType,
o.ParentId,
o.ChildType,
o.ChildId,
});
builder.Entity<WalletObjectLinkData>().HasIndex(o => new
{
o.WalletId,
o.ChildType,
o.ChildId,
});
builder.Entity<WalletObjectLinkData>()
.HasOne(o => o.Parent)
.WithMany(o => o.ChildLinks)
.HasForeignKey(o => new { o.WalletId, o.ParentType, o.ParentId })
.OnDelete(DeleteBehavior.Cascade);
builder.Entity<WalletObjectLinkData>()
.HasOne(o => o.Child)
.WithMany(o => o.ParentLinks)
.HasForeignKey(o => new { o.WalletId, o.ChildType, o.ChildId })
.OnDelete(DeleteBehavior.Cascade);
if (databaseFacade.IsNpgsql())
{
builder.Entity<WalletObjectLinkData>()
.Property(o => o.Data)
.HasColumnType("JSONB");
}
}
}
}

View File

@ -1,7 +1,9 @@
using System;
using Microsoft.EntityFrameworkCore;
namespace BTCPayServer.Data
{
[Obsolete]
public class WalletTransactionData
{
public string WalletDataId { get; set; }

View File

@ -0,0 +1,43 @@
using System;
using BTCPayServer.Data;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace BTCPayServer.Migrations
{
[DbContext(typeof(ApplicationDbContext))]
[Migration("20220610090843_AddSettingsToStore")]
public partial class AddSettingsToStore : Migration
{
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.CreateTable(
name: "StoreSettings",
columns: table => new
{
Name = table.Column<string>(type: "TEXT", nullable: false),
StoreId = table.Column<string>(type: "TEXT", nullable: false),
Value = table.Column<string>(type: migrationBuilder.IsNpgsql() ? "JSONB" : "TEXT", nullable: true)
},
constraints: table =>
{
table.PrimaryKey("PK_StoreSettings", x => new { x.StoreId, x.Name });
table.ForeignKey(
name: "FK_StoreSettings_Stores_StoreId",
column: x => x.StoreId,
principalTable: "Stores",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
});
}
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropTable(
name: "StoreSettings");
}
}
}

View File

@ -0,0 +1,81 @@
// <auto-generated />
using System;
using BTCPayServer.Data;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
#nullable disable
namespace BTCPayServer.Migrations
{
[DbContext(typeof(ApplicationDbContext))]
[Migration("20220929132704_label")]
public partial class label : Migration
{
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.CreateTable(
name: "WalletObjects",
columns: table => new
{
WalletId = table.Column<string>(type: "TEXT", nullable: false),
Type = table.Column<string>(type: "TEXT", nullable: false),
Id = table.Column<string>(type: "TEXT", nullable: false),
Data = table.Column<string>(type: migrationBuilder.IsNpgsql() ? "JSONB" : "TEXT", nullable: true)
},
constraints: table =>
{
table.PrimaryKey("PK_WalletObjects", x => new { x.WalletId, x.Type, x.Id });
});
migrationBuilder.CreateIndex(
name: "IX_WalletObjects_Type_Id",
table: "WalletObjects",
columns: new[] { "Type", "Id" });
migrationBuilder.CreateTable(
name: "WalletObjectLinks",
columns: table => new
{
WalletId = table.Column<string>(type: "TEXT", nullable: false),
ParentType = table.Column<string>(type: "TEXT", nullable: false),
ParentId = table.Column<string>(type: "TEXT", nullable: false),
ChildType = table.Column<string>(type: "TEXT", nullable: false),
ChildId = table.Column<string>(type: "TEXT", nullable: false),
Data = table.Column<string>(type: migrationBuilder.IsNpgsql() ? "JSONB" : "TEXT", nullable: true)
},
constraints: table =>
{
table.PrimaryKey("PK_WalletObjectLinks", x => new { x.WalletId, x.ParentType, x.ParentId, x.ChildType, x.ChildId });
table.ForeignKey(
name: "FK_WalletObjectLinks_WalletObjects_WalletId_ChildType_ChildId",
columns: x => new { x.WalletId, x.ChildType, x.ChildId },
principalTable: "WalletObjects",
principalColumns: new[] { "WalletId", "Type", "Id" },
onDelete: ReferentialAction.Cascade);
table.ForeignKey(
name: "FK_WalletObjectLinks_WalletObjects_WalletId_ParentType_ParentId",
columns: x => new { x.WalletId, x.ParentType, x.ParentId },
principalTable: "WalletObjects",
principalColumns: new[] { "WalletId", "Type", "Id" },
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.CreateIndex(
name: "IX_WalletObjectLinks_WalletId_ChildType_ChildId",
table: "WalletObjectLinks",
columns: new[] { "WalletId", "ChildType", "ChildId" });
}
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropTable(
name: "WalletObjectLinks");
migrationBuilder.DropTable(
name: "WalletObjects");
}
}
}

View File

@ -16,7 +16,7 @@ namespace BTCPayServer.Migrations
protected override void BuildModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder.HasAnnotation("ProductVersion", "6.0.1");
modelBuilder.HasAnnotation("ProductVersion", "6.0.9");
modelBuilder.Entity("BTCPayServer.Data.AddressInvoiceData", b =>
{
@ -189,6 +189,7 @@ namespace BTCPayServer.Migrations
.HasColumnType("TEXT");
b.Property<string>("Name")
.IsRequired()
.HasMaxLength(50)
.HasColumnType("TEXT");
@ -746,6 +747,22 @@ namespace BTCPayServer.Migrations
b.ToTable("Files");
});
modelBuilder.Entity("BTCPayServer.Data.StoreSettingData", b =>
{
b.Property<string>("StoreId")
.HasColumnType("TEXT");
b.Property<string>("Name")
.HasColumnType("TEXT");
b.Property<string>("Value")
.HasColumnType("TEXT");
b.HasKey("StoreId", "Name");
b.ToTable("StoreSettings");
});
modelBuilder.Entity("BTCPayServer.Data.StoreWebhookData", b =>
{
b.Property<string>("StoreId")
@ -829,6 +846,54 @@ namespace BTCPayServer.Migrations
b.ToTable("Wallets");
});
modelBuilder.Entity("BTCPayServer.Data.WalletObjectData", b =>
{
b.Property<string>("WalletId")
.HasColumnType("TEXT");
b.Property<string>("Type")
.HasColumnType("TEXT");
b.Property<string>("Id")
.HasColumnType("TEXT");
b.Property<string>("Data")
.HasColumnType("TEXT");
b.HasKey("WalletId", "Type", "Id");
b.HasIndex("Type", "Id");
b.ToTable("WalletObjects");
});
modelBuilder.Entity("BTCPayServer.Data.WalletObjectLinkData", b =>
{
b.Property<string>("WalletId")
.HasColumnType("TEXT");
b.Property<string>("ParentType")
.HasColumnType("TEXT");
b.Property<string>("ParentId")
.HasColumnType("TEXT");
b.Property<string>("ChildType")
.HasColumnType("TEXT");
b.Property<string>("ChildId")
.HasColumnType("TEXT");
b.Property<string>("Data")
.HasColumnType("TEXT");
b.HasKey("WalletId", "ParentType", "ParentId", "ChildType", "ChildId");
b.HasIndex("WalletId", "ChildType", "ChildId");
b.ToTable("WalletObjectLinks");
});
modelBuilder.Entity("BTCPayServer.Data.WalletTransactionData", b =>
{
b.Property<string>("WalletDataId")
@ -1258,6 +1323,17 @@ namespace BTCPayServer.Migrations
b.Navigation("ApplicationUser");
});
modelBuilder.Entity("BTCPayServer.Data.StoreSettingData", b =>
{
b.HasOne("BTCPayServer.Data.StoreData", "Store")
.WithMany("Settings")
.HasForeignKey("StoreId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Store");
});
modelBuilder.Entity("BTCPayServer.Data.StoreWebhookData", b =>
{
b.HasOne("BTCPayServer.Data.StoreData", "Store")
@ -1306,6 +1382,25 @@ namespace BTCPayServer.Migrations
b.Navigation("StoreData");
});
modelBuilder.Entity("BTCPayServer.Data.WalletObjectLinkData", b =>
{
b.HasOne("BTCPayServer.Data.WalletObjectData", "Child")
.WithMany("ParentLinks")
.HasForeignKey("WalletId", "ChildType", "ChildId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("BTCPayServer.Data.WalletObjectData", "Parent")
.WithMany("ChildLinks")
.HasForeignKey("WalletId", "ParentType", "ParentId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Child");
b.Navigation("Parent");
});
modelBuilder.Entity("BTCPayServer.Data.WalletTransactionData", b =>
{
b.HasOne("BTCPayServer.Data.WalletData", "WalletData")
@ -1438,6 +1533,8 @@ namespace BTCPayServer.Migrations
b.Navigation("PullPayments");
b.Navigation("Settings");
b.Navigation("UserStores");
});
@ -1446,6 +1543,13 @@ namespace BTCPayServer.Migrations
b.Navigation("WalletTransactions");
});
modelBuilder.Entity("BTCPayServer.Data.WalletObjectData", b =>
{
b.Navigation("ChildLinks");
b.Navigation("ParentLinks");
});
modelBuilder.Entity("BTCPayServer.Data.WebhookData", b =>
{
b.Navigation("Deliveries");

View File

@ -26,6 +26,7 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="McMaster.NETCore.Plugins.Mvc" Version="1.4.0" />
<ProjectReference Include="..\BTCPayServer.Abstractions\BTCPayServer.Abstractions.csproj" />
<None Include="icon.png" Pack="true" PackagePath="\" />
</ItemGroup>

View File

@ -8,6 +8,7 @@ using System.Text;
using System.Text.Json;
using System.Threading.Tasks;
using BTCPayServer.Abstractions.Contracts;
using McMaster.NETCore.Plugins;
using NBitcoin.Crypto;
using NBitcoin.DataEncoders;
using NBitcoin.Secp256k1;
@ -33,7 +34,8 @@ namespace BTCPayServer.PluginPacker
throw new Exception($"{rootDLLPath} could not be found");
}
var assembly = Assembly.LoadFrom(rootDLLPath);
var plugin = PluginLoader.CreateFromAssemblyFile(rootDLLPath, false, new[] { typeof(IBTCPayServerPlugin) });
var assembly = plugin.LoadAssembly(name);
var extension = GetAllExtensionTypesFromAssembly(assembly).FirstOrDefault();
if (extension is null)
{
@ -66,31 +68,45 @@ namespace BTCPayServer.PluginPacker
File.Delete(sha256dirs);
}
await File.WriteAllTextAsync(sha256dirs, sha256sums.ToString());
// try Windows executable first, fall back to macOS/Linux PowerShell
try
{
Process cmd = new();
cmd.StartInfo.FileName = "powershell.exe";
cmd.StartInfo.RedirectStandardInput = true;
cmd.StartInfo.RedirectStandardOutput = true;
cmd.StartInfo.CreateNoWindow = false;
cmd.StartInfo.UseShellExecute = false;
cmd.Start();
await cmd.StandardInput.WriteLineAsync($"cat {sha256dirs} | gpg -s > {Path.Combine(outputDir, "SHA256SUMS.asc")}");
await cmd.StandardInput.FlushAsync();
cmd.StandardInput.Close();
await cmd.WaitForExitAsync();
Console.WriteLine(await cmd.StandardOutput.ReadToEndAsync());
await CreateShasums("powershell.exe", sha256dirs, outputDir);
}
catch (Exception e)
catch (Exception)
{
Console.WriteLine($"Attempted to sign hashes with gpg but maybe powershell is not installed?\n{e.Message}");
try
{
await CreateShasums("bash", sha256dirs, outputDir);
}
catch (Exception ex)
{
Console.WriteLine(
$"Attempted to sign hashes with gpg but maybe powershell is not installed?\n{ex.Message}");
}
}
Console.WriteLine($"Created {outputFile}.btcpay at {directory}");
}
private static async Task CreateShasums(string exec, string sha256dirs, string outputDir)
{
Process cmd = new();
cmd.StartInfo.FileName = exec;
cmd.StartInfo.RedirectStandardInput = true;
cmd.StartInfo.RedirectStandardOutput = true;
cmd.StartInfo.CreateNoWindow = false;
cmd.StartInfo.UseShellExecute = false;
cmd.Start();
await cmd.StandardInput.WriteLineAsync($"cat {sha256dirs} | gpg -s > {Path.Combine(outputDir, "SHA256SUMS.asc")}");
await cmd.StandardInput.FlushAsync();
cmd.StandardInput.Close();
await cmd.WaitForExitAsync();
Console.WriteLine(await cmd.StandardOutput.ReadToEndAsync());
}
private static Type[] GetAllExtensionTypesFromAssembly(Assembly assembly)
{
return assembly.GetTypes().Where(type =>

View File

@ -13,7 +13,7 @@
<EmbeddedResource Include="Resources\**" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="6.0.1">
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="6.0.9">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>

View File

@ -19,6 +19,7 @@ namespace BTCPayServer.Plugins.Test
{
services.AddSingleton<IUIExtension>(new UIExtension("TestExtensionNavExtension", "header-nav"));
services.AddHostedService<ApplicationPartsLogger>();
services.AddHostedService<TestPluginMigrationRunner>();
services.AddSingleton<TestPluginService>();
services.AddSingleton<TestPluginDbContextFactory>();
services.AddDbContext<TestPluginDbContext>((provider, o) =>
@ -27,13 +28,5 @@ namespace BTCPayServer.Plugins.Test
factory.ConfigureBuilder(o);
});
}
public override void Execute(IApplicationBuilder applicationBuilder, IServiceProvider applicationBuilderApplicationServices)
{
base.Execute(applicationBuilder, applicationBuilderApplicationServices);
applicationBuilderApplicationServices.GetService<TestPluginDbContextFactory>().CreateContext().Database.Migrate();
applicationBuilderApplicationServices.GetService<TestPluginService>().AddTestDataRecord().GetAwaiter().GetResult();
}
}
}

View File

@ -0,0 +1,45 @@
using System.Threading;
using System.Threading.Tasks;
using BTCPayServer.Abstractions.Contracts;
using BTCPayServer.Plugins.Test.Services;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Hosting;
namespace BTCPayServer.Plugins.Test;
public class TestPluginMigrationRunner:IHostedService
{
public class TestPluginDataMigrationHistory
{
public bool UpdatedSomething { get; set; }
}
private readonly TestPluginDbContextFactory _testPluginDbContextFactory;
private readonly ISettingsRepository _settingsRepository;
private readonly TestPluginService _testPluginService;
public TestPluginMigrationRunner(TestPluginDbContextFactory testPluginDbContextFactory, ISettingsRepository settingsRepository, TestPluginService testPluginService)
{
_testPluginDbContextFactory = testPluginDbContextFactory;
_settingsRepository = settingsRepository;
_testPluginService = testPluginService;
}
public async Task StartAsync(CancellationToken cancellationToken)
{
var settings = await _settingsRepository.GetSettingAsync<TestPluginDataMigrationHistory>() ??
new TestPluginDataMigrationHistory();
await using var ctx = _testPluginDbContextFactory.CreateContext();
await ctx.Database.MigrateAsync(cancellationToken: cancellationToken);
if (!settings.UpdatedSomething)
{
await _testPluginService.AddTestDataRecord();
settings.UpdatedSomething = true;
await _settingsRepository.UpdateSetting(settings);
}
}
public Task StopAsync(CancellationToken cancellationToken)
{
return Task.CompletedTask;
}
}

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