Compare commits
1 Commits
multisig-s
...
fix-array-
Author | SHA1 | Date | |
---|---|---|---|
|
8290a1606f |
@@ -2,7 +2,7 @@ version: 2
|
|||||||
jobs:
|
jobs:
|
||||||
fast_tests:
|
fast_tests:
|
||||||
machine:
|
machine:
|
||||||
image: ubuntu-2004:2024.11.1
|
image: ubuntu-2004:202111-02
|
||||||
steps:
|
steps:
|
||||||
- checkout
|
- checkout
|
||||||
- run:
|
- run:
|
||||||
@@ -10,7 +10,7 @@ jobs:
|
|||||||
cd .circleci && ./run-tests.sh "Fast=Fast|ThirdParty=ThirdParty" && ./can-build.sh
|
cd .circleci && ./run-tests.sh "Fast=Fast|ThirdParty=ThirdParty" && ./can-build.sh
|
||||||
selenium_tests:
|
selenium_tests:
|
||||||
machine:
|
machine:
|
||||||
image: ubuntu-2004:2024.11.1
|
image: ubuntu-2004:202111-02
|
||||||
steps:
|
steps:
|
||||||
- checkout
|
- checkout
|
||||||
- run:
|
- run:
|
||||||
@@ -18,7 +18,7 @@ jobs:
|
|||||||
cd .circleci && ./run-tests.sh "Selenium=Selenium"
|
cd .circleci && ./run-tests.sh "Selenium=Selenium"
|
||||||
integration_tests:
|
integration_tests:
|
||||||
machine:
|
machine:
|
||||||
image: ubuntu-2004:2024.11.1
|
image: ubuntu-2004:202111-02
|
||||||
steps:
|
steps:
|
||||||
- checkout
|
- checkout
|
||||||
- run:
|
- run:
|
||||||
@@ -26,27 +26,84 @@ jobs:
|
|||||||
cd .circleci && ./run-tests.sh "Integration=Integration"
|
cd .circleci && ./run-tests.sh "Integration=Integration"
|
||||||
trigger_docs_build:
|
trigger_docs_build:
|
||||||
machine:
|
machine:
|
||||||
image: ubuntu-2004:2024.11.1
|
image: ubuntu-2004:202111-02
|
||||||
steps:
|
steps:
|
||||||
- run:
|
- run:
|
||||||
command: |
|
command: |
|
||||||
curl -X POST -H "Authorization: token $GH_PAT" -H "Accept: application/vnd.github.everest-preview+json" -H "Content-Type: application/json" https://api.github.com/repos/btcpayserver/btcpayserver-doc/dispatches --data '{"event_type": "build_docs"}'
|
curl -X POST -H "Authorization: token $GH_PAT" -H "Accept: application/vnd.github.everest-preview+json" -H "Content-Type: application/json" https://api.github.com/repos/btcpayserver/btcpayserver-doc/dispatches --data '{"event_type": "build_docs"}'
|
||||||
|
|
||||||
# publish jobs require $DOCKERHUB_REPO, $DOCKERHUB_USER, $DOCKERHUB_PASS defined
|
# publish jobs require $DOCKERHUB_REPO, $DOCKERHUB_USER, $DOCKERHUB_PASS defined
|
||||||
docker:
|
amd64:
|
||||||
docker:
|
machine:
|
||||||
- image: cimg/base:stable
|
image: ubuntu-2004:202111-02
|
||||||
steps:
|
steps:
|
||||||
- setup_remote_docker
|
|
||||||
- checkout
|
- checkout
|
||||||
- run:
|
- run:
|
||||||
command: |
|
command: |
|
||||||
LATEST_TAG=${CIRCLE_TAG:1} #trim v from tag
|
LATEST_TAG=${CIRCLE_TAG:1} #trim v from tag
|
||||||
GIT_COMMIT=$(git rev-parse HEAD)
|
GIT_COMMIT=$(git rev-parse HEAD)
|
||||||
#
|
#
|
||||||
docker login --username=$DOCKERHUB_USER --password=$DOCKERHUB_PASS
|
sudo docker build --build-arg GIT_COMMIT=${GIT_COMMIT} --pull -t $DOCKERHUB_REPO:$LATEST_TAG-amd64 -f amd64.Dockerfile .
|
||||||
docker buildx create --use
|
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 .
|
||||||
DOCKER_BUILDX_OPTS="--platform linux/amd64,linux/arm64,linux/arm/v7 --build-arg GIT_COMMIT=${GIT_COMMIT} --push"
|
sudo docker login --username=$DOCKERHUB_USER --password=$DOCKERHUB_PASS
|
||||||
docker buildx build $DOCKER_BUILDX_OPTS -t $DOCKERHUB_REPO:$LATEST_TAG .
|
sudo docker push $DOCKERHUB_REPO:$LATEST_TAG-amd64
|
||||||
|
sudo docker push $DOCKERHUB_REPO:$LATEST_TAG-altcoins-amd64
|
||||||
|
|
||||||
|
arm32v7:
|
||||||
|
machine:
|
||||||
|
image: ubuntu-2004:202111-02
|
||||||
|
steps:
|
||||||
|
- checkout
|
||||||
|
- run:
|
||||||
|
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 --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
|
||||||
|
|
||||||
|
arm64v8:
|
||||||
|
machine:
|
||||||
|
image: ubuntu-2004:202111-02
|
||||||
|
steps:
|
||||||
|
- checkout
|
||||||
|
- run:
|
||||||
|
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 --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
|
||||||
|
|
||||||
|
multiarch:
|
||||||
|
machine:
|
||||||
|
image: ubuntu-2004:202201-02
|
||||||
|
steps:
|
||||||
|
- run:
|
||||||
|
command: |
|
||||||
|
sudo docker login --username=$DOCKERHUB_USER --password=$DOCKERHUB_PASS
|
||||||
|
#
|
||||||
|
LATEST_TAG=${CIRCLE_TAG:1} #trim v from tag
|
||||||
|
sudo docker manifest create --amend $DOCKERHUB_REPO:$LATEST_TAG $DOCKERHUB_REPO:$LATEST_TAG-amd64 $DOCKERHUB_REPO:$LATEST_TAG-arm32v7 $DOCKERHUB_REPO:$LATEST_TAG-arm64v8
|
||||||
|
sudo docker manifest annotate $DOCKERHUB_REPO:$LATEST_TAG $DOCKERHUB_REPO:$LATEST_TAG-amd64 --os linux --arch amd64
|
||||||
|
sudo docker manifest annotate $DOCKERHUB_REPO:$LATEST_TAG $DOCKERHUB_REPO:$LATEST_TAG-arm32v7 --os linux --arch arm --variant v7
|
||||||
|
sudo docker manifest annotate $DOCKERHUB_REPO:$LATEST_TAG $DOCKERHUB_REPO:$LATEST_TAG-arm64v8 --os linux --arch arm64 --variant v8
|
||||||
|
sudo docker manifest push $DOCKERHUB_REPO:$LATEST_TAG -p
|
||||||
|
|
||||||
|
sudo docker manifest create --amend $DOCKERHUB_REPO:$LATEST_TAG-altcoins $DOCKERHUB_REPO:$LATEST_TAG-altcoins-amd64 $DOCKERHUB_REPO:$LATEST_TAG-altcoins-arm32v7 $DOCKERHUB_REPO:$LATEST_TAG-altcoins-arm64v8
|
||||||
|
sudo docker manifest annotate $DOCKERHUB_REPO:$LATEST_TAG-altcoins $DOCKERHUB_REPO:$LATEST_TAG-altcoins-amd64 --os linux --arch amd64
|
||||||
|
sudo docker manifest annotate $DOCKERHUB_REPO:$LATEST_TAG-altcoins $DOCKERHUB_REPO:$LATEST_TAG-altcoins-arm32v7 --os linux --arch arm --variant v7
|
||||||
|
sudo docker manifest annotate $DOCKERHUB_REPO:$LATEST_TAG-altcoins $DOCKERHUB_REPO:$LATEST_TAG-altcoins-arm64v8 --os linux --arch arm64 --variant v8
|
||||||
|
sudo docker manifest push $DOCKERHUB_REPO:$LATEST_TAG-altcoins -p
|
||||||
|
|
||||||
workflows:
|
workflows:
|
||||||
version: 2
|
version: 2
|
||||||
build_and_test:
|
build_and_test:
|
||||||
@@ -63,7 +120,7 @@ workflows:
|
|||||||
# only act on version tags
|
# only act on version tags
|
||||||
tags:
|
tags:
|
||||||
only: /(v[1-9]+(\.[0-9]+)*(-[a-z0-9-]+)?)|(v[a-z0-9-]+)/
|
only: /(v[1-9]+(\.[0-9]+)*(-[a-z0-9-]+)?)|(v[a-z0-9-]+)/
|
||||||
- docker:
|
- amd64:
|
||||||
filters:
|
filters:
|
||||||
# ignore any commit on any branch by default
|
# ignore any commit on any branch by default
|
||||||
branches:
|
branches:
|
||||||
@@ -73,3 +130,25 @@ workflows:
|
|||||||
# OR features on specific versions like v1.0.0.88-lndseedbackup-1
|
# OR features on specific versions like v1.0.0.88-lndseedbackup-1
|
||||||
tags:
|
tags:
|
||||||
only: /(v[1-9]+(\.[0-9]+)*(-[a-z0-9-]+)?)|(v[a-z0-9-]+)/
|
only: /(v[1-9]+(\.[0-9]+)*(-[a-z0-9-]+)?)|(v[a-z0-9-]+)/
|
||||||
|
- arm32v7:
|
||||||
|
filters:
|
||||||
|
branches:
|
||||||
|
ignore: /.*/
|
||||||
|
tags:
|
||||||
|
only: /(v[1-9]+(\.[0-9]+)*(-[a-z0-9-]+)?)|(v[a-z0-9-]+)/
|
||||||
|
- arm64v8:
|
||||||
|
filters:
|
||||||
|
branches:
|
||||||
|
ignore: /.*/
|
||||||
|
tags:
|
||||||
|
only: /(v[1-9]+(\.[0-9]+)*(-[a-z0-9-]+)?)|(v[a-z0-9-]+)/
|
||||||
|
- multiarch:
|
||||||
|
requires:
|
||||||
|
- amd64
|
||||||
|
- arm32v7
|
||||||
|
- arm64v8
|
||||||
|
filters:
|
||||||
|
branches:
|
||||||
|
ignore: /.*/
|
||||||
|
tags:
|
||||||
|
only: /(v[1-9]+(\.[0-9]+)*(-[a-z0-9-]+)?)|(v[a-z0-9-]+)/
|
||||||
|
@@ -2,8 +2,8 @@
|
|||||||
set -e
|
set -e
|
||||||
|
|
||||||
cd ../BTCPayServer.Tests
|
cd ../BTCPayServer.Tests
|
||||||
docker-compose --version
|
docker-compose -v
|
||||||
docker-compose -f "docker-compose.altcoins.yml" down -v
|
docker-compose -f "docker-compose.altcoins.yml" down --v
|
||||||
|
|
||||||
# For some reason, docker-compose pull fails time to time, so we try several times
|
# For some reason, docker-compose pull fails time to time, so we try several times
|
||||||
n=0
|
n=0
|
||||||
|
2
.github/ISSUE_TEMPLATE/bug_report.yml
vendored
2
.github/ISSUE_TEMPLATE/bug_report.yml
vendored
@@ -62,7 +62,7 @@ body:
|
|||||||
id: terms
|
id: terms
|
||||||
attributes:
|
attributes:
|
||||||
label: Are you sure this is a bug report?
|
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) Beware of scammers we will never direct you to third-party sites for support or ask for sensitive information your private key especially. Ignore any bots and scammers replies to GitHub issues claiming to be support agents
|
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:
|
options:
|
||||||
- label: I confirm this is a bug report
|
- label: I confirm this is a bug report
|
||||||
required: true
|
required: true
|
||||||
|
2
.github/codeql/codeql-config.yml
vendored
2
.github/codeql/codeql-config.yml
vendored
@@ -1,2 +0,0 @@
|
|||||||
paths-ignore:
|
|
||||||
- 'BTCPayServer/wwwroot/vendor/**/*.js'
|
|
80
.github/workflows/codeql.yml
vendored
80
.github/workflows/codeql.yml
vendored
@@ -1,80 +0,0 @@
|
|||||||
# For most projects, this workflow file will not need changing; you simply need
|
|
||||||
# to commit it to your repository.
|
|
||||||
#
|
|
||||||
# You may wish to alter this file to override the set of languages analyzed,
|
|
||||||
# or to provide custom queries or build logic.
|
|
||||||
#
|
|
||||||
# ******** NOTE ********
|
|
||||||
# We have attempted to detect the languages in your repository. Please check
|
|
||||||
# the `language` matrix defined below to confirm you have the correct set of
|
|
||||||
# supported CodeQL languages.
|
|
||||||
#
|
|
||||||
name: "CodeQL"
|
|
||||||
|
|
||||||
on:
|
|
||||||
# Allow running tests manually. Usefull if scan failure, or need to rescan before next scheduled date.
|
|
||||||
workflow_dispatch:
|
|
||||||
# We scan only on a schedule for now, can uncomment the following to scan on commit or PR merge later on if deemed appropriate.
|
|
||||||
# push:
|
|
||||||
# branches: [ "master" ]
|
|
||||||
# pull_request:
|
|
||||||
# branches: [ "master" ]
|
|
||||||
schedule:
|
|
||||||
# Scan every Monday 06:00 UTC.
|
|
||||||
- cron: '0 6 * * 1'
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
analyze:
|
|
||||||
name: Analyze
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
permissions:
|
|
||||||
actions: read
|
|
||||||
contents: read
|
|
||||||
security-events: write
|
|
||||||
|
|
||||||
strategy:
|
|
||||||
fail-fast: false
|
|
||||||
matrix:
|
|
||||||
language: [ 'javascript', 'csharp' ]
|
|
||||||
# CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python', 'ruby' ]
|
|
||||||
# Use only 'java' to analyze code written in Java, Kotlin or both
|
|
||||||
# Use only 'javascript' to analyze code written in JavaScript, TypeScript or both
|
|
||||||
# Learn more about CodeQL language support at https://aka.ms/codeql-docs/language-support
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- name: Checkout repository
|
|
||||||
uses: actions/checkout@v3
|
|
||||||
|
|
||||||
# Initializes the CodeQL tools for scanning.
|
|
||||||
- name: Initialize CodeQL
|
|
||||||
uses: github/codeql-action/init@v2
|
|
||||||
with:
|
|
||||||
languages: ${{ matrix.language }}
|
|
||||||
config-file: ./.github/codeql/codeql-config.yml
|
|
||||||
# If you wish to specify custom queries, you can do so here or in a config file.
|
|
||||||
# By default, queries listed here will override any specified in a config file.
|
|
||||||
# Prefix the list here with "+" to use these queries and those in the config file.
|
|
||||||
|
|
||||||
# Details on CodeQL's query packs refer to : https://docs.github.com/en/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-code-scanning#using-queries-in-ql-packs
|
|
||||||
# queries: security-extended,security-and-quality
|
|
||||||
|
|
||||||
|
|
||||||
# Autobuild attempts to build any compiled languages (C/C++, C#, Go, or Java).
|
|
||||||
# If this step fails, then you should remove it and run the build manually (see below)
|
|
||||||
- name: Autobuild
|
|
||||||
uses: github/codeql-action/autobuild@v2
|
|
||||||
|
|
||||||
# ℹ️ Command-line programs to run using the OS shell.
|
|
||||||
# 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun
|
|
||||||
|
|
||||||
# If the Autobuild fails above, remove it and uncomment the following three lines.
|
|
||||||
# modify them (or add more) to build your code if your project, please refer to the EXAMPLE below for guidance.
|
|
||||||
|
|
||||||
# - run: |
|
|
||||||
# echo "Run, Build Application using script"
|
|
||||||
# ./location_of_script_within_repo/buildscript.sh
|
|
||||||
|
|
||||||
- name: Perform CodeQL Analysis
|
|
||||||
uses: github/codeql-action/analyze@v2
|
|
||||||
with:
|
|
||||||
category: "/language:${{matrix.language}}"
|
|
5
.gitignore
vendored
5
.gitignore
vendored
@@ -266,7 +266,6 @@ paket-files/
|
|||||||
# JetBrains Rider
|
# JetBrains Rider
|
||||||
.idea/
|
.idea/
|
||||||
*.sln.iml
|
*.sln.iml
|
||||||
.run
|
|
||||||
|
|
||||||
# CodeRush
|
# CodeRush
|
||||||
.cr/
|
.cr/
|
||||||
@@ -299,6 +298,4 @@ Packed Plugins
|
|||||||
Plugins/packed
|
Plugins/packed
|
||||||
|
|
||||||
BTCPayServer/wwwroot/swagger/v1/openapi.json
|
BTCPayServer/wwwroot/swagger/v1/openapi.json
|
||||||
BTCPayServer/appsettings.dev.json
|
BTCPayServer/appsettings.dev.json
|
||||||
BTCPayServer.Tests/monero_wallet
|
|
||||||
/BTCPayServer.Tests/NewBlocks.bat
|
|
2
.vscode/launch.json
vendored
2
.vscode/launch.json
vendored
@@ -10,7 +10,7 @@
|
|||||||
"request": "launch",
|
"request": "launch",
|
||||||
"preLaunchTask": "build",
|
"preLaunchTask": "build",
|
||||||
// If you have changed target frameworks, make sure to update the program path.
|
// If you have changed target frameworks, make sure to update the program path.
|
||||||
"program": "${workspaceFolder}/BTCPayServer/bin/Debug/net8.0/BTCPayServer.dll",
|
"program": "${workspaceFolder}/BTCPayServer/bin/Debug/net6.0/BTCPayServer.dll",
|
||||||
"args": [],
|
"args": [],
|
||||||
"cwd": "${workspaceFolder}/BTCPayServer",
|
"cwd": "${workspaceFolder}/BTCPayServer",
|
||||||
"stopAtEntry": false,
|
"stopAtEntry": false,
|
||||||
|
@@ -31,9 +31,11 @@
|
|||||||
<None Include="icon.png" Pack="true" PackagePath="\" />
|
<None Include="icon.png" Pack="true" PackagePath="\" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="HtmlSanitizer" Version="8.0.838" />
|
<PackageReference Include="HtmlSanitizer" Version="5.0.372" />
|
||||||
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="8.0.11" />
|
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="6.0.9" />
|
||||||
<PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="8.0.11" />
|
<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>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ProjectReference Include="..\BTCPayServer.Client\BTCPayServer.Client.csproj" />
|
<ProjectReference Include="..\BTCPayServer.Client\BTCPayServer.Client.csproj" />
|
||||||
|
@@ -9,7 +9,6 @@ namespace BTCPayServer.Configuration
|
|||||||
public string TempStorageDir { get; set; }
|
public string TempStorageDir { get; set; }
|
||||||
public string StorageDir { get; set; }
|
public string StorageDir { get; set; }
|
||||||
public string TempDir { get; set; }
|
public string TempDir { get; set; }
|
||||||
public string LangsDir { get; set; }
|
|
||||||
|
|
||||||
public string ToDatadirFullPath(string path)
|
public string ToDatadirFullPath(string path)
|
||||||
{
|
{
|
||||||
|
@@ -4,8 +4,6 @@ using Microsoft.EntityFrameworkCore;
|
|||||||
using Microsoft.EntityFrameworkCore.Metadata;
|
using Microsoft.EntityFrameworkCore.Metadata;
|
||||||
using Microsoft.EntityFrameworkCore.Migrations;
|
using Microsoft.EntityFrameworkCore.Migrations;
|
||||||
using Microsoft.Extensions.Options;
|
using Microsoft.Extensions.Options;
|
||||||
using Npgsql;
|
|
||||||
using Npgsql.EntityFrameworkCore.PostgreSQL.Infrastructure;
|
|
||||||
using Npgsql.EntityFrameworkCore.PostgreSQL.Migrations;
|
using Npgsql.EntityFrameworkCore.PostgreSQL.Migrations;
|
||||||
using Npgsql.EntityFrameworkCore.PostgreSQL.Migrations.Operations;
|
using Npgsql.EntityFrameworkCore.PostgreSQL.Migrations.Operations;
|
||||||
|
|
||||||
@@ -14,16 +12,16 @@ namespace BTCPayServer.Abstractions.Contracts
|
|||||||
public abstract class BaseDbContextFactory<T> where T : DbContext
|
public abstract class BaseDbContextFactory<T> where T : DbContext
|
||||||
{
|
{
|
||||||
private readonly IOptions<DatabaseOptions> _options;
|
private readonly IOptions<DatabaseOptions> _options;
|
||||||
private readonly string _migrationTableName;
|
private readonly string _schemaPrefix;
|
||||||
|
|
||||||
public BaseDbContextFactory(IOptions<DatabaseOptions> options, string migrationTableName)
|
public BaseDbContextFactory(IOptions<DatabaseOptions> options, string schemaPrefix)
|
||||||
{
|
{
|
||||||
_options = options;
|
_options = options;
|
||||||
_migrationTableName = migrationTableName;
|
_schemaPrefix = schemaPrefix;
|
||||||
}
|
}
|
||||||
|
|
||||||
public T CreateContext() => CreateContext(null);
|
public abstract T CreateContext();
|
||||||
public abstract T CreateContext(Action<NpgsqlDbContextOptionsBuilder> npgsqlOptionsAction = null);
|
|
||||||
class CustomNpgsqlMigrationsSqlGenerator : NpgsqlMigrationsSqlGenerator
|
class CustomNpgsqlMigrationsSqlGenerator : NpgsqlMigrationsSqlGenerator
|
||||||
{
|
{
|
||||||
#pragma warning disable EF1001 // Internal EF Core API usage.
|
#pragma warning disable EF1001 // Internal EF Core API usage.
|
||||||
@@ -68,27 +66,46 @@ namespace BTCPayServer.Abstractions.Contracts
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ConfigureBuilder(DbContextOptionsBuilder builder) => ConfigureBuilder(builder, null);
|
public void ConfigureBuilder(DbContextOptionsBuilder builder)
|
||||||
public void ConfigureBuilder(DbContextOptionsBuilder builder, Action<NpgsqlDbContextOptionsBuilder> npgsqlOptionsAction = null)
|
|
||||||
{
|
{
|
||||||
builder
|
switch (_options.Value.DatabaseType)
|
||||||
.UseNpgsql(_options.Value.ConnectionString, o =>
|
|
||||||
{
|
{
|
||||||
o.EnableRetryOnFailure(10);
|
case DatabaseType.Sqlite:
|
||||||
o.SetPostgresVersion(12, 0);
|
builder.UseSqlite(_options.Value.ConnectionString, o =>
|
||||||
npgsqlOptionsAction?.Invoke(o);
|
{
|
||||||
var mainSearchPath = GetSearchPath(_options.Value.ConnectionString);
|
if (!string.IsNullOrEmpty(_schemaPrefix))
|
||||||
var schemaPrefix = string.IsNullOrEmpty(_migrationTableName) ? "__EFMigrationsHistory" : _migrationTableName;
|
{
|
||||||
o.MigrationsHistoryTable(schemaPrefix, mainSearchPath);
|
o.MigrationsHistoryTable(_schemaPrefix);
|
||||||
})
|
}
|
||||||
.ReplaceService<IMigrationsSqlGenerator, CustomNpgsqlMigrationsSqlGenerator>();
|
});
|
||||||
|
break;
|
||||||
|
case DatabaseType.Postgres:
|
||||||
|
builder
|
||||||
|
.UseNpgsql(_options.Value.ConnectionString, o =>
|
||||||
|
{
|
||||||
|
o.EnableRetryOnFailure(10);
|
||||||
|
if (!string.IsNullOrEmpty(_schemaPrefix))
|
||||||
|
{
|
||||||
|
o.MigrationsHistoryTable(_schemaPrefix);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.ReplaceService<IMigrationsSqlGenerator, CustomNpgsqlMigrationsSqlGenerator>();
|
||||||
|
break;
|
||||||
|
case DatabaseType.MySQL:
|
||||||
|
builder.UseMySql(_options.Value.ConnectionString, ServerVersion.AutoDetect(_options.Value.ConnectionString), o =>
|
||||||
|
{
|
||||||
|
o.EnableRetryOnFailure(10);
|
||||||
|
|
||||||
|
if (!string.IsNullOrEmpty(_schemaPrefix))
|
||||||
|
{
|
||||||
|
o.MigrationsHistoryTable(_schemaPrefix);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new ArgumentOutOfRangeException();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private string GetSearchPath(string connectionString)
|
|
||||||
{
|
|
||||||
var connectionStringBuilder = new NpgsqlConnectionStringBuilder(connectionString);
|
|
||||||
var searchPaths = connectionStringBuilder.SearchPath?.Split(',');
|
|
||||||
return searchPaths is not { Length: > 0 } ? null : searchPaths[0];
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -2,7 +2,6 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Microsoft.AspNetCore.Http;
|
using Microsoft.AspNetCore.Http;
|
||||||
using BTCPayServer.Abstractions.Models;
|
|
||||||
|
|
||||||
namespace BTCPayServer.Abstractions.Contracts;
|
namespace BTCPayServer.Abstractions.Contracts;
|
||||||
|
|
||||||
@@ -15,5 +14,4 @@ public interface IFileService
|
|||||||
Task<string?> GetTemporaryFileUrl(Uri baseUri, string fileId, DateTimeOffset expiry,
|
Task<string?> GetTemporaryFileUrl(Uri baseUri, string fileId, DateTimeOffset expiry,
|
||||||
bool isDownload);
|
bool isDownload);
|
||||||
Task RemoveFile(string fileId, string userId);
|
Task RemoveFile(string fileId, string userId);
|
||||||
Task<UploadImageResultModel> UploadImage(IFormFile file, string userId, long maxFileSizeInBytes = 1_000_000);
|
|
||||||
}
|
}
|
||||||
|
@@ -25,6 +25,5 @@ namespace BTCPayServer.Abstractions.Contracts
|
|||||||
public string Body { get; set; }
|
public string Body { get; set; }
|
||||||
public string ActionLink { get; set; }
|
public string ActionLink { get; set; }
|
||||||
public bool Seen { get; set; }
|
public bool Seen { get; set; }
|
||||||
public string StoreId { get; set; }
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1,4 +1,3 @@
|
|||||||
using System;
|
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
namespace BTCPayServer.Abstractions.Contracts
|
namespace BTCPayServer.Abstractions.Contracts
|
||||||
@@ -7,8 +6,5 @@ namespace BTCPayServer.Abstractions.Contracts
|
|||||||
{
|
{
|
||||||
Task ApplyAction(string hook, object args);
|
Task ApplyAction(string hook, object args);
|
||||||
Task<object> ApplyFilter(string hook, object args);
|
Task<object> ApplyFilter(string hook, object args);
|
||||||
|
|
||||||
event EventHandler<(string hook, object args)> ActionInvoked;
|
|
||||||
event EventHandler<(string hook, object args)> FilterInvoked;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -12,7 +12,7 @@ namespace BTCPayServer.Abstractions.Contracts
|
|||||||
|
|
||||||
public interface ISyncStatus
|
public interface ISyncStatus
|
||||||
{
|
{
|
||||||
public string PaymentMethodId { get; set; }
|
public string CryptoCode { get; set; }
|
||||||
public bool Available { get; }
|
public bool Available { get; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -0,0 +1,19 @@
|
|||||||
|
namespace BTCPayServer.Abstractions.Custodians.Client;
|
||||||
|
|
||||||
|
public class AssetQuoteResult
|
||||||
|
{
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
FromAsset = fromAsset;
|
||||||
|
ToAsset = toAsset;
|
||||||
|
Bid = bid;
|
||||||
|
Ask = ask;
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,12 @@
|
|||||||
|
namespace BTCPayServer.Abstractions.Custodians;
|
||||||
|
|
||||||
|
public class AssetBalancesUnavailableException : CustodianApiException
|
||||||
|
{
|
||||||
|
public AssetBalancesUnavailableException(System.Exception e) : base(500, "asset-balances-unavailable", $"Cannot fetch the asset balances: {e.Message}", e)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public AssetBalancesUnavailableException(string errorMsg) : base(500, "asset-balances-unavailable", $"Cannot fetch the asset balances: {errorMsg}")
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,13 @@
|
|||||||
|
using BTCPayServer.Client.Models;
|
||||||
|
|
||||||
|
namespace BTCPayServer.Abstractions.Custodians;
|
||||||
|
|
||||||
|
public class AssetQuoteUnavailableException : CustodianApiException
|
||||||
|
{
|
||||||
|
public AssetPairData AssetPair { get; }
|
||||||
|
|
||||||
|
public AssetQuoteUnavailableException(AssetPairData assetPair) : base(400, "asset-price-unavailable", "Cannot find a quote for pair " + assetPair)
|
||||||
|
{
|
||||||
|
this.AssetPair = assetPair;
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,13 @@
|
|||||||
|
using System;
|
||||||
|
|
||||||
|
namespace BTCPayServer.Abstractions.Custodians;
|
||||||
|
|
||||||
|
public class BadConfigException : CustodianApiException
|
||||||
|
{
|
||||||
|
public string[] BadConfigKeys { get; set; }
|
||||||
|
|
||||||
|
public BadConfigException(string[] badConfigKeys) : base(500, "bad-custodian-account-config", "Wrong config values: " + String.Join(", ", badConfigKeys))
|
||||||
|
{
|
||||||
|
this.BadConfigKeys = badConfigKeys;
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,13 @@
|
|||||||
|
namespace BTCPayServer.Abstractions.Custodians;
|
||||||
|
|
||||||
|
public class CannotWithdrawException : CustodianApiException
|
||||||
|
|
||||||
|
{
|
||||||
|
public CannotWithdrawException(ICustodian custodian, string paymentMethod, string message) : base(403, "cannot-withdraw", message)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public CannotWithdrawException(ICustodian custodian, string paymentMethod, string targetAddress, CustodianApiException originalException) : base(403, "cannot-withdraw", $"{custodian.Name} cannot withdraw {paymentMethod} to '{targetAddress}': {originalException.Message}")
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,18 @@
|
|||||||
|
using System;
|
||||||
|
namespace BTCPayServer.Abstractions.Custodians;
|
||||||
|
public class CustodianApiException : Exception
|
||||||
|
{
|
||||||
|
public int HttpStatus { get; }
|
||||||
|
public string Code { get; }
|
||||||
|
|
||||||
|
public CustodianApiException(int httpStatus, string code, string message, System.Exception ex) : base(message, ex)
|
||||||
|
{
|
||||||
|
HttpStatus = httpStatus;
|
||||||
|
Code = code;
|
||||||
|
}
|
||||||
|
|
||||||
|
public CustodianApiException(int httpStatus, string code, string message) : this(httpStatus, code, message, null)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@@ -0,0 +1,8 @@
|
|||||||
|
namespace BTCPayServer.Abstractions.Custodians;
|
||||||
|
|
||||||
|
public class CustodianFeatureNotImplementedException : CustodianApiException
|
||||||
|
{
|
||||||
|
public CustodianFeatureNotImplementedException(string message) : base(400, "not-implemented", message)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,8 @@
|
|||||||
|
namespace BTCPayServer.Abstractions.Custodians;
|
||||||
|
|
||||||
|
public class DepositsUnavailableException : CustodianApiException
|
||||||
|
{
|
||||||
|
public DepositsUnavailableException(string message) : base(404, "deposits-unavailable", message)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,8 @@
|
|||||||
|
namespace BTCPayServer.Abstractions.Custodians;
|
||||||
|
|
||||||
|
public class InsufficientFundsException : CustodianApiException
|
||||||
|
{
|
||||||
|
public InsufficientFundsException(string message) : base(400, "insufficient-funds", message)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,9 @@
|
|||||||
|
namespace BTCPayServer.Abstractions.Custodians;
|
||||||
|
|
||||||
|
public class InvalidWithdrawalTargetException : CustodianApiException
|
||||||
|
|
||||||
|
{
|
||||||
|
public InvalidWithdrawalTargetException(ICustodian custodian, string paymentMethod, string targetAddress, CustodianApiException originalException) : base(403, "invalid-withdrawal-target", $"{custodian.Name} cannot withdraw {paymentMethod} to '{targetAddress}': {originalException.Message}")
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,9 @@
|
|||||||
|
namespace BTCPayServer.Abstractions.Custodians;
|
||||||
|
|
||||||
|
public class PermissionDeniedCustodianApiException : CustodianApiException
|
||||||
|
|
||||||
|
{
|
||||||
|
public PermissionDeniedCustodianApiException(ICustodian custodian) : base(403, "custodian-api-permission-denied", $"{custodian.Name}'s API reported that you don't have permission.")
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,11 @@
|
|||||||
|
namespace BTCPayServer.Abstractions.Custodians;
|
||||||
|
|
||||||
|
public class TradeNotFoundException : CustodianApiException
|
||||||
|
{
|
||||||
|
private string tradeId { get; }
|
||||||
|
|
||||||
|
public TradeNotFoundException(string tradeId) : base(404, "trade-not-found", "Could not find trade ID " + tradeId)
|
||||||
|
{
|
||||||
|
this.tradeId = tradeId;
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,11 @@
|
|||||||
|
namespace BTCPayServer.Abstractions.Custodians;
|
||||||
|
|
||||||
|
public class WithdrawalNotFoundException : CustodianApiException
|
||||||
|
{
|
||||||
|
private string WithdrawalId { get; }
|
||||||
|
|
||||||
|
public WithdrawalNotFoundException(string withdrawalId) : base(404, "withdrawal-not-found", $"Could not find withdrawal ID {withdrawalId}.")
|
||||||
|
{
|
||||||
|
WithdrawalId = withdrawalId;
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,9 @@
|
|||||||
|
namespace BTCPayServer.Abstractions.Custodians;
|
||||||
|
|
||||||
|
public class WrongTradingPairException : CustodianApiException
|
||||||
|
{
|
||||||
|
public const int HttpCode = 404;
|
||||||
|
public WrongTradingPairException(string fromAsset, string toAsset) : base(HttpCode, "wrong-trading-pair", $"Cannot find a trading pair for converting {fromAsset} into {toAsset}.")
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,29 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
using BTCPayServer.Client.Models;
|
||||||
|
|
||||||
|
namespace BTCPayServer.Abstractions.Custodians.Client;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The result of a market trade. Used as a return type for custodians implementing ICanTrade
|
||||||
|
*/
|
||||||
|
public class MarketTradeResult
|
||||||
|
{
|
||||||
|
public string FromAsset { get; }
|
||||||
|
public string ToAsset { get; }
|
||||||
|
/**
|
||||||
|
* The ledger entries that show the balances that were affected by the trade.
|
||||||
|
*/
|
||||||
|
public List<LedgerEntryData> LedgerEntries { get; }
|
||||||
|
/**
|
||||||
|
* The unique ID of the trade that was executed.
|
||||||
|
*/
|
||||||
|
public string TradeId { get; }
|
||||||
|
|
||||||
|
public MarketTradeResult(string fromAsset, string toAsset, List<LedgerEntryData> ledgerEntries, string tradeId)
|
||||||
|
{
|
||||||
|
this.FromAsset = fromAsset;
|
||||||
|
this.ToAsset = toAsset;
|
||||||
|
this.LedgerEntries = ledgerEntries;
|
||||||
|
this.TradeId = tradeId;
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,28 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
using BTCPayServer.Client.Models;
|
||||||
|
using BTCPayServer.JsonConverters;
|
||||||
|
|
||||||
|
namespace BTCPayServer.Abstractions.Custodians.Client;
|
||||||
|
|
||||||
|
public class SimulateWithdrawalResult
|
||||||
|
{
|
||||||
|
public string PaymentMethod { get; }
|
||||||
|
public string Asset { get; }
|
||||||
|
public decimal MinQty { get; }
|
||||||
|
public decimal MaxQty { get; }
|
||||||
|
|
||||||
|
public List<LedgerEntryData> LedgerEntries { get; }
|
||||||
|
|
||||||
|
// Fee can be NULL if unknown.
|
||||||
|
public decimal? Fee { get; }
|
||||||
|
|
||||||
|
public SimulateWithdrawalResult(string paymentMethod, string asset, List<LedgerEntryData> ledgerEntries,
|
||||||
|
decimal minQty, decimal maxQty)
|
||||||
|
{
|
||||||
|
PaymentMethod = paymentMethod;
|
||||||
|
Asset = asset;
|
||||||
|
LedgerEntries = ledgerEntries;
|
||||||
|
MinQty = minQty;
|
||||||
|
MaxQty = maxQty;
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,29 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using BTCPayServer.Client.Models;
|
||||||
|
|
||||||
|
namespace BTCPayServer.Abstractions.Custodians.Client;
|
||||||
|
|
||||||
|
public class WithdrawResult
|
||||||
|
{
|
||||||
|
public string PaymentMethod { get; }
|
||||||
|
public string Asset { get; set; }
|
||||||
|
public List<LedgerEntryData> LedgerEntries { get; }
|
||||||
|
public string WithdrawalId { get; }
|
||||||
|
public WithdrawalResponseData.WithdrawalStatus Status { get; }
|
||||||
|
public DateTimeOffset CreatedTime { get; }
|
||||||
|
public string TargetAddress { get; }
|
||||||
|
public string TransactionId { get; }
|
||||||
|
|
||||||
|
public WithdrawResult(string paymentMethod, string asset, List<LedgerEntryData> ledgerEntries, string withdrawalId, WithdrawalResponseData.WithdrawalStatus status, DateTimeOffset createdTime, string targetAddress, string transactionId)
|
||||||
|
{
|
||||||
|
PaymentMethod = paymentMethod;
|
||||||
|
Asset = asset;
|
||||||
|
LedgerEntries = ledgerEntries;
|
||||||
|
WithdrawalId = withdrawalId;
|
||||||
|
CreatedTime = createdTime;
|
||||||
|
Status = status;
|
||||||
|
TargetAddress = targetAddress;
|
||||||
|
TransactionId = transactionId;
|
||||||
|
}
|
||||||
|
}
|
17
BTCPayServer.Abstractions/Custodians/ICanDeposit.cs
Normal file
17
BTCPayServer.Abstractions/Custodians/ICanDeposit.cs
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
using System.Threading;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using BTCPayServer.Client.Models;
|
||||||
|
using Newtonsoft.Json.Linq;
|
||||||
|
|
||||||
|
namespace BTCPayServer.Abstractions.Custodians;
|
||||||
|
|
||||||
|
public interface ICanDeposit
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Get the address where we can deposit for the chosen payment method (crypto code + network).
|
||||||
|
* The result can be a string in different formats like a bitcoin address or even a LN invoice.
|
||||||
|
*/
|
||||||
|
public Task<DepositAddressData> GetDepositAddressAsync(string paymentMethod, JObject config, CancellationToken cancellationToken);
|
||||||
|
|
||||||
|
public string[] GetDepositablePaymentMethods();
|
||||||
|
}
|
31
BTCPayServer.Abstractions/Custodians/ICanTrade.cs
Normal file
31
BTCPayServer.Abstractions/Custodians/ICanTrade.cs
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Threading;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using BTCPayServer.Abstractions.Custodians.Client;
|
||||||
|
using BTCPayServer.Client.Models;
|
||||||
|
using Newtonsoft.Json.Linq;
|
||||||
|
|
||||||
|
namespace BTCPayServer.Abstractions.Custodians;
|
||||||
|
|
||||||
|
public interface ICanTrade
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* A list of tradable asset pairs, or NULL if the custodian cannot trade/convert assets. if thr asset pair contains fiat, fiat is always put last. If both assets are a cyrptocode or both are fiat, the pair is written alphabetically. Always in uppercase. Example: ["BTC/EUR","BTC/USD", "EUR/USD", "BTC/ETH",...]
|
||||||
|
*/
|
||||||
|
public List<AssetPairData> GetTradableAssetPairs();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Execute a market order right now.
|
||||||
|
*/
|
||||||
|
public Task<MarketTradeResult> TradeMarketAsync(string fromAsset, string toAsset, decimal qty, JObject config, CancellationToken cancellationToken);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the details about a previous market trade.
|
||||||
|
*/
|
||||||
|
public Task<MarketTradeResult> GetTradeInfoAsync(string tradeId, JObject config, CancellationToken cancellationToken);
|
||||||
|
|
||||||
|
public Task<AssetQuoteResult> GetQuoteForAssetAsync(string fromAsset, string toAsset, JObject config, CancellationToken cancellationToken);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
20
BTCPayServer.Abstractions/Custodians/ICanWithdraw.cs
Normal file
20
BTCPayServer.Abstractions/Custodians/ICanWithdraw.cs
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
using System.Threading;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using BTCPayServer.Abstractions.Custodians.Client;
|
||||||
|
using Newtonsoft.Json.Linq;
|
||||||
|
|
||||||
|
namespace BTCPayServer.Abstractions.Custodians;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Interface for custodians that can move funds to the store wallet.
|
||||||
|
/// </summary>
|
||||||
|
public interface ICanWithdraw
|
||||||
|
{
|
||||||
|
public Task<WithdrawResult> WithdrawToStoreWalletAsync(string paymentMethod, decimal amount, JObject config, CancellationToken cancellationToken);
|
||||||
|
|
||||||
|
public Task<SimulateWithdrawalResult> SimulateWithdrawalAsync(string paymentMethod, decimal qty, JObject config, CancellationToken cancellationToken);
|
||||||
|
|
||||||
|
public Task<WithdrawResult> GetWithdrawalInfoAsync(string paymentMethod, string withdrawalId, JObject config, CancellationToken cancellationToken);
|
||||||
|
|
||||||
|
public string[] GetWithdrawablePaymentMethods();
|
||||||
|
}
|
26
BTCPayServer.Abstractions/Custodians/ICustodian.cs
Normal file
26
BTCPayServer.Abstractions/Custodians/ICustodian.cs
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
#nullable enable
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Threading;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using BTCPayServer.Client.Models;
|
||||||
|
using Newtonsoft.Json.Linq;
|
||||||
|
|
||||||
|
namespace BTCPayServer.Abstractions.Custodians;
|
||||||
|
|
||||||
|
public interface ICustodian
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Get the unique code that identifies this custodian.
|
||||||
|
*/
|
||||||
|
string Code { get; }
|
||||||
|
|
||||||
|
string Name { get; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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, CancellationToken cancellationToken = default);
|
||||||
|
|
||||||
|
}
|
14
BTCPayServer.Abstractions/Extensions/CustodianExtensions.cs
Normal file
14
BTCPayServer.Abstractions/Extensions/CustodianExtensions.cs
Normal 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);
|
||||||
|
}
|
||||||
|
}
|
@@ -36,17 +36,6 @@ public static class HttpRequestExtensions
|
|||||||
request.Path.ToUriComponent());
|
request.Path.ToUriComponent());
|
||||||
}
|
}
|
||||||
|
|
||||||
public static string GetCurrentUrlWithQueryString(this HttpRequest request)
|
|
||||||
{
|
|
||||||
return string.Concat(
|
|
||||||
request.Scheme,
|
|
||||||
"://",
|
|
||||||
request.Host.ToUriComponent(),
|
|
||||||
request.PathBase.ToUriComponent(),
|
|
||||||
request.Path.ToUriComponent(),
|
|
||||||
request.QueryString.ToUriComponent());
|
|
||||||
}
|
|
||||||
|
|
||||||
public static string GetCurrentPath(this HttpRequest request)
|
public static string GetCurrentPath(this HttpRequest request)
|
||||||
{
|
{
|
||||||
return string.Concat(
|
return string.Concat(
|
||||||
@@ -106,8 +95,8 @@ public static class HttpRequestExtensions
|
|||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Will return an absolute URL.
|
/// Will return an absolute URL.
|
||||||
/// If `relativeOrAbsolute` is absolute, returns it.
|
/// If `relativeOrAsbolute` is absolute, returns it.
|
||||||
/// If `relativeOrAbsolute` is relative, send absolute url based on the HOST of this request (without PathBase)
|
/// If `relativeOrAsbolute` is relative, send absolute url based on the HOST of this request (without PathBase)
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="request"></param>
|
/// <param name="request"></param>
|
||||||
/// <param name="relativeOrAbsolte"></param>
|
/// <param name="relativeOrAbsolte"></param>
|
||||||
|
@@ -8,14 +8,6 @@ namespace BTCPayServer.Abstractions.Extensions;
|
|||||||
|
|
||||||
public static class SetStatusMessageModelExtensions
|
public static class SetStatusMessageModelExtensions
|
||||||
{
|
{
|
||||||
public static void SetStatusSuccess(this ITempDataDictionary tempData, string statusMessage)
|
|
||||||
{
|
|
||||||
tempData.SetStatusMessageModel(new StatusMessageModel
|
|
||||||
{
|
|
||||||
Severity = StatusMessageModel.StatusSeverity.Success,
|
|
||||||
Message = statusMessage
|
|
||||||
});
|
|
||||||
}
|
|
||||||
public static void SetStatusMessageModel(this ITempDataDictionary tempData, StatusMessageModel statusMessage)
|
public static void SetStatusMessageModel(this ITempDataDictionary tempData, StatusMessageModel statusMessage)
|
||||||
{
|
{
|
||||||
if (statusMessage == null)
|
if (statusMessage == null)
|
||||||
@@ -34,14 +26,19 @@ public static class SetStatusMessageModelExtensions
|
|||||||
tempData.TryGetValue("StatusMessageModel", out var model);
|
tempData.TryGetValue("StatusMessageModel", out var model);
|
||||||
if (successMessage != null || errorMessage != null)
|
if (successMessage != null || errorMessage != null)
|
||||||
{
|
{
|
||||||
var parsedModel = new StatusMessageModel
|
var parsedModel = new StatusMessageModel();
|
||||||
|
parsedModel.Message = (string)successMessage ?? (string)errorMessage;
|
||||||
|
if (successMessage != null)
|
||||||
{
|
{
|
||||||
Message = (string)successMessage ?? (string)errorMessage,
|
parsedModel.Severity = StatusMessageModel.StatusSeverity.Success;
|
||||||
Severity = successMessage != null ? StatusMessageModel.StatusSeverity.Success : StatusMessageModel.StatusSeverity.Error
|
}
|
||||||
};
|
else
|
||||||
|
{
|
||||||
|
parsedModel.Severity = StatusMessageModel.StatusSeverity.Error;
|
||||||
|
}
|
||||||
return parsedModel;
|
return parsedModel;
|
||||||
}
|
}
|
||||||
if (model is string str)
|
else if (model != null && model is string str)
|
||||||
{
|
{
|
||||||
return JObject.Parse(str).ToObject<StatusMessageModel>();
|
return JObject.Parse(str).ToObject<StatusMessageModel>();
|
||||||
}
|
}
|
||||||
|
@@ -12,7 +12,7 @@ namespace BTCPayServer.Abstractions.Extensions
|
|||||||
private const string ACTIVE_CATEGORY_KEY = "ActiveCategory";
|
private const string ACTIVE_CATEGORY_KEY = "ActiveCategory";
|
||||||
private const string ACTIVE_PAGE_KEY = "ActivePage";
|
private const string ACTIVE_PAGE_KEY = "ActivePage";
|
||||||
private const string ACTIVE_ID_KEY = "ActiveId";
|
private const string ACTIVE_ID_KEY = "ActiveId";
|
||||||
private const string ACTIVE_CLASS = "active";
|
private const string ActivePageClass = "active";
|
||||||
|
|
||||||
public enum DateDisplayFormat
|
public enum DateDisplayFormat
|
||||||
{
|
{
|
||||||
@@ -20,15 +20,6 @@ namespace BTCPayServer.Abstractions.Extensions
|
|||||||
Relative
|
Relative
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void SetBlazorAllowed(this ViewDataDictionary viewData, bool allowed)
|
|
||||||
{
|
|
||||||
viewData["BlazorAllowed"] = allowed;
|
|
||||||
}
|
|
||||||
public static bool IsBlazorAllowed(this ViewDataDictionary viewData)
|
|
||||||
{
|
|
||||||
return viewData["BlazorAllowed"] is not false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void SetActivePage<T>(this ViewDataDictionary viewData, T activePage, string title = null, string activeId = null)
|
public static void SetActivePage<T>(this ViewDataDictionary viewData, T activePage, string title = null, string activeId = null)
|
||||||
where T : IConvertible
|
where T : IConvertible
|
||||||
{
|
{
|
||||||
@@ -55,101 +46,50 @@ namespace BTCPayServer.Abstractions.Extensions
|
|||||||
viewData[ACTIVE_CATEGORY_KEY] = activeCategory;
|
viewData[ACTIVE_CATEGORY_KEY] = activeCategory;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static bool IsCategoryActive(this ViewDataDictionary viewData, string category, object id = null)
|
public static string IsActiveCategory<T>(this ViewDataDictionary viewData, T category, object id = null)
|
||||||
{
|
{
|
||||||
if (!viewData.ContainsKey(ACTIVE_CATEGORY_KEY)) return false;
|
return IsActiveCategory(viewData, category.ToString(), id);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static string IsActiveCategory(this ViewDataDictionary viewData, string category, object id = null)
|
||||||
|
{
|
||||||
|
if (!viewData.ContainsKey(ACTIVE_CATEGORY_KEY))
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
var activeId = viewData[ACTIVE_ID_KEY];
|
var activeId = viewData[ACTIVE_ID_KEY];
|
||||||
var activeCategory = viewData[ACTIVE_CATEGORY_KEY]?.ToString();
|
var activeCategory = viewData[ACTIVE_CATEGORY_KEY]?.ToString();
|
||||||
var categoryMatch = category.Equals(activeCategory, StringComparison.InvariantCultureIgnoreCase);
|
var categoryMatch = category.Equals(activeCategory, StringComparison.InvariantCultureIgnoreCase);
|
||||||
var idMatch = id == null || activeId == null || id.Equals(activeId);
|
var idMatch = id == null || activeId == null || id.Equals(activeId);
|
||||||
return categoryMatch && idMatch;
|
return categoryMatch && idMatch ? ActivePageClass : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static bool IsCategoryActive<T>(this ViewDataDictionary viewData, T category, object id = null)
|
public static string IsActivePage<T>(this ViewDataDictionary viewData, T page, object id = null)
|
||||||
|
where T : IConvertible
|
||||||
{
|
{
|
||||||
return IsCategoryActive(viewData, category.ToString(), id);
|
return IsActivePage(viewData, page.ToString(), page.GetType().ToString(), id);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static bool IsPageActive(this ViewDataDictionary viewData, string page, string category, object id = null)
|
public static string IsActivePage<T>(this ViewDataDictionary viewData, IEnumerable<T> pages, object id = null)
|
||||||
|
where T : IConvertible
|
||||||
{
|
{
|
||||||
if (!viewData.ContainsKey(ACTIVE_PAGE_KEY)) return false;
|
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)
|
||||||
|
{
|
||||||
|
if (!viewData.ContainsKey(ACTIVE_PAGE_KEY))
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
var activeId = viewData[ACTIVE_ID_KEY];
|
var activeId = viewData[ACTIVE_ID_KEY];
|
||||||
var activePage = viewData[ACTIVE_PAGE_KEY]?.ToString();
|
var activePage = viewData[ACTIVE_PAGE_KEY]?.ToString();
|
||||||
var activeCategory = viewData[ACTIVE_CATEGORY_KEY]?.ToString();
|
var activeCategory = viewData[ACTIVE_CATEGORY_KEY]?.ToString();
|
||||||
var categoryAndPageMatch = page.Equals(activePage, StringComparison.InvariantCultureIgnoreCase) &&
|
var categoryAndPageMatch = (category == null || activeCategory.Equals(category, StringComparison.InvariantCultureIgnoreCase)) && page.Equals(activePage, StringComparison.InvariantCultureIgnoreCase);
|
||||||
(category == null || activeCategory != null && activeCategory.Equals(category, StringComparison.InvariantCultureIgnoreCase));
|
|
||||||
var idMatch = id == null || activeId == null || id.Equals(activeId);
|
var idMatch = id == null || activeId == null || id.Equals(activeId);
|
||||||
return categoryAndPageMatch && idMatch;
|
return categoryAndPageMatch && idMatch ? ActivePageClass : null;
|
||||||
}
|
|
||||||
|
|
||||||
public static bool IsPageActive<T>(this ViewDataDictionary viewData, IEnumerable<T> pages, object id = null)
|
|
||||||
where T : IConvertible
|
|
||||||
{
|
|
||||||
return pages.Any(page => ActivePageClass(viewData, page.ToString(), page.GetType().ToString(), id) == ACTIVE_CLASS);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static string ActiveCategoryClass<T>(this ViewDataDictionary viewData, T category, object id = null)
|
|
||||||
{
|
|
||||||
return ActiveCategoryClass(viewData, category.ToString(), id);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static string ActiveCategoryClass(this ViewDataDictionary viewData, string category, object id = null)
|
|
||||||
{
|
|
||||||
return IsCategoryActive(viewData, category, id) ? ACTIVE_CLASS : null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static string ActivePageClass<T>(this ViewDataDictionary viewData, T page, object id = null)
|
|
||||||
where T : IConvertible
|
|
||||||
{
|
|
||||||
return ActivePageClass(viewData, page.ToString(), page.GetType().ToString(), id);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static string ActivePageClass(this ViewDataDictionary viewData, string page, string category, object id = null)
|
|
||||||
{
|
|
||||||
return IsPageActive(viewData, page, category, id) ? ACTIVE_CLASS : null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static string ActivePageClass<T>(this ViewDataDictionary viewData, IEnumerable<T> pages, object id = null) where T : IConvertible
|
|
||||||
{
|
|
||||||
return IsPageActive(viewData, pages, id) ? ACTIVE_CLASS : null;
|
|
||||||
}
|
|
||||||
|
|
||||||
[Obsolete("Use ActiveCategoryClass instead")]
|
|
||||||
public static string IsActiveCategory<T>(this ViewDataDictionary viewData, T category, object id = null)
|
|
||||||
{
|
|
||||||
return ActiveCategoryClass(viewData, category, id);
|
|
||||||
}
|
|
||||||
|
|
||||||
[Obsolete("Use ActiveCategoryClass instead")]
|
|
||||||
public static string IsActiveCategory(this ViewDataDictionary viewData, string category, object id = null)
|
|
||||||
{
|
|
||||||
return ActiveCategoryClass(viewData, category, id);
|
|
||||||
}
|
|
||||||
|
|
||||||
[Obsolete("Use ActivePageClass instead")]
|
|
||||||
public static string IsActivePage<T>(this ViewDataDictionary viewData, T page, object id = null) where T : IConvertible
|
|
||||||
{
|
|
||||||
return ActivePageClass(viewData, page, id);
|
|
||||||
}
|
|
||||||
|
|
||||||
[Obsolete("Use ActivePageClass instead")]
|
|
||||||
public static string IsActivePage<T>(this ViewDataDictionary viewData, IEnumerable<T> pages, object id = null) where T : IConvertible
|
|
||||||
{
|
|
||||||
return ActivePageClass(viewData, pages, id);
|
|
||||||
}
|
|
||||||
|
|
||||||
[Obsolete("Use ActivePageClass instead")]
|
|
||||||
public static string IsActivePage(this ViewDataDictionary viewData, string page, string category, object id = null)
|
|
||||||
{
|
|
||||||
return ActivePageClass(viewData, page, category, id);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static HtmlString ToBrowserDate(this DateTimeOffset date, string netFormat, string jsDateFormat = "short", string jsTimeFormat = "short")
|
|
||||||
{
|
|
||||||
var dateTime = date.ToString("o", CultureInfo.InvariantCulture);
|
|
||||||
var displayDate = date.ToString(netFormat, CultureInfo.InvariantCulture);
|
|
||||||
var tooltip = dateTime.Replace("T", " ");
|
|
||||||
return new HtmlString($"<time datetime=\"{dateTime}\" data-date-style=\"{jsDateFormat}\" data-time-style=\"{jsTimeFormat}\" data-initial=\"localized\" data-bs-toggle=\"tooltip\" data-bs-title=\"{tooltip}\">{displayDate}</time>");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static HtmlString ToBrowserDate(this DateTimeOffset date, DateDisplayFormat format = DateDisplayFormat.Localized)
|
public static HtmlString ToBrowserDate(this DateTimeOffset date, DateDisplayFormat format = DateDisplayFormat.Localized)
|
||||||
|
@@ -5,6 +5,7 @@ using System.Reflection;
|
|||||||
using Microsoft.AspNetCore.Http;
|
using Microsoft.AspNetCore.Http;
|
||||||
using Microsoft.Extensions.Primitives;
|
using Microsoft.Extensions.Primitives;
|
||||||
using Newtonsoft.Json.Linq;
|
using Newtonsoft.Json.Linq;
|
||||||
|
using Npgsql.Internal.TypeHandlers.GeometricHandlers;
|
||||||
|
|
||||||
namespace BTCPayServer.Abstractions.Form;
|
namespace BTCPayServer.Abstractions.Form;
|
||||||
|
|
||||||
@@ -68,6 +69,7 @@ public class Form
|
|||||||
if (!nameReturned.Add(fullName))
|
if (!nameReturned.Add(fullName))
|
||||||
{
|
{
|
||||||
errors.Add($"Form contains duplicate field names '{fullName}'");
|
errors.Add($"Form contains duplicate field names '{fullName}'");
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return errors.Count == 0;
|
return errors.Count == 0;
|
||||||
@@ -84,10 +86,15 @@ public class Form
|
|||||||
thisPath.Add(field.Name);
|
thisPath.Add(field.Name);
|
||||||
yield return (thisPath, field);
|
yield return (thisPath, field);
|
||||||
}
|
}
|
||||||
foreach (var descendant in GetAllFieldsCore(thisPath, field.Fields))
|
|
||||||
|
foreach (var child in field.Fields)
|
||||||
{
|
{
|
||||||
descendant.Field.Constant = field.Constant || descendant.Field.Constant;
|
if (field.Constant)
|
||||||
yield return descendant;
|
child.Constant = true;
|
||||||
|
foreach (var descendant in GetAllFieldsCore(thisPath, field.Fields))
|
||||||
|
{
|
||||||
|
yield return descendant;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -104,7 +111,31 @@ public class Form
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void SetValues(JObject values)
|
||||||
|
{
|
||||||
|
var fields = GetAllFields().ToDictionary(k => k.FullName, k => k.Field);
|
||||||
|
SetValues(fields, new List<string>(), values);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void SetValues(Dictionary<string, Field> fields, List<string> path, JObject values)
|
||||||
|
{
|
||||||
|
foreach (var prop in values.Properties())
|
||||||
|
{
|
||||||
|
List<string> propPath = new List<string>(path.Count + 1);
|
||||||
|
propPath.AddRange(path);
|
||||||
|
propPath.Add(prop.Name);
|
||||||
|
if (prop.Value.Type == JTokenType.Object)
|
||||||
|
{
|
||||||
|
SetValues(fields, propPath, (JObject)prop.Value);
|
||||||
|
}
|
||||||
|
else if (prop.Value.Type == JTokenType.String)
|
||||||
|
{
|
||||||
|
var fullName = string.Join('_', propPath.Where(s => !string.IsNullOrEmpty(s)));
|
||||||
|
if (fields.TryGetValue(fullName, out var f) && !f.Constant)
|
||||||
|
f.Value = prop.Value.Value<string>();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -2,6 +2,7 @@ namespace BTCPayServer.Abstractions.Models
|
|||||||
{
|
{
|
||||||
public class DatabaseOptions
|
public class DatabaseOptions
|
||||||
{
|
{
|
||||||
|
public DatabaseType DatabaseType { get; set; }
|
||||||
public string ConnectionString { get; set; }
|
public string ConnectionString { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
9
BTCPayServer.Abstractions/Models/DatabaseType.cs
Normal file
9
BTCPayServer.Abstractions/Models/DatabaseType.cs
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
namespace BTCPayServer.Abstractions.Models
|
||||||
|
{
|
||||||
|
public enum DatabaseType
|
||||||
|
{
|
||||||
|
Sqlite,
|
||||||
|
Postgres,
|
||||||
|
MySQL,
|
||||||
|
}
|
||||||
|
}
|
@@ -14,6 +14,14 @@ namespace BTCPayServer.Abstractions.Models
|
|||||||
|
|
||||||
public string SeverityCSS => ToString(Severity);
|
public string SeverityCSS => ToString(Severity);
|
||||||
|
|
||||||
|
private void ParseNonJsonStatus(string s)
|
||||||
|
{
|
||||||
|
Message = s;
|
||||||
|
Severity = s.StartsWith("Error", StringComparison.InvariantCultureIgnoreCase)
|
||||||
|
? StatusSeverity.Error
|
||||||
|
: StatusSeverity.Success;
|
||||||
|
}
|
||||||
|
|
||||||
public static string ToString(StatusSeverity severity)
|
public static string ToString(StatusSeverity severity)
|
||||||
{
|
{
|
||||||
switch (severity)
|
switch (severity)
|
||||||
|
@@ -1,16 +0,0 @@
|
|||||||
#nullable enable
|
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using BTCPayServer.Abstractions.Contracts;
|
|
||||||
|
|
||||||
namespace BTCPayServer.Abstractions.Models;
|
|
||||||
|
|
||||||
public class UploadImageResultModel
|
|
||||||
{
|
|
||||||
public bool Success { get; set; }
|
|
||||||
public string Response { get; set; } = string.Empty;
|
|
||||||
public IStoredFile? StoredFile { get; set; }
|
|
||||||
}
|
|
@@ -1,5 +1,4 @@
|
|||||||
using System.Web;
|
using Ganss.XSS;
|
||||||
using Ganss.Xss;
|
|
||||||
using Microsoft.AspNetCore.Html;
|
using Microsoft.AspNetCore.Html;
|
||||||
using Microsoft.AspNetCore.Mvc.Rendering;
|
using Microsoft.AspNetCore.Mvc.Rendering;
|
||||||
|
|
||||||
@@ -16,57 +15,16 @@ namespace BTCPayServer.Abstractions.Services
|
|||||||
_htmlHelper = htmlHelper;
|
_htmlHelper = htmlHelper;
|
||||||
_jsonHelper = jsonHelper;
|
_jsonHelper = jsonHelper;
|
||||||
_htmlSanitizer = htmlSanitizer;
|
_htmlSanitizer = htmlSanitizer;
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public IHtmlContent Raw(string value)
|
public IHtmlContent Raw(string value)
|
||||||
{
|
{
|
||||||
return _htmlHelper.Raw(_htmlSanitizer.Sanitize(value));
|
return _htmlHelper.Raw(_htmlSanitizer.Sanitize(value));
|
||||||
}
|
}
|
||||||
|
|
||||||
public IHtmlContent RawEncode(string value)
|
|
||||||
{
|
|
||||||
return _htmlHelper.Raw(HttpUtility.HtmlEncode(_htmlSanitizer.Sanitize(value)));
|
|
||||||
}
|
|
||||||
|
|
||||||
public IHtmlContent Json(object model)
|
public IHtmlContent Json(object model)
|
||||||
{
|
{
|
||||||
return _htmlHelper.Raw(_jsonHelper.Serialize(model));
|
return _htmlHelper.Raw(_jsonHelper.Serialize(model));
|
||||||
}
|
}
|
||||||
|
|
||||||
public IHtmlContent Meta(string inputHtml) => _htmlHelper.Raw(RawMeta(inputHtml, out _));
|
|
||||||
|
|
||||||
public string RawMeta(string inputHtml, out bool isHtmlModified)
|
|
||||||
{
|
|
||||||
bool bHtmlModified;
|
|
||||||
HtmlSanitizer sane = new HtmlSanitizer();
|
|
||||||
|
|
||||||
sane.AllowedTags.Clear();
|
|
||||||
sane.AllowedTags.Add("meta");
|
|
||||||
|
|
||||||
sane.AllowedAttributes.Clear();
|
|
||||||
sane.AllowedAttributes.Add("name");
|
|
||||||
sane.AllowedAttributes.Add("http-equiv");
|
|
||||||
sane.AllowedAttributes.Add("content");
|
|
||||||
sane.AllowedAttributes.Add("value");
|
|
||||||
sane.AllowedAttributes.Add("property");
|
|
||||||
|
|
||||||
sane.AllowDataAttributes = false;
|
|
||||||
|
|
||||||
sane.RemovingTag += (sender, e) => bHtmlModified = true;
|
|
||||||
sane.RemovingAtRule += (sender, e) => bHtmlModified = true;
|
|
||||||
sane.RemovingAttribute += (sender, e) => bHtmlModified = true;
|
|
||||||
sane.RemovingComment += (sender, e) => bHtmlModified = true;
|
|
||||||
sane.RemovingCssClass += (sender, e) => bHtmlModified = true;
|
|
||||||
sane.RemovingStyle += (sender, e) => bHtmlModified = true;
|
|
||||||
|
|
||||||
bHtmlModified = false;
|
|
||||||
|
|
||||||
var sRet = sane.Sanitize(inputHtml);
|
|
||||||
isHtmlModified = bHtmlModified;
|
|
||||||
|
|
||||||
return sRet;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1,11 +1,9 @@
|
|||||||
using System;
|
|
||||||
using BTCPayServer.Abstractions.Contracts;
|
using BTCPayServer.Abstractions.Contracts;
|
||||||
|
|
||||||
namespace BTCPayServer.Abstractions.Services
|
namespace BTCPayServer.Abstractions.Services
|
||||||
{
|
{
|
||||||
public class UIExtension : IUIExtension
|
public class UIExtension : IUIExtension
|
||||||
{
|
{
|
||||||
[Obsolete("Use extension method BTCPayServer.Extensions.AddUIExtension(this IServiceCollection services, string location, string partialViewName) instead")]
|
|
||||||
public UIExtension(string partial, string location)
|
public UIExtension(string partial, string location)
|
||||||
{
|
{
|
||||||
Partial = partial;
|
Partial = partial;
|
||||||
|
@@ -2,93 +2,47 @@ using System.Threading.Tasks;
|
|||||||
using Microsoft.AspNetCore.Authorization;
|
using Microsoft.AspNetCore.Authorization;
|
||||||
using Microsoft.AspNetCore.Http;
|
using Microsoft.AspNetCore.Http;
|
||||||
using Microsoft.AspNetCore.Razor.TagHelpers;
|
using Microsoft.AspNetCore.Razor.TagHelpers;
|
||||||
using System;
|
using Microsoft.Extensions.Logging;
|
||||||
using System.Linq;
|
|
||||||
|
|
||||||
namespace BTCPayServer.Abstractions.TagHelpers;
|
namespace BTCPayServer.Abstractions.TagHelpers;
|
||||||
|
|
||||||
[HtmlTargetElement(Attributes = "[permission]")]
|
[HtmlTargetElement(Attributes = nameof(Permission))]
|
||||||
[HtmlTargetElement(Attributes = "[not-permission]")]
|
|
||||||
public class PermissionTagHelper : TagHelper
|
public class PermissionTagHelper : TagHelper
|
||||||
{
|
{
|
||||||
private readonly IAuthorizationService _authorizationService;
|
private readonly IAuthorizationService _authorizationService;
|
||||||
private readonly IHttpContextAccessor _httpContextAccessor;
|
private readonly IHttpContextAccessor _httpContextAccessor;
|
||||||
|
private readonly ILogger<PermissionTagHelper> _logger;
|
||||||
|
|
||||||
public PermissionTagHelper(IAuthorizationService authorizationService, IHttpContextAccessor httpContextAccessor)
|
public PermissionTagHelper(IAuthorizationService authorizationService, IHttpContextAccessor httpContextAccessor, ILogger<PermissionTagHelper> logger)
|
||||||
{
|
{
|
||||||
_authorizationService = authorizationService;
|
_authorizationService = authorizationService;
|
||||||
_httpContextAccessor = httpContextAccessor;
|
_httpContextAccessor = httpContextAccessor;
|
||||||
|
_logger = logger;
|
||||||
}
|
}
|
||||||
|
|
||||||
public string Permission { get; set; }
|
public string Permission { get; set; }
|
||||||
public string NotPermission { get; set; }
|
|
||||||
public string PermissionResource { get; set; }
|
public string PermissionResource { get; set; }
|
||||||
public bool AndMode { get; set; } = false;
|
|
||||||
|
|
||||||
public override async Task ProcessAsync(TagHelperContext context, TagHelperOutput output)
|
public override async Task ProcessAsync(TagHelperContext context, TagHelperOutput output)
|
||||||
{
|
{
|
||||||
var permissions = Permission?.Split(',', StringSplitOptions.RemoveEmptyEntries) ?? Array.Empty<string>();
|
if (string.IsNullOrEmpty(Permission))
|
||||||
var notPermissions = NotPermission?.Split(',', StringSplitOptions.RemoveEmptyEntries) ?? Array.Empty<string>();
|
|
||||||
|
|
||||||
if (!permissions.Any() && !notPermissions.Any())
|
|
||||||
return;
|
return;
|
||||||
if (_httpContextAccessor.HttpContext is null)
|
if (_httpContextAccessor.HttpContext is null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
bool shouldRender = true; // Assume tag should be rendered unless a check fails
|
var key = $"{Permission}_{PermissionResource}";
|
||||||
|
if (!_httpContextAccessor.HttpContext.Items.TryGetValue(key, out var o) ||
|
||||||
// Process 'Permission' - User must have these permissions
|
o is not AuthorizationResult res)
|
||||||
if (permissions.Any())
|
|
||||||
{
|
{
|
||||||
bool finalResult = AndMode;
|
res = await _authorizationService.AuthorizeAsync(_httpContextAccessor.HttpContext.User,
|
||||||
foreach (var perm in permissions)
|
PermissionResource,
|
||||||
{
|
Permission);
|
||||||
var key = $"{perm}_{PermissionResource}";
|
_httpContextAccessor.HttpContext.Items.Add(key, res);
|
||||||
AuthorizationResult res = await GetOrAddAuthorizationResult(key, perm);
|
|
||||||
|
|
||||||
if (AndMode)
|
|
||||||
finalResult &= res.Succeeded;
|
|
||||||
else
|
|
||||||
finalResult |= res.Succeeded;
|
|
||||||
|
|
||||||
if (!AndMode && finalResult) break;
|
|
||||||
}
|
|
||||||
|
|
||||||
shouldRender = finalResult;
|
|
||||||
}
|
}
|
||||||
|
if (!res.Succeeded)
|
||||||
// Process 'NotPermission' - User must not have these permissions
|
|
||||||
if (shouldRender && notPermissions.Any())
|
|
||||||
{
|
|
||||||
foreach (var notPerm in notPermissions)
|
|
||||||
{
|
|
||||||
var key = $"{notPerm}_{PermissionResource}";
|
|
||||||
AuthorizationResult res = await GetOrAddAuthorizationResult(key, notPerm);
|
|
||||||
|
|
||||||
if (res.Succeeded) // If the user has a 'NotPermission', they should not see the tag
|
|
||||||
{
|
|
||||||
shouldRender = false;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!shouldRender)
|
|
||||||
{
|
{
|
||||||
output.SuppressOutput();
|
output.SuppressOutput();
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
private async Task<AuthorizationResult> GetOrAddAuthorizationResult(string key, string permission)
|
|
||||||
{
|
|
||||||
if (!_httpContextAccessor.HttpContext.Items.TryGetValue(key, out var cachedResult))
|
|
||||||
{
|
|
||||||
var res = await _authorizationService.AuthorizeAsync(_httpContextAccessor.HttpContext.User,
|
|
||||||
PermissionResource, permission);
|
|
||||||
_httpContextAccessor.HttpContext.Items[key] = res;
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
return cachedResult as AuthorizationResult;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1,35 +0,0 @@
|
|||||||
using System.Text.RegularExpressions;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using Microsoft.AspNetCore.Authorization;
|
|
||||||
using Microsoft.AspNetCore.Http;
|
|
||||||
using Microsoft.AspNetCore.Razor.TagHelpers;
|
|
||||||
|
|
||||||
namespace BTCPayServer.Abstractions.TagHelpers;
|
|
||||||
|
|
||||||
[HtmlTargetElement("form", Attributes = "[permissioned]")]
|
|
||||||
public partial class PermissionedFormTagHelper(
|
|
||||||
IAuthorizationService authorizationService,
|
|
||||||
IHttpContextAccessor httpContextAccessor)
|
|
||||||
: TagHelper
|
|
||||||
{
|
|
||||||
public string Permissioned { get; set; }
|
|
||||||
public string PermissionResource { get; set; }
|
|
||||||
|
|
||||||
public override async Task ProcessAsync(TagHelperContext context, TagHelperOutput output)
|
|
||||||
{
|
|
||||||
if (httpContextAccessor.HttpContext is null || string.IsNullOrEmpty(Permissioned))
|
|
||||||
return;
|
|
||||||
|
|
||||||
var res = await authorizationService.AuthorizeAsync(httpContextAccessor.HttpContext.User,
|
|
||||||
PermissionResource, Permissioned);
|
|
||||||
if (!res.Succeeded)
|
|
||||||
{
|
|
||||||
var content = await output.GetChildContentAsync();
|
|
||||||
var html = SubmitButtonRegex().Replace(content.GetContent(), "");
|
|
||||||
output.Content.SetHtmlContent($"<fieldset disabled>{html}</fieldset>");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
[GeneratedRegex("<(button|input).*?type=\"submit\".*?>.*?</\\1>")]
|
|
||||||
private static partial Regex SubmitButtonRegex();
|
|
||||||
}
|
|
@@ -12,11 +12,9 @@
|
|||||||
<PackageLicenseExpression>MIT</PackageLicenseExpression>
|
<PackageLicenseExpression>MIT</PackageLicenseExpression>
|
||||||
<RepositoryUrl>https://github.com/btcpayserver/btcpayserver</RepositoryUrl>
|
<RepositoryUrl>https://github.com/btcpayserver/btcpayserver</RepositoryUrl>
|
||||||
<RepositoryType>git</RepositoryType>
|
<RepositoryType>git</RepositoryType>
|
||||||
<Configurations>Debug;Release</Configurations>
|
|
||||||
<Platforms>AnyCPU</Platforms>
|
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<Version Condition=" '$(Version)' == '' ">2.0.1</Version>
|
<Version Condition=" '$(Version)' == '' ">1.7.2</Version>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition=" '$(Configuration)' == 'Release' ">
|
<PropertyGroup Condition=" '$(Configuration)' == 'Release' ">
|
||||||
<PublishRepositoryUrl>true</PublishRepositoryUrl>
|
<PublishRepositoryUrl>true</PublishRepositoryUrl>
|
||||||
@@ -30,9 +28,9 @@
|
|||||||
<PackageReference Include="Microsoft.SourceLink.GitHub" Version="1.0.0" PrivateAssets="All" />
|
<PackageReference Include="Microsoft.SourceLink.GitHub" Version="1.0.0" PrivateAssets="All" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="BTCPayServer.Lightning.Common" Version="1.5.2" />
|
<PackageReference Include="BTCPayServer.Lightning.Common" Version="1.3.21" />
|
||||||
<PackageReference Include="NBitcoin" Version="7.0.48" />
|
<PackageReference Include="NBitcoin" Version="7.0.24" />
|
||||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
|
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<None Include="icon.png" Pack="true" PackagePath="\" />
|
<None Include="icon.png" Pack="true" PackagePath="\" />
|
||||||
|
@@ -1,44 +1,58 @@
|
|||||||
using System;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
using System.Net.Http;
|
using System.Net.Http;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using BTCPayServer.Client.Models;
|
using BTCPayServer.Client.Models;
|
||||||
|
|
||||||
namespace BTCPayServer.Client;
|
namespace BTCPayServer.Client
|
||||||
|
|
||||||
public partial class BTCPayServerClient
|
|
||||||
{
|
{
|
||||||
public virtual async Task<ApiKeyData> GetCurrentAPIKeyInfo(CancellationToken token = default)
|
public partial class BTCPayServerClient
|
||||||
{
|
{
|
||||||
return await SendHttpRequest<ApiKeyData>("api/v1/api-keys/current", null, HttpMethod.Get, token);
|
public virtual async Task<ApiKeyData> GetCurrentAPIKeyInfo(CancellationToken token = default)
|
||||||
}
|
{
|
||||||
|
var response = await _httpClient.SendAsync(CreateHttpRequest("api/v1/api-keys/current"), token);
|
||||||
|
return await HandleResponse<ApiKeyData>(response);
|
||||||
|
}
|
||||||
|
|
||||||
public virtual async Task<ApiKeyData> CreateAPIKey(CreateApiKeyRequest request, CancellationToken token = default)
|
public virtual async Task<ApiKeyData> CreateAPIKey(CreateApiKeyRequest request, CancellationToken token = default)
|
||||||
{
|
{
|
||||||
if (request == null) throw new ArgumentNullException(nameof(request));
|
if (request == null)
|
||||||
return await SendHttpRequest<ApiKeyData>("api/v1/api-keys", request, HttpMethod.Post, token);
|
throw new ArgumentNullException(nameof(request));
|
||||||
}
|
var response = await _httpClient.SendAsync(CreateHttpRequest("api/v1/api-keys", bodyPayload: request, method: HttpMethod.Post), token);
|
||||||
|
return await HandleResponse<ApiKeyData>(response);
|
||||||
|
}
|
||||||
|
|
||||||
public virtual async Task<ApiKeyData> CreateAPIKey(string userId, CreateApiKeyRequest request, CancellationToken token = default)
|
public virtual async Task<ApiKeyData> CreateAPIKey(string userId, CreateApiKeyRequest request, CancellationToken token = default)
|
||||||
{
|
{
|
||||||
if (request == null) throw new ArgumentNullException(nameof(request));
|
if (request == null)
|
||||||
return await SendHttpRequest<ApiKeyData>($"api/v1/users/{userId}/api-keys", request, HttpMethod.Post, token);
|
throw new ArgumentNullException(nameof(request));
|
||||||
}
|
var response = await _httpClient.SendAsync(CreateHttpRequest($"api/v1/users/{userId}/api-keys",
|
||||||
|
bodyPayload: request, method: HttpMethod.Post), token);
|
||||||
|
return await HandleResponse<ApiKeyData>(response);
|
||||||
|
}
|
||||||
|
|
||||||
public virtual async Task RevokeCurrentAPIKeyInfo(CancellationToken token = default)
|
public virtual async Task RevokeCurrentAPIKeyInfo(CancellationToken token = default)
|
||||||
{
|
{
|
||||||
await SendHttpRequest("api/v1/api-keys/current", null, HttpMethod.Delete, token);
|
var response = await _httpClient.SendAsync(CreateHttpRequest("api/v1/api-keys/current", null, HttpMethod.Delete), token);
|
||||||
}
|
await HandleResponse(response);
|
||||||
|
}
|
||||||
|
|
||||||
public virtual async Task RevokeAPIKey(string apikey, CancellationToken token = default)
|
public virtual async Task RevokeAPIKey(string apikey, CancellationToken token = default)
|
||||||
{
|
{
|
||||||
if (apikey == null) throw new ArgumentNullException(nameof(apikey));
|
if (apikey == null)
|
||||||
await SendHttpRequest($"api/v1/api-keys/{apikey}", null, HttpMethod.Delete, token);
|
throw new ArgumentNullException(nameof(apikey));
|
||||||
}
|
var response = await _httpClient.SendAsync(CreateHttpRequest($"api/v1/api-keys/{apikey}", null, HttpMethod.Delete), token);
|
||||||
public virtual async Task RevokeAPIKey(string userId, string apikey, CancellationToken token = default)
|
await HandleResponse(response);
|
||||||
{
|
}
|
||||||
if (apikey == null) throw new ArgumentNullException(nameof(apikey));
|
public virtual async Task RevokeAPIKey(string userId, string apikey, CancellationToken token = default)
|
||||||
if (userId is null) throw new ArgumentNullException(nameof(userId));
|
{
|
||||||
await SendHttpRequest($"api/v1/users/{userId}/api-keys/{apikey}", null, HttpMethod.Delete, token);
|
if (apikey == null)
|
||||||
|
throw new ArgumentNullException(nameof(apikey));
|
||||||
|
if (userId is null)
|
||||||
|
throw new ArgumentNullException(nameof(userId));
|
||||||
|
var response = await _httpClient.SendAsync(CreateHttpRequest($"api/v1/users/{userId}/api-keys/{apikey}", null, HttpMethod.Delete), token);
|
||||||
|
await HandleResponse(response);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1,91 +1,103 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Net.Http;
|
using System.Net.Http;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using BTCPayServer.Client.Models;
|
using BTCPayServer.Client.Models;
|
||||||
|
|
||||||
namespace BTCPayServer.Client;
|
namespace BTCPayServer.Client
|
||||||
|
|
||||||
public partial class BTCPayServerClient
|
|
||||||
{
|
{
|
||||||
public virtual async Task<PointOfSaleAppData> CreatePointOfSaleApp(string storeId,
|
public partial class BTCPayServerClient
|
||||||
PointOfSaleAppRequest request, CancellationToken token = default)
|
|
||||||
{
|
{
|
||||||
if (request == null) throw new ArgumentNullException(nameof(request));
|
|
||||||
return await SendHttpRequest<PointOfSaleAppData>($"api/v1/stores/{storeId}/apps/pos", request, HttpMethod.Post, token);
|
|
||||||
}
|
|
||||||
|
|
||||||
public virtual async Task<CrowdfundAppData> CreateCrowdfundApp(string storeId,
|
public virtual async Task<PointOfSaleAppData> CreatePointOfSaleApp(string storeId,
|
||||||
CrowdfundAppRequest request, CancellationToken token = default)
|
CreatePointOfSaleAppRequest request, CancellationToken token = default)
|
||||||
{
|
{
|
||||||
if (request == null) throw new ArgumentNullException(nameof(request));
|
if (request == null)
|
||||||
return await SendHttpRequest<CrowdfundAppData>($"api/v1/stores/{storeId}/apps/crowdfund", request, HttpMethod.Post, token);
|
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<PointOfSaleAppData> UpdatePointOfSaleApp(string appId,
|
public virtual async Task<CrowdfundAppData> CreateCrowdfundApp(string storeId,
|
||||||
PointOfSaleAppRequest request, CancellationToken token = default)
|
CreateCrowdfundAppRequest request, CancellationToken token = default)
|
||||||
{
|
{
|
||||||
if (request == null) throw new ArgumentNullException(nameof(request));
|
if (request == null)
|
||||||
return await SendHttpRequest<PointOfSaleAppData>($"api/v1/apps/pos/{appId}", request, HttpMethod.Put, token);
|
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<AppBaseData> GetApp(string appId, CancellationToken token = default)
|
public virtual async Task<PointOfSaleAppData> UpdatePointOfSaleApp(string appId,
|
||||||
{
|
CreatePointOfSaleAppRequest request, CancellationToken token = default)
|
||||||
if (appId == null) throw new ArgumentNullException(nameof(appId));
|
{
|
||||||
return await SendHttpRequest<AppBaseData>($"api/v1/apps/{appId}", null, HttpMethod.Get, token);
|
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<AppBaseData[]> GetAllApps(string storeId, CancellationToken token = default)
|
public virtual async Task<AppDataBase> GetApp(string appId, CancellationToken token = default)
|
||||||
{
|
{
|
||||||
if (storeId == null) throw new ArgumentNullException(nameof(storeId));
|
if (appId == null)
|
||||||
return await SendHttpRequest<AppBaseData[]>($"api/v1/stores/{storeId}/apps", null, HttpMethod.Get, token);
|
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<AppBaseData[]> GetAllApps(CancellationToken token = default)
|
public virtual async Task<AppDataBase[]> GetAllApps(string storeId, CancellationToken token = default)
|
||||||
{
|
{
|
||||||
return await SendHttpRequest<AppBaseData[]>("api/v1/apps", null, HttpMethod.Get, token);
|
if (storeId == null)
|
||||||
}
|
throw new ArgumentNullException(nameof(storeId));
|
||||||
|
var response = await _httpClient.SendAsync(
|
||||||
|
CreateHttpRequest($"api/v1/stores/{storeId}/apps",
|
||||||
|
method: HttpMethod.Get), token);
|
||||||
|
return await HandleResponse<AppDataBase[]>(response);
|
||||||
|
}
|
||||||
|
|
||||||
public virtual async Task<PointOfSaleAppData> GetPosApp(string appId, CancellationToken token = default)
|
public virtual async Task<AppDataBase[]> GetAllApps(CancellationToken token = default)
|
||||||
{
|
{
|
||||||
if (appId == null) throw new ArgumentNullException(nameof(appId));
|
var response = await _httpClient.SendAsync(
|
||||||
return await SendHttpRequest<PointOfSaleAppData>($"api/v1/apps/pos/{appId}", null, HttpMethod.Get, token);
|
CreateHttpRequest($"api/v1/apps",
|
||||||
}
|
method: HttpMethod.Get), token);
|
||||||
|
return await HandleResponse<AppDataBase[]>(response);
|
||||||
|
}
|
||||||
|
|
||||||
public virtual async Task<CrowdfundAppData> GetCrowdfundApp(string appId, CancellationToken token = default)
|
public virtual async Task<PointOfSaleAppData> GetPosApp(string appId, CancellationToken token = default)
|
||||||
{
|
{
|
||||||
if (appId == null) throw new ArgumentNullException(nameof(appId));
|
if (appId == null)
|
||||||
return await SendHttpRequest<CrowdfundAppData>($"api/v1/apps/crowdfund/{appId}", null, HttpMethod.Get, token);
|
throw new ArgumentNullException(nameof(appId));
|
||||||
}
|
var response = await _httpClient.SendAsync(
|
||||||
|
CreateHttpRequest($"api/v1/apps/pos/{appId}",
|
||||||
|
method: HttpMethod.Get), token);
|
||||||
|
return await HandleResponse<PointOfSaleAppData>(response);
|
||||||
|
}
|
||||||
|
|
||||||
public virtual async Task<AppSalesStats> GetAppSales(string appId, int numberOfDays = 7, CancellationToken token = default)
|
public virtual async Task<CrowdfundAppData> GetCrowdfundApp(string appId, CancellationToken token = default)
|
||||||
{
|
{
|
||||||
if (appId == null) throw new ArgumentNullException(nameof(appId));
|
if (appId == null)
|
||||||
var queryPayload = new Dictionary<string, object> { { nameof(numberOfDays), numberOfDays } };
|
throw new ArgumentNullException(nameof(appId));
|
||||||
return await SendHttpRequest<AppSalesStats>($"api/v1/apps/{appId}/sales", queryPayload, HttpMethod.Get, token);
|
var response = await _httpClient.SendAsync(
|
||||||
}
|
CreateHttpRequest($"api/v1/apps/crowdfund/{appId}",
|
||||||
|
method: HttpMethod.Get), token);
|
||||||
|
return await HandleResponse<CrowdfundAppData>(response);
|
||||||
|
}
|
||||||
|
|
||||||
public virtual async Task<List<AppItemStats>> GetAppTopItems(string appId, int offset = 0, int count = 10, CancellationToken token = default)
|
public virtual async Task DeleteApp(string appId, CancellationToken token = default)
|
||||||
{
|
{
|
||||||
if (appId == null) throw new ArgumentNullException(nameof(appId));
|
if (appId == null)
|
||||||
var queryPayload = new Dictionary<string, object> { { nameof(offset), offset }, { nameof(count), count } };
|
throw new ArgumentNullException(nameof(appId));
|
||||||
return await SendHttpRequest<List<AppItemStats>>($"api/v1/apps/{appId}/top-items", queryPayload, HttpMethod.Get, token);
|
var response = await _httpClient.SendAsync(
|
||||||
}
|
CreateHttpRequest($"api/v1/apps/{appId}",
|
||||||
|
method: HttpMethod.Delete), token);
|
||||||
public virtual async Task DeleteApp(string appId, CancellationToken token = default)
|
await HandleResponse(response);
|
||||||
{
|
}
|
||||||
if (appId == null) throw new ArgumentNullException(nameof(appId));
|
|
||||||
await SendHttpRequest($"api/v1/apps/{appId}", null, HttpMethod.Delete, token);
|
|
||||||
}
|
|
||||||
|
|
||||||
public virtual async Task<FileData> UploadAppItemImage(string appId, string filePath, string mimeType, CancellationToken token = default)
|
|
||||||
{
|
|
||||||
return await UploadFileRequest<FileData>($"api/v1/apps/{appId}/image", filePath, mimeType, "file", HttpMethod.Post, token);
|
|
||||||
}
|
|
||||||
|
|
||||||
public virtual async Task DeleteAppItemImage(string appId, string fileId, CancellationToken token = default)
|
|
||||||
{
|
|
||||||
await SendHttpRequest($"api/v1/apps/{appId}/image/{fileId}", null, HttpMethod.Delete, token);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1,29 +1,34 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
namespace BTCPayServer.Client;
|
namespace BTCPayServer.Client
|
||||||
|
|
||||||
public partial class BTCPayServerClient
|
|
||||||
{
|
{
|
||||||
public static Uri GenerateAuthorizeUri(Uri btcpayHost, string[] permissions, bool strict = true,
|
public partial class BTCPayServerClient
|
||||||
bool selectiveStores = false, (string ApplicationIdentifier, Uri Redirect) applicationDetails = default)
|
|
||||||
{
|
{
|
||||||
var result = new UriBuilder(btcpayHost) { Path = "api-keys/authorize" };
|
|
||||||
AppendPayloadToQuery(result,
|
|
||||||
new Dictionary<string, object>
|
|
||||||
{
|
|
||||||
{"strict", strict}, {"selectiveStores", selectiveStores}, {"permissions", permissions}
|
|
||||||
});
|
|
||||||
|
|
||||||
if (applicationDetails.Redirect != null)
|
public static Uri GenerateAuthorizeUri(Uri btcpayHost, string[] permissions, bool strict = true,
|
||||||
|
bool selectiveStores = false, (string ApplicationIdentifier, Uri Redirect) applicationDetails = default)
|
||||||
{
|
{
|
||||||
AppendPayloadToQuery(result, new KeyValuePair<string, object>("redirect", applicationDetails.Redirect));
|
var result = new UriBuilder(btcpayHost);
|
||||||
if (!string.IsNullOrEmpty(applicationDetails.ApplicationIdentifier))
|
result.Path = "api-keys/authorize";
|
||||||
{
|
|
||||||
AppendPayloadToQuery(result, new KeyValuePair<string, object>("applicationIdentifier", applicationDetails.ApplicationIdentifier));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return result.Uri;
|
AppendPayloadToQuery(result,
|
||||||
|
new Dictionary<string, object>()
|
||||||
|
{
|
||||||
|
{"strict", strict}, {"selectiveStores", selectiveStores}, {"permissions", permissions}
|
||||||
|
});
|
||||||
|
|
||||||
|
if (applicationDetails.Redirect != null)
|
||||||
|
{
|
||||||
|
AppendPayloadToQuery(result, new KeyValuePair<string, object>("redirect", applicationDetails.Redirect));
|
||||||
|
if (!string.IsNullOrEmpty(applicationDetails.ApplicationIdentifier))
|
||||||
|
{
|
||||||
|
AppendPayloadToQuery(result, new KeyValuePair<string, object>("applicationIdentifier", applicationDetails.ApplicationIdentifier));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result.Uri;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
102
BTCPayServer.Client/BTCPayServerClient.CustodianAccounts.cs
Normal file
102
BTCPayServer.Client/BTCPayServerClient.CustodianAccounts.cs
Normal file
@@ -0,0 +1,102 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Net.Http;
|
||||||
|
using System.Threading;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using BTCPayServer.Client.Models;
|
||||||
|
|
||||||
|
namespace BTCPayServer.Client
|
||||||
|
{
|
||||||
|
public partial class BTCPayServerClient
|
||||||
|
{
|
||||||
|
public virtual async Task<IEnumerable<CustodianAccountData>> GetCustodianAccounts(string storeId, bool includeAssetBalances = false, CancellationToken token = default)
|
||||||
|
{
|
||||||
|
var queryPayload = new Dictionary<string, object>();
|
||||||
|
if (includeAssetBalances)
|
||||||
|
{
|
||||||
|
queryPayload.Add("assetBalances", "true");
|
||||||
|
}
|
||||||
|
|
||||||
|
var response = await _httpClient.SendAsync(CreateHttpRequest($"api/v1/stores/{storeId}/custodian-accounts", queryPayload), token);
|
||||||
|
return await HandleResponse<IEnumerable<CustodianAccountData>>(response);
|
||||||
|
}
|
||||||
|
|
||||||
|
public virtual async Task<CustodianAccountResponse> GetCustodianAccount(string storeId, string accountId, bool includeAssetBalances = false, CancellationToken token = default)
|
||||||
|
{
|
||||||
|
var queryPayload = new Dictionary<string, object>();
|
||||||
|
if (includeAssetBalances)
|
||||||
|
{
|
||||||
|
queryPayload.Add("assetBalances", "true");
|
||||||
|
}
|
||||||
|
|
||||||
|
var response = await _httpClient.SendAsync(CreateHttpRequest($"api/v1/stores/{storeId}/custodian-accounts/{accountId}", queryPayload), token);
|
||||||
|
return await HandleResponse<CustodianAccountResponse>(response);
|
||||||
|
}
|
||||||
|
|
||||||
|
public virtual async Task<CustodianAccountData> CreateCustodianAccount(string storeId, CreateCustodianAccountRequest request, CancellationToken token = default)
|
||||||
|
{
|
||||||
|
var response = await _httpClient.SendAsync(CreateHttpRequest($"api/v1/stores/{storeId}/custodian-accounts", bodyPayload: request, method: HttpMethod.Post), token);
|
||||||
|
return await HandleResponse<CustodianAccountData>(response);
|
||||||
|
}
|
||||||
|
|
||||||
|
public virtual async Task<CustodianAccountData> UpdateCustodianAccount(string storeId, string accountId, CreateCustodianAccountRequest request, CancellationToken token = default)
|
||||||
|
{
|
||||||
|
var response = await _httpClient.SendAsync(CreateHttpRequest($"api/v1/stores/{storeId}/custodian-accounts/{accountId}", bodyPayload: request, method: HttpMethod.Put), token);
|
||||||
|
return await HandleResponse<CustodianAccountData>(response);
|
||||||
|
}
|
||||||
|
|
||||||
|
public virtual async Task DeleteCustodianAccount(string storeId, string accountId, CancellationToken token = default)
|
||||||
|
{
|
||||||
|
var response = await _httpClient.SendAsync(CreateHttpRequest($"api/v1/stores/{storeId}/custodian-accounts/{accountId}", method: HttpMethod.Delete), token);
|
||||||
|
await HandleResponse(response);
|
||||||
|
}
|
||||||
|
|
||||||
|
public virtual async Task<DepositAddressData> GetCustodianAccountDepositAddress(string storeId, string accountId, string paymentMethod, CancellationToken token = default)
|
||||||
|
{
|
||||||
|
var response = await _httpClient.SendAsync(CreateHttpRequest($"api/v1/stores/{storeId}/custodian-accounts/{accountId}/addresses/{paymentMethod}"), token);
|
||||||
|
return await HandleResponse<DepositAddressData>(response);
|
||||||
|
}
|
||||||
|
|
||||||
|
public virtual async Task<MarketTradeResponseData> MarketTradeCustodianAccountAsset(string storeId, string accountId, TradeRequestData request, CancellationToken token = default)
|
||||||
|
{
|
||||||
|
//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);
|
||||||
|
}
|
||||||
|
|
||||||
|
public virtual async Task<MarketTradeResponseData> GetCustodianAccountTradeInfo(string storeId, string accountId, string tradeId, CancellationToken token = default)
|
||||||
|
{
|
||||||
|
var response = await _httpClient.SendAsync(CreateHttpRequest($"api/v1/stores/{storeId}/custodian-accounts/{accountId}/trades/{tradeId}", method: HttpMethod.Get), token);
|
||||||
|
return await HandleResponse<MarketTradeResponseData>(response);
|
||||||
|
}
|
||||||
|
|
||||||
|
public virtual async Task<TradeQuoteResponseData> GetCustodianAccountTradeQuote(string storeId, string accountId, string fromAsset, string toAsset, CancellationToken token = default)
|
||||||
|
{
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
public virtual async Task<WithdrawalResponseData> CreateCustodianAccountWithdrawal(string storeId, string accountId, WithdrawRequestData request, CancellationToken token = default)
|
||||||
|
{
|
||||||
|
var response = await _httpClient.SendAsync(CreateHttpRequest($"api/v1/stores/{storeId}/custodian-accounts/{accountId}/withdrawals", bodyPayload: request, method: HttpMethod.Post), token);
|
||||||
|
return await HandleResponse<WithdrawalResponseData>(response);
|
||||||
|
}
|
||||||
|
|
||||||
|
public virtual async Task<WithdrawalSimulationResponseData> SimulateCustodianAccountWithdrawal(string storeId, string accountId, WithdrawRequestData request, CancellationToken token = default)
|
||||||
|
{
|
||||||
|
var response = await _httpClient.SendAsync(CreateHttpRequest($"api/v1/stores/{storeId}/custodian-accounts/{accountId}/withdrawals/simulation", bodyPayload: request, method: HttpMethod.Post), token);
|
||||||
|
return await HandleResponse<WithdrawalSimulationResponseData>(response);
|
||||||
|
}
|
||||||
|
|
||||||
|
public virtual async Task<WithdrawalResponseData> GetCustodianAccountWithdrawalInfo(string storeId, string accountId, string paymentMethod, string withdrawalId, CancellationToken token = default)
|
||||||
|
{
|
||||||
|
var response = await _httpClient.SendAsync(CreateHttpRequest($"api/v1/stores/{storeId}/custodian-accounts/{accountId}/withdrawals/{paymentMethod}/{withdrawalId}", method: HttpMethod.Get), token);
|
||||||
|
return await HandleResponse<WithdrawalResponseData>(response);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
16
BTCPayServer.Client/BTCPayServerClient.Custodians.cs
Normal file
16
BTCPayServer.Client/BTCPayServerClient.Custodians.cs
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Threading;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using BTCPayServer.Client.Models;
|
||||||
|
|
||||||
|
namespace BTCPayServer.Client
|
||||||
|
{
|
||||||
|
public partial class BTCPayServerClient
|
||||||
|
{
|
||||||
|
public virtual async Task<IEnumerable<CustodianData>> GetCustodians(CancellationToken token = default)
|
||||||
|
{
|
||||||
|
var response = await _httpClient.SendAsync(CreateHttpRequest("api/v1/custodians"), token);
|
||||||
|
return await HandleResponse<IEnumerable<CustodianData>>(response);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -1,29 +0,0 @@
|
|||||||
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<FileData[]> GetFiles(CancellationToken token = default)
|
|
||||||
{
|
|
||||||
return await SendHttpRequest<FileData[]>("api/v1/files", null, HttpMethod.Get, token);
|
|
||||||
}
|
|
||||||
|
|
||||||
public virtual async Task<FileData> GetFile(string fileId, CancellationToken token = default)
|
|
||||||
{
|
|
||||||
return await SendHttpRequest<FileData>($"api/v1/files/{fileId}", null, HttpMethod.Get, token);
|
|
||||||
}
|
|
||||||
|
|
||||||
public virtual async Task<FileData> UploadFile(string filePath, string mimeType, CancellationToken token = default)
|
|
||||||
{
|
|
||||||
return await UploadFileRequest<FileData>("api/v1/files", filePath, mimeType, "file", HttpMethod.Post, token);
|
|
||||||
}
|
|
||||||
|
|
||||||
public virtual async Task DeleteFile(string fileId, CancellationToken token = default)
|
|
||||||
{
|
|
||||||
await SendHttpRequest($"api/v1/files/{fileId}", null, HttpMethod.Delete, token);
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,14 +1,15 @@
|
|||||||
using System.Net.Http;
|
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using BTCPayServer.Client.Models;
|
using BTCPayServer.Client.Models;
|
||||||
|
|
||||||
namespace BTCPayServer.Client;
|
namespace BTCPayServer.Client
|
||||||
|
|
||||||
public partial class BTCPayServerClient
|
|
||||||
{
|
{
|
||||||
public virtual async Task<ApiHealthData> GetHealth(CancellationToken token = default)
|
public partial class BTCPayServerClient
|
||||||
{
|
{
|
||||||
return await SendHttpRequest<ApiHealthData>("api/v1/health", null, HttpMethod.Get, token);
|
public virtual async Task<ApiHealthData> GetHealth(CancellationToken token = default)
|
||||||
|
{
|
||||||
|
var response = await _httpClient.SendAsync(CreateHttpRequest("api/v1/health"), token);
|
||||||
|
return await HandleResponse<ApiHealthData>(response);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -7,101 +7,139 @@ using System.Threading.Tasks;
|
|||||||
using BTCPayServer.Client.Models;
|
using BTCPayServer.Client.Models;
|
||||||
using NBitcoin;
|
using NBitcoin;
|
||||||
|
|
||||||
namespace BTCPayServer.Client;
|
namespace BTCPayServer.Client
|
||||||
|
|
||||||
public partial class BTCPayServerClient
|
|
||||||
{
|
{
|
||||||
public virtual async Task<IEnumerable<InvoiceData>> GetInvoices(string storeId, string[] orderId = null,
|
public partial class BTCPayServerClient
|
||||||
InvoiceStatus[] status = null,
|
|
||||||
DateTimeOffset? startDate = null,
|
|
||||||
DateTimeOffset? endDate = null,
|
|
||||||
string textSearch = null,
|
|
||||||
bool includeArchived = false,
|
|
||||||
int? skip = null,
|
|
||||||
int? take = null,
|
|
||||||
CancellationToken token = default)
|
|
||||||
{
|
{
|
||||||
var queryPayload = new Dictionary<string, object> { { nameof(includeArchived), includeArchived } };
|
public virtual async Task<IEnumerable<InvoiceData>> GetInvoices(string storeId, string[] orderId = null,
|
||||||
if (startDate is { } s)
|
InvoiceStatus[] status = null,
|
||||||
queryPayload.Add(nameof(startDate), Utils.DateTimeToUnixTime(s));
|
DateTimeOffset? startDate = null,
|
||||||
if (endDate is { } e)
|
DateTimeOffset? endDate = null,
|
||||||
queryPayload.Add(nameof(endDate), Utils.DateTimeToUnixTime(e));
|
string textSearch = null,
|
||||||
if (orderId != null)
|
bool includeArchived = false,
|
||||||
queryPayload.Add(nameof(orderId), orderId);
|
int? skip = null,
|
||||||
if (textSearch != null)
|
int? take = null,
|
||||||
queryPayload.Add(nameof(textSearch), textSearch);
|
CancellationToken token = default)
|
||||||
if (status != null)
|
|
||||||
queryPayload.Add(nameof(status), status.Select(s => s.ToString().ToLower()).ToArray());
|
|
||||||
if (skip != null)
|
|
||||||
queryPayload.Add(nameof(skip), skip);
|
|
||||||
if (take != null)
|
|
||||||
queryPayload.Add(nameof(take), take);
|
|
||||||
|
|
||||||
return await SendHttpRequest<IEnumerable<InvoiceData>>($"api/v1/stores/{storeId}/invoices", queryPayload, HttpMethod.Get, token);
|
|
||||||
}
|
|
||||||
|
|
||||||
public virtual async Task<InvoiceData> GetInvoice(string storeId, string invoiceId,
|
|
||||||
CancellationToken token = default)
|
|
||||||
{
|
|
||||||
return await SendHttpRequest<InvoiceData>($"api/v1/stores/{storeId}/invoices/{invoiceId}", null, HttpMethod.Get, token);
|
|
||||||
}
|
|
||||||
public virtual async Task<InvoicePaymentMethodDataModel[]> GetInvoicePaymentMethods(string storeId, string invoiceId,
|
|
||||||
bool onlyAccountedPayments = true, bool includeSensitive = false,
|
|
||||||
CancellationToken token = default)
|
|
||||||
{
|
|
||||||
var queryPayload = new Dictionary<string, object>
|
|
||||||
{
|
{
|
||||||
{ nameof(onlyAccountedPayments), onlyAccountedPayments },
|
Dictionary<string, object> queryPayload = new Dictionary<string, object>();
|
||||||
{ nameof(includeSensitive), includeSensitive }
|
queryPayload.Add(nameof(includeArchived), includeArchived);
|
||||||
};
|
|
||||||
return await SendHttpRequest<InvoicePaymentMethodDataModel[]>($"api/v1/stores/{storeId}/invoices/{invoiceId}/payment-methods", queryPayload, HttpMethod.Get, token);
|
|
||||||
}
|
|
||||||
|
|
||||||
public virtual async Task ArchiveInvoice(string storeId, string invoiceId,
|
if (startDate is DateTimeOffset s)
|
||||||
CancellationToken token = default)
|
queryPayload.Add(nameof(startDate), Utils.DateTimeToUnixTime(s));
|
||||||
{
|
|
||||||
await SendHttpRequest($"api/v1/stores/{storeId}/invoices/{invoiceId}", null, HttpMethod.Delete, token);
|
|
||||||
}
|
|
||||||
|
|
||||||
public virtual async Task<InvoiceData> CreateInvoice(string storeId,
|
if (endDate is DateTimeOffset e)
|
||||||
CreateInvoiceRequest request, CancellationToken token = default)
|
queryPayload.Add(nameof(endDate), Utils.DateTimeToUnixTime(e));
|
||||||
{
|
|
||||||
if (request == null) throw new ArgumentNullException(nameof(request));
|
|
||||||
return await SendHttpRequest<InvoiceData>($"api/v1/stores/{storeId}/invoices", request, HttpMethod.Post, token);
|
|
||||||
}
|
|
||||||
|
|
||||||
public virtual async Task<InvoiceData> UpdateInvoice(string storeId, string invoiceId,
|
if (orderId != null)
|
||||||
UpdateInvoiceRequest request, CancellationToken token = default)
|
queryPayload.Add(nameof(orderId), orderId);
|
||||||
{
|
if (textSearch != null)
|
||||||
if (request == null) throw new ArgumentNullException(nameof(request));
|
queryPayload.Add(nameof(textSearch), textSearch);
|
||||||
return await SendHttpRequest<InvoiceData>($"api/v1/stores/{storeId}/invoices/{invoiceId}", request, HttpMethod.Put, token);
|
if (status != null)
|
||||||
}
|
queryPayload.Add(nameof(status), status.Select(s => s.ToString().ToLower()).ToArray());
|
||||||
|
|
||||||
public virtual async Task<InvoiceData> MarkInvoiceStatus(string storeId, string invoiceId,
|
if (skip != null)
|
||||||
MarkInvoiceStatusRequest request, CancellationToken token = default)
|
{
|
||||||
{
|
queryPayload.Add(nameof(skip), skip);
|
||||||
if (request == null) throw new ArgumentNullException(nameof(request));
|
}
|
||||||
if (request.Status != InvoiceStatus.Settled && request.Status != InvoiceStatus.Invalid) throw new ArgumentOutOfRangeException(nameof(request.Status), "Status can only be Invalid or Complete");
|
|
||||||
return await SendHttpRequest<InvoiceData>($"api/v1/stores/{storeId}/invoices/{invoiceId}/status", request, HttpMethod.Post, token);
|
|
||||||
}
|
|
||||||
|
|
||||||
public virtual async Task<InvoiceData> UnarchiveInvoice(string storeId, string invoiceId, CancellationToken token = default)
|
if (take != null)
|
||||||
{
|
{
|
||||||
return await SendHttpRequest<InvoiceData>($"api/v1/stores/{storeId}/invoices/{invoiceId}/unarchive", null, HttpMethod.Post, token);
|
queryPayload.Add(nameof(take), take);
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual async Task ActivateInvoicePaymentMethod(string storeId, string invoiceId, string paymentMethod, CancellationToken token = default)
|
var response =
|
||||||
{
|
await _httpClient.SendAsync(
|
||||||
await SendHttpRequest($"api/v1/stores/{storeId}/invoices/{invoiceId}/payment-methods/{paymentMethod}/activate", null, HttpMethod.Post, token);
|
CreateHttpRequest($"api/v1/stores/{storeId}/invoices",
|
||||||
}
|
queryPayload), token);
|
||||||
|
return await HandleResponse<IEnumerable<InvoiceData>>(response);
|
||||||
|
}
|
||||||
|
|
||||||
public virtual async Task<PullPaymentData> RefundInvoice(
|
public virtual async Task<InvoiceData> GetInvoice(string storeId, string invoiceId,
|
||||||
string storeId,
|
CancellationToken token = default)
|
||||||
string invoiceId,
|
{
|
||||||
RefundInvoiceRequest request,
|
var response = await _httpClient.SendAsync(
|
||||||
CancellationToken token = default
|
CreateHttpRequest($"api/v1/stores/{storeId}/invoices/{invoiceId}"), token);
|
||||||
)
|
return await HandleResponse<InvoiceData>(response);
|
||||||
{
|
}
|
||||||
return await SendHttpRequest<PullPaymentData>($"api/v1/stores/{storeId}/invoices/{invoiceId}/refund", request, HttpMethod.Post, token);
|
public virtual async Task<InvoicePaymentMethodDataModel[]> GetInvoicePaymentMethods(string storeId, string invoiceId,
|
||||||
|
CancellationToken token = default)
|
||||||
|
{
|
||||||
|
var response = await _httpClient.SendAsync(
|
||||||
|
CreateHttpRequest($"api/v1/stores/{storeId}/invoices/{invoiceId}/payment-methods"), token);
|
||||||
|
return await HandleResponse<InvoicePaymentMethodDataModel[]>(response);
|
||||||
|
}
|
||||||
|
|
||||||
|
public virtual async Task ArchiveInvoice(string storeId, string invoiceId,
|
||||||
|
CancellationToken token = default)
|
||||||
|
{
|
||||||
|
var response = await _httpClient.SendAsync(
|
||||||
|
CreateHttpRequest($"api/v1/stores/{storeId}/invoices/{invoiceId}",
|
||||||
|
method: HttpMethod.Delete), token);
|
||||||
|
await HandleResponse(response);
|
||||||
|
}
|
||||||
|
|
||||||
|
public virtual async Task<InvoiceData> CreateInvoice(string storeId,
|
||||||
|
CreateInvoiceRequest request, CancellationToken token = default)
|
||||||
|
{
|
||||||
|
if (request == null)
|
||||||
|
throw new ArgumentNullException(nameof(request));
|
||||||
|
var response = await _httpClient.SendAsync(
|
||||||
|
CreateHttpRequest($"api/v1/stores/{storeId}/invoices", bodyPayload: request,
|
||||||
|
method: HttpMethod.Post), token);
|
||||||
|
return await HandleResponse<InvoiceData>(response);
|
||||||
|
}
|
||||||
|
|
||||||
|
public virtual async Task<InvoiceData> UpdateInvoice(string storeId, string invoiceId,
|
||||||
|
UpdateInvoiceRequest request, CancellationToken token = default)
|
||||||
|
{
|
||||||
|
if (request == null)
|
||||||
|
throw new ArgumentNullException(nameof(request));
|
||||||
|
var response = await _httpClient.SendAsync(
|
||||||
|
CreateHttpRequest($"api/v1/stores/{storeId}/invoices/{invoiceId}", bodyPayload: request,
|
||||||
|
method: HttpMethod.Put), token);
|
||||||
|
return await HandleResponse<InvoiceData>(response);
|
||||||
|
}
|
||||||
|
|
||||||
|
public virtual async Task<InvoiceData> MarkInvoiceStatus(string storeId, string invoiceId,
|
||||||
|
MarkInvoiceStatusRequest request, CancellationToken token = default)
|
||||||
|
{
|
||||||
|
if (request == null)
|
||||||
|
throw new ArgumentNullException(nameof(request));
|
||||||
|
if (request.Status != InvoiceStatus.Settled && request.Status != InvoiceStatus.Invalid)
|
||||||
|
throw new ArgumentOutOfRangeException(nameof(request.Status), "Status can only be Invalid or Complete");
|
||||||
|
var response = await _httpClient.SendAsync(
|
||||||
|
CreateHttpRequest($"api/v1/stores/{storeId}/invoices/{invoiceId}/status", bodyPayload: request,
|
||||||
|
method: HttpMethod.Post), token);
|
||||||
|
return await HandleResponse<InvoiceData>(response);
|
||||||
|
}
|
||||||
|
|
||||||
|
public virtual async Task<InvoiceData> UnarchiveInvoice(string storeId, string invoiceId, CancellationToken token = default)
|
||||||
|
{
|
||||||
|
var response = await _httpClient.SendAsync(
|
||||||
|
CreateHttpRequest($"api/v1/stores/{storeId}/invoices/{invoiceId}/unarchive",
|
||||||
|
method: HttpMethod.Post), token);
|
||||||
|
return await HandleResponse<InvoiceData>(response);
|
||||||
|
}
|
||||||
|
|
||||||
|
public virtual async Task ActivateInvoicePaymentMethod(string storeId, string invoiceId, string paymentMethod, CancellationToken token = default)
|
||||||
|
{
|
||||||
|
var response = await _httpClient.SendAsync(
|
||||||
|
CreateHttpRequest($"api/v1/stores/{storeId}/invoices/{invoiceId}/payment-methods/{paymentMethod}/activate",
|
||||||
|
method: HttpMethod.Post), token);
|
||||||
|
await HandleResponse(response);
|
||||||
|
}
|
||||||
|
|
||||||
|
public virtual async Task<PullPaymentData> RefundInvoice(
|
||||||
|
string storeId,
|
||||||
|
string invoiceId,
|
||||||
|
RefundInvoiceRequest request,
|
||||||
|
CancellationToken token = default
|
||||||
|
)
|
||||||
|
{
|
||||||
|
var response = await _httpClient.SendAsync(
|
||||||
|
CreateHttpRequest($"api/v1/stores/{storeId}/invoices/{invoiceId}/refund", bodyPayload: request,
|
||||||
|
method: HttpMethod.Post), token);
|
||||||
|
return await HandleResponse<PullPaymentData>(response);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -0,0 +1,59 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Net.Http;
|
||||||
|
using System.Threading;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using BTCPayServer.Client.Models;
|
||||||
|
|
||||||
|
namespace BTCPayServer.Client
|
||||||
|
{
|
||||||
|
public partial class BTCPayServerClient
|
||||||
|
{
|
||||||
|
public virtual async Task<IEnumerable<LNURLPayPaymentMethodData>>
|
||||||
|
GetStoreLNURLPayPaymentMethods(string storeId, bool? enabled = null,
|
||||||
|
CancellationToken token = default)
|
||||||
|
{
|
||||||
|
var query = new Dictionary<string, object>();
|
||||||
|
if (enabled != null)
|
||||||
|
{
|
||||||
|
query.Add(nameof(enabled), enabled);
|
||||||
|
}
|
||||||
|
|
||||||
|
var response =
|
||||||
|
await _httpClient.SendAsync(
|
||||||
|
CreateHttpRequest($"api/v1/stores/{storeId}/payment-methods/LNURLPay",
|
||||||
|
query), token);
|
||||||
|
return await HandleResponse<IEnumerable<LNURLPayPaymentMethodData>>(response);
|
||||||
|
}
|
||||||
|
|
||||||
|
public virtual async Task<LNURLPayPaymentMethodData> GetStoreLNURLPayPaymentMethod(
|
||||||
|
string storeId,
|
||||||
|
string cryptoCode, CancellationToken token = default)
|
||||||
|
{
|
||||||
|
var response =
|
||||||
|
await _httpClient.SendAsync(
|
||||||
|
CreateHttpRequest($"api/v1/stores/{storeId}/payment-methods/LNURLPay/{cryptoCode}"), token);
|
||||||
|
return await HandleResponse<LNURLPayPaymentMethodData>(response);
|
||||||
|
}
|
||||||
|
|
||||||
|
public virtual async Task RemoveStoreLNURLPayPaymentMethod(string storeId,
|
||||||
|
string cryptoCode, CancellationToken token = default)
|
||||||
|
{
|
||||||
|
var response =
|
||||||
|
await _httpClient.SendAsync(
|
||||||
|
CreateHttpRequest($"api/v1/stores/{storeId}/payment-methods/LNURLPay/{cryptoCode}",
|
||||||
|
method: HttpMethod.Delete), token);
|
||||||
|
await HandleResponse(response);
|
||||||
|
}
|
||||||
|
|
||||||
|
public virtual async Task<LNURLPayPaymentMethodData> UpdateStoreLNURLPayPaymentMethod(
|
||||||
|
string storeId,
|
||||||
|
string cryptoCode, LNURLPayPaymentMethodData paymentMethod,
|
||||||
|
CancellationToken token = default)
|
||||||
|
{
|
||||||
|
var response = await _httpClient.SendAsync(
|
||||||
|
CreateHttpRequest($"api/v1/stores/{storeId}/payment-methods/LNURLPay/{cryptoCode}",
|
||||||
|
bodyPayload: paymentMethod, method: HttpMethod.Put), token);
|
||||||
|
return await HandleResponse<LNURLPayPaymentMethodData>(response);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -5,108 +5,142 @@ using System.Threading;
|
|||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using BTCPayServer.Client.Models;
|
using BTCPayServer.Client.Models;
|
||||||
|
|
||||||
namespace BTCPayServer.Client;
|
namespace BTCPayServer.Client
|
||||||
|
|
||||||
public partial class BTCPayServerClient
|
|
||||||
{
|
{
|
||||||
public virtual async Task<LightningNodeInformationData> GetLightningNodeInfo(string cryptoCode,
|
public partial class BTCPayServerClient
|
||||||
CancellationToken token = default)
|
|
||||||
{
|
{
|
||||||
return await SendHttpRequest<LightningNodeInformationData>($"api/v1/server/lightning/{cryptoCode}/info", null, HttpMethod.Get, token);
|
public virtual async Task<LightningNodeInformationData> GetLightningNodeInfo(string cryptoCode,
|
||||||
}
|
CancellationToken token = default)
|
||||||
|
|
||||||
public virtual async Task<LightningNodeBalanceData> GetLightningNodeBalance(string cryptoCode,
|
|
||||||
CancellationToken token = default)
|
|
||||||
{
|
|
||||||
return await SendHttpRequest<LightningNodeBalanceData>($"api/v1/server/lightning/{cryptoCode}/balance", null, HttpMethod.Get, token);
|
|
||||||
}
|
|
||||||
|
|
||||||
public virtual async Task<HistogramData> GetLightningNodeHistogram(string cryptoCode, HistogramType? type = null,
|
|
||||||
CancellationToken token = default)
|
|
||||||
{
|
|
||||||
var queryPayload = type == null ? null : new Dictionary<string, object> { { "type", type.ToString() } };
|
|
||||||
return await SendHttpRequest<HistogramData>($"api/v1/server/lightning/{cryptoCode}/histogram", queryPayload, HttpMethod.Get, token);
|
|
||||||
}
|
|
||||||
|
|
||||||
public virtual async Task ConnectToLightningNode(string cryptoCode, ConnectToNodeRequest request,
|
|
||||||
CancellationToken token = default)
|
|
||||||
{
|
|
||||||
if (request == null) throw new ArgumentNullException(nameof(request));
|
|
||||||
await SendHttpRequest($"api/v1/server/lightning/{cryptoCode}/connect", request, HttpMethod.Post, token);
|
|
||||||
}
|
|
||||||
|
|
||||||
public virtual async Task<IEnumerable<LightningChannelData>> GetLightningNodeChannels(string cryptoCode,
|
|
||||||
CancellationToken token = default)
|
|
||||||
{
|
|
||||||
return await SendHttpRequest<IEnumerable<LightningChannelData>>($"api/v1/server/lightning/{cryptoCode}/channels", null, HttpMethod.Get, token);
|
|
||||||
}
|
|
||||||
|
|
||||||
public virtual async Task OpenLightningChannel(string cryptoCode, OpenLightningChannelRequest request,
|
|
||||||
CancellationToken token = default)
|
|
||||||
{
|
|
||||||
await SendHttpRequest($"api/v1/server/lightning/{cryptoCode}/channels", request, HttpMethod.Post, token);
|
|
||||||
}
|
|
||||||
|
|
||||||
public virtual async Task<string> GetLightningDepositAddress(string cryptoCode, CancellationToken token = default)
|
|
||||||
{
|
|
||||||
return await SendHttpRequest<string>($"api/v1/server/lightning/{cryptoCode}/address", null, HttpMethod.Post, token);
|
|
||||||
}
|
|
||||||
|
|
||||||
public virtual async Task<LightningPaymentData> PayLightningInvoice(string cryptoCode, PayLightningInvoiceRequest request,
|
|
||||||
CancellationToken token = default)
|
|
||||||
{
|
|
||||||
if (request == null) throw new ArgumentNullException(nameof(request));
|
|
||||||
return await SendHttpRequest<LightningPaymentData>($"api/v1/server/lightning/{cryptoCode}/invoices/pay", request, HttpMethod.Post, token);
|
|
||||||
}
|
|
||||||
|
|
||||||
public virtual async Task<LightningPaymentData> GetLightningPayment(string cryptoCode,
|
|
||||||
string paymentHash, CancellationToken token = default)
|
|
||||||
{
|
|
||||||
if (paymentHash == null) throw new ArgumentNullException(nameof(paymentHash));
|
|
||||||
return await SendHttpRequest<LightningPaymentData>($"api/v1/server/lightning/{cryptoCode}/payments/{paymentHash}", null, HttpMethod.Get, token);
|
|
||||||
}
|
|
||||||
|
|
||||||
public virtual async Task<LightningInvoiceData> GetLightningInvoice(string cryptoCode,
|
|
||||||
string invoiceId, CancellationToken token = default)
|
|
||||||
{
|
|
||||||
if (invoiceId == null) throw new ArgumentNullException(nameof(invoiceId));
|
|
||||||
return await SendHttpRequest<LightningInvoiceData>($"api/v1/server/lightning/{cryptoCode}/invoices/{invoiceId}", null, HttpMethod.Get, token);
|
|
||||||
}
|
|
||||||
|
|
||||||
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());
|
var response = await _httpClient.SendAsync(
|
||||||
|
CreateHttpRequest($"api/v1/server/lightning/{cryptoCode}/info",
|
||||||
|
method: HttpMethod.Get), token);
|
||||||
|
return await HandleResponse<LightningNodeInformationData>(response);
|
||||||
}
|
}
|
||||||
if (offsetIndex is > 0)
|
|
||||||
{
|
|
||||||
queryPayload.Add("offsetIndex", offsetIndex);
|
|
||||||
}
|
|
||||||
return await SendHttpRequest<LightningInvoiceData[]>($"api/v1/server/lightning/{cryptoCode}/invoices", queryPayload, HttpMethod.Get, token);
|
|
||||||
}
|
|
||||||
|
|
||||||
public virtual async Task<LightningPaymentData[]> GetLightningPayments(string cryptoCode,
|
public virtual async Task<LightningNodeBalanceData> GetLightningNodeBalance(string cryptoCode,
|
||||||
bool? includePending = null, long? offsetIndex = null, CancellationToken token = default)
|
CancellationToken token = default)
|
||||||
{
|
|
||||||
var queryPayload = new Dictionary<string, object>();
|
|
||||||
if (includePending is bool v)
|
|
||||||
{
|
{
|
||||||
queryPayload.Add("includePending", v.ToString());
|
var response = await _httpClient.SendAsync(
|
||||||
|
CreateHttpRequest($"api/v1/server/lightning/{cryptoCode}/balance",
|
||||||
|
method: HttpMethod.Get), token);
|
||||||
|
return await HandleResponse<LightningNodeBalanceData>(response);
|
||||||
}
|
}
|
||||||
if (offsetIndex is > 0)
|
|
||||||
{
|
|
||||||
queryPayload.Add("offsetIndex", offsetIndex);
|
|
||||||
}
|
|
||||||
return await SendHttpRequest<LightningPaymentData[]>($"api/v1/server/lightning/{cryptoCode}/payments", queryPayload, HttpMethod.Get, token);
|
|
||||||
}
|
|
||||||
|
|
||||||
public virtual async Task<LightningInvoiceData> CreateLightningInvoice(string cryptoCode, CreateLightningInvoiceRequest request,
|
public virtual async Task ConnectToLightningNode(string cryptoCode, ConnectToNodeRequest request,
|
||||||
CancellationToken token = default)
|
CancellationToken token = default)
|
||||||
{
|
{
|
||||||
if (request == null) throw new ArgumentNullException(nameof(request));
|
if (request == null)
|
||||||
return await SendHttpRequest<LightningInvoiceData>($"api/v1/server/lightning/{cryptoCode}/invoices", request, HttpMethod.Post, token);
|
throw new ArgumentNullException(nameof(request));
|
||||||
|
var response = await _httpClient.SendAsync(
|
||||||
|
CreateHttpRequest($"api/v1/server/lightning/{cryptoCode}/connect", bodyPayload: request,
|
||||||
|
method: HttpMethod.Post), token);
|
||||||
|
await HandleResponse(response);
|
||||||
|
}
|
||||||
|
|
||||||
|
public virtual async Task<IEnumerable<LightningChannelData>> GetLightningNodeChannels(string cryptoCode,
|
||||||
|
CancellationToken token = default)
|
||||||
|
{
|
||||||
|
var response = await _httpClient.SendAsync(
|
||||||
|
CreateHttpRequest($"api/v1/server/lightning/{cryptoCode}/channels",
|
||||||
|
method: HttpMethod.Get), token);
|
||||||
|
return await HandleResponse<IEnumerable<LightningChannelData>>(response);
|
||||||
|
}
|
||||||
|
|
||||||
|
public virtual async Task OpenLightningChannel(string cryptoCode, OpenLightningChannelRequest request,
|
||||||
|
CancellationToken token = default)
|
||||||
|
{
|
||||||
|
var response = await _httpClient.SendAsync(
|
||||||
|
CreateHttpRequest($"api/v1/server/lightning/{cryptoCode}/channels", bodyPayload: request,
|
||||||
|
method: HttpMethod.Post), token);
|
||||||
|
await HandleResponse(response);
|
||||||
|
}
|
||||||
|
|
||||||
|
public virtual async Task<string> GetLightningDepositAddress(string cryptoCode, CancellationToken token = default)
|
||||||
|
{
|
||||||
|
var response = await _httpClient.SendAsync(
|
||||||
|
CreateHttpRequest($"api/v1/server/lightning/{cryptoCode}/address", method: HttpMethod.Post), token);
|
||||||
|
return await HandleResponse<string>(response);
|
||||||
|
}
|
||||||
|
|
||||||
|
public virtual async Task<LightningPaymentData> PayLightningInvoice(string cryptoCode, PayLightningInvoiceRequest request,
|
||||||
|
CancellationToken token = default)
|
||||||
|
{
|
||||||
|
if (request == null)
|
||||||
|
throw new ArgumentNullException(nameof(request));
|
||||||
|
var response = await _httpClient.SendAsync(
|
||||||
|
CreateHttpRequest($"api/v1/server/lightning/{cryptoCode}/invoices/pay", bodyPayload: request,
|
||||||
|
method: HttpMethod.Post), token);
|
||||||
|
return await HandleResponse<LightningPaymentData>(response);
|
||||||
|
}
|
||||||
|
|
||||||
|
public virtual async Task<LightningPaymentData> GetLightningPayment(string cryptoCode,
|
||||||
|
string paymentHash, CancellationToken token = default)
|
||||||
|
{
|
||||||
|
if (paymentHash == null)
|
||||||
|
throw new ArgumentNullException(nameof(paymentHash));
|
||||||
|
var response = await _httpClient.SendAsync(
|
||||||
|
CreateHttpRequest($"api/v1/server/lightning/{cryptoCode}/payments/{paymentHash}",
|
||||||
|
method: HttpMethod.Get), token);
|
||||||
|
return await HandleResponse<LightningPaymentData>(response);
|
||||||
|
}
|
||||||
|
|
||||||
|
public virtual async Task<LightningInvoiceData> GetLightningInvoice(string cryptoCode,
|
||||||
|
string invoiceId, CancellationToken token = default)
|
||||||
|
{
|
||||||
|
if (invoiceId == null)
|
||||||
|
throw new ArgumentNullException(nameof(invoiceId));
|
||||||
|
var response = await _httpClient.SendAsync(
|
||||||
|
CreateHttpRequest($"api/v1/server/lightning/{cryptoCode}/invoices/{invoiceId}",
|
||||||
|
method: HttpMethod.Get), token);
|
||||||
|
return await HandleResponse<LightningInvoiceData>(response);
|
||||||
|
}
|
||||||
|
|
||||||
|
public 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<LightningPaymentData[]> GetLightningPayments(string cryptoCode,
|
||||||
|
bool? includePending = null, long? offsetIndex = null, CancellationToken token = default)
|
||||||
|
{
|
||||||
|
var queryPayload = new Dictionary<string, object>();
|
||||||
|
if (includePending is bool v)
|
||||||
|
{
|
||||||
|
queryPayload.Add("includePending", v.ToString());
|
||||||
|
}
|
||||||
|
if (offsetIndex is > 0)
|
||||||
|
{
|
||||||
|
queryPayload.Add("offsetIndex", offsetIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
var response = await _httpClient.SendAsync(
|
||||||
|
CreateHttpRequest($"api/v1/server/lightning/{cryptoCode}/payments", queryPayload), token);
|
||||||
|
return await HandleResponse<LightningPaymentData[]>(response);
|
||||||
|
}
|
||||||
|
|
||||||
|
public virtual async Task<LightningInvoiceData> CreateLightningInvoice(string cryptoCode, CreateLightningInvoiceRequest request,
|
||||||
|
CancellationToken token = default)
|
||||||
|
{
|
||||||
|
if (request == null)
|
||||||
|
throw new ArgumentNullException(nameof(request));
|
||||||
|
var response = await _httpClient.SendAsync(
|
||||||
|
CreateHttpRequest($"api/v1/server/lightning/{cryptoCode}/invoices", bodyPayload: request,
|
||||||
|
method: HttpMethod.Post), token);
|
||||||
|
return await HandleResponse<LightningInvoiceData>(response);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -5,109 +5,144 @@ using System.Threading;
|
|||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using BTCPayServer.Client.Models;
|
using BTCPayServer.Client.Models;
|
||||||
|
|
||||||
namespace BTCPayServer.Client;
|
namespace BTCPayServer.Client
|
||||||
|
|
||||||
public partial class BTCPayServerClient
|
|
||||||
{
|
{
|
||||||
public virtual async Task<LightningNodeInformationData> GetLightningNodeInfo(string storeId, string cryptoCode,
|
public partial class BTCPayServerClient
|
||||||
CancellationToken token = default)
|
|
||||||
{
|
{
|
||||||
return await SendHttpRequest<LightningNodeInformationData>($"api/v1/stores/{storeId}/lightning/{cryptoCode}/info", null, HttpMethod.Get, token);
|
public virtual async Task<LightningNodeInformationData> GetLightningNodeInfo(string storeId, string cryptoCode,
|
||||||
}
|
CancellationToken token = default)
|
||||||
|
|
||||||
public virtual async Task<LightningNodeBalanceData> GetLightningNodeBalance(string storeId, string cryptoCode,
|
|
||||||
CancellationToken token = default)
|
|
||||||
{
|
|
||||||
return await SendHttpRequest<LightningNodeBalanceData>($"api/v1/stores/{storeId}/lightning/{cryptoCode}/balance", null, HttpMethod.Get, token);
|
|
||||||
}
|
|
||||||
|
|
||||||
public virtual async Task<HistogramData> GetLightningNodeHistogram(string storeId, string cryptoCode, HistogramType? type = null,
|
|
||||||
CancellationToken token = default)
|
|
||||||
{
|
|
||||||
var queryPayload = type == null ? null : new Dictionary<string, object> { { "type", type.ToString() } };
|
|
||||||
return await SendHttpRequest<HistogramData>($"api/v1/stores/{storeId}/lightning/{cryptoCode}/histogram", queryPayload, HttpMethod.Get, token);
|
|
||||||
}
|
|
||||||
|
|
||||||
public virtual async Task ConnectToLightningNode(string storeId, string cryptoCode, ConnectToNodeRequest request,
|
|
||||||
CancellationToken token = default)
|
|
||||||
{
|
|
||||||
if (request == null) throw new ArgumentNullException(nameof(request));
|
|
||||||
await SendHttpRequest($"api/v1/stores/{storeId}/lightning/{cryptoCode}/connect", request, HttpMethod.Post, token);
|
|
||||||
}
|
|
||||||
|
|
||||||
public virtual async Task<IEnumerable<LightningChannelData>> GetLightningNodeChannels(string storeId, string cryptoCode,
|
|
||||||
CancellationToken token = default)
|
|
||||||
{
|
|
||||||
return await SendHttpRequest<IEnumerable<LightningChannelData>>($"api/v1/stores/{storeId}/lightning/{cryptoCode}/channels", null, HttpMethod.Get, token);
|
|
||||||
}
|
|
||||||
|
|
||||||
public virtual async Task OpenLightningChannel(string storeId, string cryptoCode, OpenLightningChannelRequest request,
|
|
||||||
CancellationToken token = default)
|
|
||||||
{
|
|
||||||
await SendHttpRequest($"api/v1/stores/{storeId}/lightning/{cryptoCode}/channels", request, HttpMethod.Post, token);
|
|
||||||
}
|
|
||||||
|
|
||||||
public virtual async Task<string> GetLightningDepositAddress(string storeId, string cryptoCode,
|
|
||||||
CancellationToken token = default)
|
|
||||||
{
|
|
||||||
return await SendHttpRequest<string>($"api/v1/stores/{storeId}/lightning/{cryptoCode}/address", null, HttpMethod.Post, token);
|
|
||||||
}
|
|
||||||
|
|
||||||
public virtual async Task<LightningPaymentData> PayLightningInvoice(string storeId, string cryptoCode, PayLightningInvoiceRequest request,
|
|
||||||
CancellationToken token = default)
|
|
||||||
{
|
|
||||||
if (request == null) throw new ArgumentNullException(nameof(request));
|
|
||||||
return await SendHttpRequest<LightningPaymentData>($"api/v1/stores/{storeId}/lightning/{cryptoCode}/invoices/pay", request, HttpMethod.Post, token);
|
|
||||||
}
|
|
||||||
|
|
||||||
public virtual async Task<LightningPaymentData> GetLightningPayment(string storeId, string cryptoCode,
|
|
||||||
string paymentHash, CancellationToken token = default)
|
|
||||||
{
|
|
||||||
if (paymentHash == null) throw new ArgumentNullException(nameof(paymentHash));
|
|
||||||
return await SendHttpRequest<LightningPaymentData>($"api/v1/stores/{storeId}/lightning/{cryptoCode}/payments/{paymentHash}", null, HttpMethod.Get, token);
|
|
||||||
}
|
|
||||||
|
|
||||||
public virtual async Task<LightningInvoiceData> GetLightningInvoice(string storeId, string cryptoCode,
|
|
||||||
string invoiceId, CancellationToken token = default)
|
|
||||||
{
|
|
||||||
if (invoiceId == null) throw new ArgumentNullException(nameof(invoiceId));
|
|
||||||
return await SendHttpRequest<LightningInvoiceData>($"api/v1/stores/{storeId}/lightning/{cryptoCode}/invoices/{invoiceId}", null, HttpMethod.Get, token);
|
|
||||||
}
|
|
||||||
|
|
||||||
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());
|
var response = await _httpClient.SendAsync(
|
||||||
|
CreateHttpRequest($"api/v1/stores/{storeId}/lightning/{cryptoCode}/info",
|
||||||
|
method: HttpMethod.Get), token);
|
||||||
|
return await HandleResponse<LightningNodeInformationData>(response);
|
||||||
}
|
}
|
||||||
if (offsetIndex is > 0)
|
|
||||||
{
|
|
||||||
queryPayload.Add("offsetIndex", offsetIndex);
|
|
||||||
}
|
|
||||||
return await SendHttpRequest<LightningInvoiceData[]>($"api/v1/stores/{storeId}/lightning/{cryptoCode}/invoices", queryPayload, HttpMethod.Get, token);
|
|
||||||
}
|
|
||||||
|
|
||||||
public virtual async Task<LightningPaymentData[]> GetLightningPayments(string storeId, string cryptoCode,
|
public virtual async Task<LightningNodeBalanceData> GetLightningNodeBalance(string storeId, string cryptoCode,
|
||||||
bool? includePending = null, long? offsetIndex = null, CancellationToken token = default)
|
CancellationToken token = default)
|
||||||
{
|
|
||||||
var queryPayload = new Dictionary<string, object>();
|
|
||||||
if (includePending is bool v)
|
|
||||||
{
|
{
|
||||||
queryPayload.Add("includePending", v.ToString());
|
var response = await _httpClient.SendAsync(
|
||||||
|
CreateHttpRequest($"api/v1/stores/{storeId}/lightning/{cryptoCode}/balance",
|
||||||
|
method: HttpMethod.Get), token);
|
||||||
|
return await HandleResponse<LightningNodeBalanceData>(response);
|
||||||
}
|
}
|
||||||
if (offsetIndex is > 0)
|
|
||||||
{
|
|
||||||
queryPayload.Add("offsetIndex", offsetIndex);
|
|
||||||
}
|
|
||||||
return await SendHttpRequest<LightningPaymentData[]>($"api/v1/stores/{storeId}/lightning/{cryptoCode}/payments", queryPayload, HttpMethod.Get, token);
|
|
||||||
}
|
|
||||||
|
|
||||||
public virtual async Task<LightningInvoiceData> CreateLightningInvoice(string storeId, string cryptoCode,
|
public virtual async Task ConnectToLightningNode(string storeId, string cryptoCode, ConnectToNodeRequest request,
|
||||||
CreateLightningInvoiceRequest request, CancellationToken token = default)
|
CancellationToken token = default)
|
||||||
{
|
{
|
||||||
if (request == null) throw new ArgumentNullException(nameof(request));
|
if (request == null)
|
||||||
return await SendHttpRequest<LightningInvoiceData>($"api/v1/stores/{storeId}/lightning/{cryptoCode}/invoices", request, HttpMethod.Post, token);
|
throw new ArgumentNullException(nameof(request));
|
||||||
|
var response = await _httpClient.SendAsync(
|
||||||
|
CreateHttpRequest($"api/v1/stores/{storeId}/lightning/{cryptoCode}/connect", bodyPayload: request,
|
||||||
|
method: HttpMethod.Post), token);
|
||||||
|
await HandleResponse(response);
|
||||||
|
}
|
||||||
|
|
||||||
|
public virtual async Task<IEnumerable<LightningChannelData>> GetLightningNodeChannels(string storeId, string cryptoCode,
|
||||||
|
CancellationToken token = default)
|
||||||
|
{
|
||||||
|
var response = await _httpClient.SendAsync(
|
||||||
|
CreateHttpRequest($"api/v1/stores/{storeId}/lightning/{cryptoCode}/channels",
|
||||||
|
method: HttpMethod.Get), token);
|
||||||
|
return await HandleResponse<IEnumerable<LightningChannelData>>(response);
|
||||||
|
}
|
||||||
|
|
||||||
|
public virtual async Task OpenLightningChannel(string storeId, string cryptoCode, OpenLightningChannelRequest request,
|
||||||
|
CancellationToken token = default)
|
||||||
|
{
|
||||||
|
var response = await _httpClient.SendAsync(
|
||||||
|
CreateHttpRequest($"api/v1/stores/{storeId}/lightning/{cryptoCode}/channels", bodyPayload: request,
|
||||||
|
method: HttpMethod.Post), token);
|
||||||
|
await HandleResponse(response);
|
||||||
|
}
|
||||||
|
|
||||||
|
public virtual async Task<string> GetLightningDepositAddress(string storeId, string cryptoCode,
|
||||||
|
CancellationToken token = default)
|
||||||
|
{
|
||||||
|
var response = await _httpClient.SendAsync(
|
||||||
|
CreateHttpRequest($"api/v1/stores/{storeId}/lightning/{cryptoCode}/address", method: HttpMethod.Post),
|
||||||
|
token);
|
||||||
|
return await HandleResponse<string>(response);
|
||||||
|
}
|
||||||
|
|
||||||
|
public virtual async Task<LightningPaymentData> PayLightningInvoice(string storeId, string cryptoCode, PayLightningInvoiceRequest request,
|
||||||
|
CancellationToken token = default)
|
||||||
|
{
|
||||||
|
if (request == null)
|
||||||
|
throw new ArgumentNullException(nameof(request));
|
||||||
|
var response = await _httpClient.SendAsync(
|
||||||
|
CreateHttpRequest($"api/v1/stores/{storeId}/lightning/{cryptoCode}/invoices/pay", bodyPayload: request,
|
||||||
|
method: HttpMethod.Post), token);
|
||||||
|
return await HandleResponse<LightningPaymentData>(response);
|
||||||
|
}
|
||||||
|
|
||||||
|
public virtual async Task<LightningPaymentData> GetLightningPayment(string storeId, string cryptoCode,
|
||||||
|
string paymentHash, CancellationToken token = default)
|
||||||
|
{
|
||||||
|
if (paymentHash == null)
|
||||||
|
throw new ArgumentNullException(nameof(paymentHash));
|
||||||
|
var response = await _httpClient.SendAsync(
|
||||||
|
CreateHttpRequest($"api/v1/stores/{storeId}/lightning/{cryptoCode}/payments/{paymentHash}",
|
||||||
|
method: HttpMethod.Get), token);
|
||||||
|
return await HandleResponse<LightningPaymentData>(response);
|
||||||
|
}
|
||||||
|
|
||||||
|
public virtual async Task<LightningInvoiceData> GetLightningInvoice(string storeId, string cryptoCode,
|
||||||
|
string invoiceId, CancellationToken token = default)
|
||||||
|
{
|
||||||
|
if (invoiceId == null)
|
||||||
|
throw new ArgumentNullException(nameof(invoiceId));
|
||||||
|
var response = await _httpClient.SendAsync(
|
||||||
|
CreateHttpRequest($"api/v1/stores/{storeId}/lightning/{cryptoCode}/invoices/{invoiceId}",
|
||||||
|
method: HttpMethod.Get), token);
|
||||||
|
return await HandleResponse<LightningInvoiceData>(response);
|
||||||
|
}
|
||||||
|
|
||||||
|
public 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<LightningPaymentData[]> GetLightningPayments(string storeId, string cryptoCode,
|
||||||
|
bool? includePending = null, long? offsetIndex = null, CancellationToken token = default)
|
||||||
|
{
|
||||||
|
var queryPayload = new Dictionary<string, object>();
|
||||||
|
if (includePending is bool v)
|
||||||
|
{
|
||||||
|
queryPayload.Add("includePending", v.ToString());
|
||||||
|
}
|
||||||
|
if (offsetIndex is > 0)
|
||||||
|
{
|
||||||
|
queryPayload.Add("offsetIndex", offsetIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
var response = await _httpClient.SendAsync(
|
||||||
|
CreateHttpRequest($"api/v1/stores/{storeId}/lightning/{cryptoCode}/payments", queryPayload), token);
|
||||||
|
return await HandleResponse<LightningPaymentData[]>(response);
|
||||||
|
}
|
||||||
|
|
||||||
|
public virtual async Task<LightningInvoiceData> CreateLightningInvoice(string storeId, string cryptoCode,
|
||||||
|
CreateLightningInvoiceRequest request, CancellationToken token = default)
|
||||||
|
{
|
||||||
|
if (request == null)
|
||||||
|
throw new ArgumentNullException(nameof(request));
|
||||||
|
var response = await _httpClient.SendAsync(
|
||||||
|
CreateHttpRequest($"api/v1/stores/{storeId}/lightning/{cryptoCode}/invoices", bodyPayload: request,
|
||||||
|
method: HttpMethod.Post), token);
|
||||||
|
return await HandleResponse<LightningInvoiceData>(response);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -3,32 +3,46 @@ using System.Threading;
|
|||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using BTCPayServer.Client.Models;
|
using BTCPayServer.Client.Models;
|
||||||
|
|
||||||
namespace BTCPayServer.Client;
|
namespace BTCPayServer.Client
|
||||||
|
|
||||||
public partial class BTCPayServerClient
|
|
||||||
{
|
{
|
||||||
public virtual async Task<LightningAddressData[]> GetStoreLightningAddresses(string storeId,
|
public partial class BTCPayServerClient
|
||||||
CancellationToken token = default)
|
|
||||||
{
|
{
|
||||||
return await SendHttpRequest<LightningAddressData[]>($"api/v1/stores/{storeId}/lightning-addresses", null, HttpMethod.Get, token);
|
public virtual async Task<LightningAddressData[]> GetStoreLightningAddresses(string storeId,
|
||||||
}
|
CancellationToken token = default)
|
||||||
|
{
|
||||||
|
var response = await _httpClient.SendAsync(
|
||||||
|
CreateHttpRequest($"api/v1/stores/{storeId}/lightning-addresses",
|
||||||
|
method: HttpMethod.Get), token);
|
||||||
|
return await HandleResponse<LightningAddressData[]>(response);
|
||||||
|
}
|
||||||
|
|
||||||
public virtual async Task<LightningAddressData> GetStoreLightningAddress(string storeId, string username,
|
public virtual async Task<LightningAddressData> GetStoreLightningAddress(string storeId, string username,
|
||||||
CancellationToken token = default)
|
CancellationToken token = default)
|
||||||
{
|
{
|
||||||
return await SendHttpRequest<LightningAddressData>($"api/v1/stores/{storeId}/lightning-addresses/{username}", null, HttpMethod.Get, token);
|
var response = await _httpClient.SendAsync(
|
||||||
}
|
CreateHttpRequest($"api/v1/stores/{storeId}/lightning-addresses/{username}",
|
||||||
|
method: HttpMethod.Get), token);
|
||||||
|
return await HandleResponse<LightningAddressData>(response);
|
||||||
|
}
|
||||||
|
|
||||||
public virtual async Task RemoveStoreLightningAddress(string storeId, string username,
|
public virtual async Task RemoveStoreLightningAddress(string storeId, string username,
|
||||||
CancellationToken token = default)
|
CancellationToken token = default)
|
||||||
{
|
{
|
||||||
await SendHttpRequest($"api/v1/stores/{storeId}/lightning-addresses/{username}", null, HttpMethod.Delete, token);
|
var response = await _httpClient.SendAsync(
|
||||||
}
|
CreateHttpRequest($"api/v1/stores/{storeId}/lightning-addresses/{username}",
|
||||||
|
method: HttpMethod.Delete), token);
|
||||||
|
await HandleResponse(response);
|
||||||
|
}
|
||||||
|
|
||||||
public virtual async Task<LightningAddressData> AddOrUpdateStoreLightningAddress(string storeId,
|
public virtual async Task<LightningAddressData> AddOrUpdateStoreLightningAddress(string storeId,
|
||||||
string username, LightningAddressData data,
|
string username, LightningAddressData data,
|
||||||
CancellationToken token = default)
|
CancellationToken token = default)
|
||||||
{
|
{
|
||||||
return await SendHttpRequest<LightningAddressData>($"api/v1/stores/{storeId}/lightning-addresses/{username}", data, HttpMethod.Post, token);
|
var response = await _httpClient.SendAsync(
|
||||||
|
CreateHttpRequest($"api/v1/stores/{storeId}/lightning-addresses/{username}",
|
||||||
|
method: HttpMethod.Post, bodyPayload: data), token);
|
||||||
|
|
||||||
|
return await HandleResponse<LightningAddressData>(response);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -0,0 +1,59 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Net.Http;
|
||||||
|
using System.Threading;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using BTCPayServer.Client.Models;
|
||||||
|
|
||||||
|
namespace BTCPayServer.Client
|
||||||
|
{
|
||||||
|
public partial class BTCPayServerClient
|
||||||
|
{
|
||||||
|
public virtual async Task<IEnumerable<LightningNetworkPaymentMethodData>>
|
||||||
|
GetStoreLightningNetworkPaymentMethods(string storeId, bool? enabled = null,
|
||||||
|
CancellationToken token = default)
|
||||||
|
{
|
||||||
|
var query = new Dictionary<string, object>();
|
||||||
|
if (enabled != null)
|
||||||
|
{
|
||||||
|
query.Add(nameof(enabled), enabled);
|
||||||
|
}
|
||||||
|
|
||||||
|
var response =
|
||||||
|
await _httpClient.SendAsync(
|
||||||
|
CreateHttpRequest($"api/v1/stores/{storeId}/payment-methods/LightningNetwork",
|
||||||
|
query), token);
|
||||||
|
return await HandleResponse<IEnumerable<LightningNetworkPaymentMethodData>>(response);
|
||||||
|
}
|
||||||
|
|
||||||
|
public virtual async Task<LightningNetworkPaymentMethodData> GetStoreLightningNetworkPaymentMethod(
|
||||||
|
string storeId,
|
||||||
|
string cryptoCode, CancellationToken token = default)
|
||||||
|
{
|
||||||
|
var response =
|
||||||
|
await _httpClient.SendAsync(
|
||||||
|
CreateHttpRequest($"api/v1/stores/{storeId}/payment-methods/LightningNetwork/{cryptoCode}"), token);
|
||||||
|
return await HandleResponse<LightningNetworkPaymentMethodData>(response);
|
||||||
|
}
|
||||||
|
|
||||||
|
public virtual async Task RemoveStoreLightningNetworkPaymentMethod(string storeId,
|
||||||
|
string cryptoCode, CancellationToken token = default)
|
||||||
|
{
|
||||||
|
var response =
|
||||||
|
await _httpClient.SendAsync(
|
||||||
|
CreateHttpRequest($"api/v1/stores/{storeId}/payment-methods/LightningNetwork/{cryptoCode}",
|
||||||
|
method: HttpMethod.Delete), token);
|
||||||
|
await HandleResponse(response);
|
||||||
|
}
|
||||||
|
|
||||||
|
public virtual async Task<LightningNetworkPaymentMethodData> UpdateStoreLightningNetworkPaymentMethod(
|
||||||
|
string storeId,
|
||||||
|
string cryptoCode, UpdateLightningNetworkPaymentMethodRequest paymentMethod,
|
||||||
|
CancellationToken token = default)
|
||||||
|
{
|
||||||
|
var response = await _httpClient.SendAsync(
|
||||||
|
CreateHttpRequest($"api/v1/stores/{storeId}/payment-methods/LightningNetwork/{cryptoCode}",
|
||||||
|
bodyPayload: paymentMethod, method: HttpMethod.Put), token);
|
||||||
|
return await HandleResponse<LightningNetworkPaymentMethodData>(response);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -1,19 +1,23 @@
|
|||||||
using System.Net.Http;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Text;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using BTCPayServer.Client.Models;
|
using BTCPayServer.Client.Models;
|
||||||
|
|
||||||
namespace BTCPayServer.Client;
|
namespace BTCPayServer.Client
|
||||||
|
|
||||||
public partial class BTCPayServerClient
|
|
||||||
{
|
{
|
||||||
public virtual async Task<PermissionMetadata[]> GetPermissionMetadata(CancellationToken token = default)
|
public partial class BTCPayServerClient
|
||||||
{
|
{
|
||||||
return await SendHttpRequest<PermissionMetadata[]>("misc/permissions", null, HttpMethod.Get, token);
|
public virtual async Task<PermissionMetadata[]> GetPermissionMetadata(CancellationToken token = default)
|
||||||
}
|
{
|
||||||
|
var response = await _httpClient.SendAsync(CreateHttpRequest("misc/permissions"), token);
|
||||||
public virtual async Task<Language[]> GetAvailableLanguages(CancellationToken token = default)
|
return await HandleResponse<PermissionMetadata[]>(response);
|
||||||
{
|
}
|
||||||
return await SendHttpRequest<Language[]>("misc/lang", null, HttpMethod.Get, token);
|
public virtual async Task<Language[]> GetAvailableLanguages(CancellationToken token = default)
|
||||||
|
{
|
||||||
|
var response = await _httpClient.SendAsync(CreateHttpRequest("misc/lang"), token);
|
||||||
|
return await HandleResponse<Language[]>(response);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1,52 +1,56 @@
|
|||||||
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Net.Http;
|
using System.Net.Http;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using BTCPayServer.Client.Models;
|
using BTCPayServer.Client.Models;
|
||||||
|
|
||||||
namespace BTCPayServer.Client;
|
namespace BTCPayServer.Client
|
||||||
|
|
||||||
public partial class BTCPayServerClient
|
|
||||||
{
|
{
|
||||||
public virtual async Task<IEnumerable<NotificationData>> GetNotifications(bool? seen = null, int? skip = null,
|
public partial class BTCPayServerClient
|
||||||
int? take = null, string[] storeId = null, CancellationToken token = default)
|
|
||||||
{
|
{
|
||||||
var queryPayload = new Dictionary<string, object>();
|
public virtual async Task<IEnumerable<NotificationData>> GetNotifications(bool? seen = null, int? skip = null,
|
||||||
if (seen != null)
|
int? take = null, CancellationToken token = default)
|
||||||
queryPayload.Add(nameof(seen), seen);
|
{
|
||||||
if (skip != null)
|
Dictionary<string, object> queryPayload = new Dictionary<string, object>();
|
||||||
queryPayload.Add(nameof(skip), skip);
|
|
||||||
if (take != null)
|
|
||||||
queryPayload.Add(nameof(take), take);
|
|
||||||
if (storeId != null)
|
|
||||||
queryPayload.Add(nameof(storeId), storeId);
|
|
||||||
return await SendHttpRequest<IEnumerable<NotificationData>>("api/v1/users/me/notifications", queryPayload, HttpMethod.Get, token);
|
|
||||||
}
|
|
||||||
|
|
||||||
public virtual async Task<NotificationData> GetNotification(string notificationId,
|
if (seen != null)
|
||||||
CancellationToken token = default)
|
queryPayload.Add(nameof(seen), seen);
|
||||||
{
|
if (skip != null)
|
||||||
return await SendHttpRequest<NotificationData>($"api/v1/users/me/notifications/{notificationId}", null, HttpMethod.Get, token);
|
queryPayload.Add(nameof(skip), skip);
|
||||||
}
|
if (take != null)
|
||||||
|
queryPayload.Add(nameof(take), take);
|
||||||
|
|
||||||
public virtual async Task<NotificationData> UpdateNotification(string notificationId, bool? seen,
|
var response = await _httpClient.SendAsync(
|
||||||
CancellationToken token = default)
|
CreateHttpRequest($"api/v1/users/me/notifications",
|
||||||
{
|
queryPayload), token);
|
||||||
return await SendHttpRequest<NotificationData>($"api/v1/users/me/notifications/{notificationId}", new UpdateNotification { Seen = seen }, HttpMethod.Put, token);
|
|
||||||
}
|
|
||||||
|
|
||||||
public virtual async Task<NotificationSettingsData> GetNotificationSettings(CancellationToken token = default)
|
return await HandleResponse<IEnumerable<NotificationData>>(response);
|
||||||
{
|
}
|
||||||
return await SendHttpRequest<NotificationSettingsData>("api/v1/users/me/notification-settings", null, HttpMethod.Get, token);
|
|
||||||
}
|
|
||||||
|
|
||||||
public virtual async Task<NotificationSettingsData> UpdateNotificationSettings(UpdateNotificationSettingsRequest request, CancellationToken token = default)
|
public virtual async Task<NotificationData> GetNotification(string notificationId,
|
||||||
{
|
CancellationToken token = default)
|
||||||
return await SendHttpRequest<NotificationSettingsData>("api/v1/users/me/notification-settings", request, HttpMethod.Put, token);
|
{
|
||||||
}
|
var response = await _httpClient.SendAsync(
|
||||||
|
CreateHttpRequest($"api/v1/users/me/notifications/{notificationId}"), token);
|
||||||
|
return await HandleResponse<NotificationData>(response);
|
||||||
|
}
|
||||||
|
|
||||||
public virtual async Task RemoveNotification(string notificationId, CancellationToken token = default)
|
public virtual async Task<NotificationData> UpdateNotification(string notificationId, bool? seen,
|
||||||
{
|
CancellationToken token = default)
|
||||||
await SendHttpRequest($"api/v1/users/me/notifications/{notificationId}", null, HttpMethod.Delete, token);
|
{
|
||||||
|
var response = await _httpClient.SendAsync(
|
||||||
|
CreateHttpRequest($"api/v1/users/me/notifications/{notificationId}",
|
||||||
|
method: HttpMethod.Put, bodyPayload: new UpdateNotification() { Seen = seen }), token);
|
||||||
|
return await HandleResponse<NotificationData>(response);
|
||||||
|
}
|
||||||
|
|
||||||
|
public virtual async Task RemoveNotification(string notificationId, CancellationToken token = default)
|
||||||
|
{
|
||||||
|
var response = await _httpClient.SendAsync(
|
||||||
|
CreateHttpRequest($"api/v1/users/me/notifications/{notificationId}",
|
||||||
|
method: HttpMethod.Delete), token);
|
||||||
|
await HandleResponse(response);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -3,37 +3,92 @@ using System.Net.Http;
|
|||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using BTCPayServer.Client.Models;
|
using BTCPayServer.Client.Models;
|
||||||
using Newtonsoft.Json.Linq;
|
|
||||||
|
|
||||||
namespace BTCPayServer.Client;
|
namespace BTCPayServer.Client
|
||||||
|
|
||||||
public partial class BTCPayServerClient
|
|
||||||
{
|
{
|
||||||
public virtual async Task<OnChainPaymentMethodPreviewResultData>
|
public partial class BTCPayServerClient
|
||||||
PreviewProposedStoreOnChainPaymentMethodAddresses(
|
{
|
||||||
string storeId, string paymentMethodId, string derivationScheme, int offset = 0,
|
public virtual async Task<IEnumerable<OnChainPaymentMethodData>> GetStoreOnChainPaymentMethods(string storeId,
|
||||||
int amount = 10,
|
bool? enabled = null,
|
||||||
CancellationToken token = default)
|
CancellationToken token = default)
|
||||||
{
|
{
|
||||||
return await SendHttpRequest<UpdatePaymentMethodRequest, OnChainPaymentMethodPreviewResultData>($"api/v1/stores/{storeId}/payment-methods/{paymentMethodId}/wallet/preview",
|
var query = new Dictionary<string, object>();
|
||||||
new Dictionary<string, object> { { "offset", offset }, { "amount", amount } },
|
if (enabled != null)
|
||||||
new UpdatePaymentMethodRequest { Config = JValue.CreateString(derivationScheme) },
|
{
|
||||||
HttpMethod.Post, token);
|
query.Add(nameof(enabled), enabled);
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual async Task<OnChainPaymentMethodPreviewResultData> PreviewStoreOnChainPaymentMethodAddresses(
|
var response =
|
||||||
string storeId, string paymentMethodId, int offset = 0, int amount = 10,
|
await _httpClient.SendAsync(
|
||||||
CancellationToken token = default)
|
CreateHttpRequest($"api/v1/stores/{storeId}/payment-methods/onchain",
|
||||||
{
|
query), token);
|
||||||
return await SendHttpRequest<OnChainPaymentMethodPreviewResultData>($"api/v1/stores/{storeId}/payment-methods/{paymentMethodId}/wallet/preview",
|
return await HandleResponse<IEnumerable<OnChainPaymentMethodData>>(response);
|
||||||
new Dictionary<string, object> { { "offset", offset }, { "amount", amount } }, HttpMethod.Get, token);
|
}
|
||||||
}
|
|
||||||
|
|
||||||
public virtual async Task<GenerateOnChainWalletResponse> GenerateOnChainWallet(string storeId,
|
public virtual async Task<OnChainPaymentMethodData> GetStoreOnChainPaymentMethod(string storeId,
|
||||||
string paymentMethodId, GenerateOnChainWalletRequest request,
|
string cryptoCode, CancellationToken token = default)
|
||||||
CancellationToken token = default)
|
{
|
||||||
{
|
var response =
|
||||||
return await SendHttpRequest<GenerateOnChainWalletResponse>($"api/v1/stores/{storeId}/payment-methods/{paymentMethodId}/wallet/generate", request, HttpMethod.Post, token);
|
await _httpClient.SendAsync(
|
||||||
}
|
CreateHttpRequest($"api/v1/stores/{storeId}/payment-methods/onchain/{cryptoCode}"), token);
|
||||||
|
return await HandleResponse<OnChainPaymentMethodData>(response);
|
||||||
|
}
|
||||||
|
|
||||||
|
public virtual async Task RemoveStoreOnChainPaymentMethod(string storeId,
|
||||||
|
string cryptoCode, CancellationToken token = default)
|
||||||
|
{
|
||||||
|
var response =
|
||||||
|
await _httpClient.SendAsync(
|
||||||
|
CreateHttpRequest($"api/v1/stores/{storeId}/payment-methods/onchain/{cryptoCode}",
|
||||||
|
method: HttpMethod.Delete), token);
|
||||||
|
await HandleResponse(response);
|
||||||
|
}
|
||||||
|
|
||||||
|
public virtual async Task<OnChainPaymentMethodData> UpdateStoreOnChainPaymentMethod(string storeId,
|
||||||
|
string cryptoCode, UpdateOnChainPaymentMethodRequest paymentMethod,
|
||||||
|
CancellationToken token = default)
|
||||||
|
{
|
||||||
|
var response = await _httpClient.SendAsync(
|
||||||
|
CreateHttpRequest($"api/v1/stores/{storeId}/payment-methods/onchain/{cryptoCode}",
|
||||||
|
bodyPayload: paymentMethod, method: HttpMethod.Put), token);
|
||||||
|
return await HandleResponse<OnChainPaymentMethodData>(response);
|
||||||
|
}
|
||||||
|
|
||||||
|
public virtual async Task<OnChainPaymentMethodPreviewResultData>
|
||||||
|
PreviewProposedStoreOnChainPaymentMethodAddresses(
|
||||||
|
string storeId, string cryptoCode, UpdateOnChainPaymentMethodRequest paymentMethod, int offset = 0,
|
||||||
|
int amount = 10,
|
||||||
|
CancellationToken token = default)
|
||||||
|
{
|
||||||
|
var response = await _httpClient.SendAsync(
|
||||||
|
CreateHttpRequest($"api/v1/stores/{storeId}/payment-methods/onchain/{cryptoCode}/preview",
|
||||||
|
bodyPayload: paymentMethod,
|
||||||
|
queryPayload: new Dictionary<string, object>() { { "offset", offset }, { "amount", amount } },
|
||||||
|
method: HttpMethod.Post), token);
|
||||||
|
return await HandleResponse<OnChainPaymentMethodPreviewResultData>(response);
|
||||||
|
}
|
||||||
|
|
||||||
|
public virtual async Task<OnChainPaymentMethodPreviewResultData> PreviewStoreOnChainPaymentMethodAddresses(
|
||||||
|
string storeId, string cryptoCode, int offset = 0, int amount = 10,
|
||||||
|
CancellationToken token = default)
|
||||||
|
{
|
||||||
|
var response = await _httpClient.SendAsync(
|
||||||
|
CreateHttpRequest($"api/v1/stores/{storeId}/payment-methods/onchain/{cryptoCode}/preview",
|
||||||
|
queryPayload: new Dictionary<string, object>() { { "offset", offset }, { "amount", amount } },
|
||||||
|
method: HttpMethod.Get), token);
|
||||||
|
return await HandleResponse<OnChainPaymentMethodPreviewResultData>(response);
|
||||||
|
}
|
||||||
|
|
||||||
|
public virtual async Task<OnChainPaymentMethodDataWithSensitiveData> GenerateOnChainWallet(string storeId,
|
||||||
|
string cryptoCode, GenerateOnChainWalletRequest request,
|
||||||
|
CancellationToken token = default)
|
||||||
|
{
|
||||||
|
var response = await _httpClient.SendAsync(
|
||||||
|
CreateHttpRequest($"api/v1/stores/{storeId}/payment-methods/onchain/{cryptoCode}/generate",
|
||||||
|
bodyPayload: request,
|
||||||
|
method: HttpMethod.Post), token);
|
||||||
|
return await HandleResponse<OnChainPaymentMethodDataWithSensitiveData>(response);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1,62 +1,82 @@
|
|||||||
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
using System.Net.Http;
|
using System.Net.Http;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using BTCPayServer.Client.Models;
|
using BTCPayServer.Client.Models;
|
||||||
|
using NBitcoin;
|
||||||
|
|
||||||
namespace BTCPayServer.Client;
|
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)
|
public partial class BTCPayServerClient
|
||||||
{
|
{
|
||||||
var parameters = new Dictionary<string, object>();
|
public virtual async Task<OnChainWalletObjectData> GetOnChainWalletObject(string storeId, string cryptoCode, OnChainWalletObjectId objectId, bool? includeNeighbourData = null, CancellationToken token = default)
|
||||||
if (includeNeighbourData is bool v)
|
|
||||||
parameters.Add("includeNeighbourData", v);
|
|
||||||
try
|
|
||||||
{
|
{
|
||||||
return await SendHttpRequest<OnChainWalletObjectData>($"api/v1/stores/{storeId}/payment-methods/{cryptoCode}-CHAIN/wallet/objects/{objectId.Type}/{objectId.Id}", parameters, HttpMethod.Get, token);
|
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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
catch (GreenfieldAPIException err) when (err.APIError.Code == "wallet-object-not-found")
|
public virtual async Task<OnChainWalletObjectData[]> GetOnChainWalletObjects(string storeId, string cryptoCode, GetWalletObjectsRequest query = null, CancellationToken token = default)
|
||||||
{
|
{
|
||||||
return null;
|
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);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
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);
|
|
||||||
return await SendHttpRequest<OnChainWalletObjectData[]>($"api/v1/stores/{storeId}/payment-methods/{cryptoCode}-CHAIN/wallet/objects", parameters, HttpMethod.Get, token);
|
|
||||||
}
|
|
||||||
public virtual async Task RemoveOnChainWalletObject(string storeId, string cryptoCode, OnChainWalletObjectId objectId,
|
|
||||||
CancellationToken token = default)
|
|
||||||
{
|
|
||||||
await SendHttpRequest($"api/v1/stores/{storeId}/payment-methods/{cryptoCode}-CHAIN/wallet/objects/{objectId.Type}/{objectId.Id}", null, HttpMethod.Delete, token);
|
|
||||||
}
|
|
||||||
public virtual async Task<OnChainWalletObjectData> AddOrUpdateOnChainWalletObject(string storeId, string cryptoCode, AddOnChainWalletObjectRequest request,
|
|
||||||
CancellationToken token = default)
|
|
||||||
{
|
|
||||||
return await SendHttpRequest<OnChainWalletObjectData>($"api/v1/stores/{storeId}/payment-methods/{cryptoCode}-CHAIN/wallet/objects", request, HttpMethod.Post, token);
|
|
||||||
}
|
|
||||||
|
|
||||||
public virtual async Task AddOrUpdateOnChainWalletLink(string storeId, string cryptoCode,
|
|
||||||
OnChainWalletObjectId objectId,
|
|
||||||
AddOnChainWalletObjectLinkRequest request = null,
|
|
||||||
CancellationToken token = default)
|
|
||||||
{
|
|
||||||
await SendHttpRequest($"api/v1/stores/{storeId}/payment-methods/{cryptoCode}-CHAIN/wallet/objects/{objectId.Type}/{objectId.Id}/links", request, HttpMethod.Post, token);
|
|
||||||
}
|
|
||||||
|
|
||||||
public virtual async Task RemoveOnChainWalletLinks(string storeId, string cryptoCode,
|
|
||||||
OnChainWalletObjectId objectId,
|
|
||||||
OnChainWalletObjectId link,
|
|
||||||
CancellationToken token = default)
|
|
||||||
{
|
|
||||||
await SendHttpRequest($"api/v1/stores/{storeId}/payment-methods/{cryptoCode}-CHAIN/wallet/objects/{objectId.Type}/{objectId.Id}/links/{link.Type}/{link.Id}", null, HttpMethod.Delete, token);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -7,113 +7,134 @@ using System.Threading.Tasks;
|
|||||||
using BTCPayServer.Client.Models;
|
using BTCPayServer.Client.Models;
|
||||||
using NBitcoin;
|
using NBitcoin;
|
||||||
|
|
||||||
namespace BTCPayServer.Client;
|
namespace BTCPayServer.Client
|
||||||
|
|
||||||
public partial class BTCPayServerClient
|
|
||||||
{
|
{
|
||||||
public virtual async Task<OnChainWalletOverviewData> ShowOnChainWalletOverview(string storeId, string cryptoCode,
|
public partial class BTCPayServerClient
|
||||||
CancellationToken token = default)
|
|
||||||
{
|
{
|
||||||
return await SendHttpRequest<OnChainWalletOverviewData>($"api/v1/stores/{storeId}/payment-methods/{cryptoCode}-CHAIN/wallet", null, HttpMethod.Get, token);
|
public virtual async Task<OnChainWalletOverviewData> ShowOnChainWalletOverview(string storeId, string cryptoCode,
|
||||||
}
|
CancellationToken token = default)
|
||||||
|
|
||||||
public virtual async Task<HistogramData> GetOnChainWalletHistogram(string storeId, string cryptoCode, HistogramType? type = null,
|
|
||||||
CancellationToken token = default)
|
|
||||||
{
|
|
||||||
var queryPayload = type == null ? null : new Dictionary<string, object> { { "type", type.ToString() } };
|
|
||||||
return await SendHttpRequest<HistogramData>($"api/v1/stores/{storeId}/payment-methods/{cryptoCode}-CHAIN/wallet/histogram", queryPayload, HttpMethod.Get, token);
|
|
||||||
}
|
|
||||||
|
|
||||||
public virtual async Task<OnChainWalletFeeRateData> GetOnChainFeeRate(string storeId, string cryptoCode, int? blockTarget = null,
|
|
||||||
CancellationToken token = default)
|
|
||||||
{
|
|
||||||
var queryParams = new Dictionary<string, object>();
|
|
||||||
if (blockTarget != null)
|
|
||||||
{
|
{
|
||||||
queryParams.Add("blockTarget", blockTarget);
|
var response =
|
||||||
|
await _httpClient.SendAsync(
|
||||||
|
CreateHttpRequest($"api/v1/stores/{storeId}/payment-methods/onchain/{cryptoCode}/wallet"), token);
|
||||||
|
return await HandleResponse<OnChainWalletOverviewData>(response);
|
||||||
}
|
}
|
||||||
return await SendHttpRequest<OnChainWalletFeeRateData>($"api/v1/stores/{storeId}/payment-methods/{cryptoCode}-CHAIN/wallet/feerate", queryParams, HttpMethod.Get, token);
|
public virtual async Task<OnChainWalletFeeRateData> GetOnChainFeeRate(string storeId, string cryptoCode, int? blockTarget = null,
|
||||||
}
|
CancellationToken token = default)
|
||||||
|
|
||||||
public virtual async Task<OnChainWalletAddressData> GetOnChainWalletReceiveAddress(string storeId, string cryptoCode, bool forceGenerate = false,
|
|
||||||
CancellationToken token = default)
|
|
||||||
{
|
|
||||||
return await SendHttpRequest<OnChainWalletAddressData>($"api/v1/stores/{storeId}/payment-methods/{cryptoCode}-CHAIN/wallet/address", new Dictionary<string, object>
|
|
||||||
{
|
{
|
||||||
{"forceGenerate", forceGenerate}
|
Dictionary<string, object> queryParams = new Dictionary<string, object>();
|
||||||
}, HttpMethod.Get, token);
|
if (blockTarget != null)
|
||||||
}
|
{
|
||||||
|
queryParams.Add("blockTarget", blockTarget);
|
||||||
public virtual async Task UnReserveOnChainWalletReceiveAddress(string storeId, string cryptoCode,
|
}
|
||||||
CancellationToken token = default)
|
var response =
|
||||||
{
|
await _httpClient.SendAsync(
|
||||||
await SendHttpRequest($"api/v1/stores/{storeId}/payment-methods/{cryptoCode}-CHAIN/wallet/address", null, HttpMethod.Delete, token);
|
CreateHttpRequest($"api/v1/stores/{storeId}/payment-methods/onchain/{cryptoCode}/wallet/feeRate", queryParams), token);
|
||||||
}
|
return await HandleResponse<OnChainWalletFeeRateData>(response);
|
||||||
|
|
||||||
public virtual async Task<IEnumerable<OnChainWalletTransactionData>> ShowOnChainWalletTransactions(
|
|
||||||
string storeId, string cryptoCode, TransactionStatus[] statusFilter = null, string labelFilter = null, int skip = 0,
|
|
||||||
CancellationToken token = default)
|
|
||||||
{
|
|
||||||
var query = new Dictionary<string, object>();
|
|
||||||
if (statusFilter?.Any() is true)
|
|
||||||
{
|
|
||||||
query.Add(nameof(statusFilter), statusFilter);
|
|
||||||
}
|
}
|
||||||
if (labelFilter != null)
|
|
||||||
|
public virtual async Task<OnChainWalletAddressData> GetOnChainWalletReceiveAddress(string storeId, string cryptoCode, bool forceGenerate = false,
|
||||||
|
CancellationToken token = default)
|
||||||
{
|
{
|
||||||
query.Add(nameof(labelFilter), labelFilter);
|
var response =
|
||||||
|
await _httpClient.SendAsync(
|
||||||
|
CreateHttpRequest($"api/v1/stores/{storeId}/payment-methods/onchain/{cryptoCode}/wallet/address", new Dictionary<string, object>()
|
||||||
|
{
|
||||||
|
{"forceGenerate", forceGenerate}
|
||||||
|
}), token);
|
||||||
|
return await HandleResponse<OnChainWalletAddressData>(response);
|
||||||
}
|
}
|
||||||
if (skip != 0)
|
|
||||||
|
public virtual async Task UnReserveOnChainWalletReceiveAddress(string storeId, string cryptoCode,
|
||||||
|
CancellationToken token = default)
|
||||||
{
|
{
|
||||||
query.Add(nameof(skip), skip);
|
var response =
|
||||||
|
await _httpClient.SendAsync(
|
||||||
|
CreateHttpRequest($"api/v1/stores/{storeId}/payment-methods/onchain/{cryptoCode}/wallet/address", method: HttpMethod.Delete), token);
|
||||||
|
await HandleResponse(response);
|
||||||
}
|
}
|
||||||
return await SendHttpRequest<IEnumerable<OnChainWalletTransactionData>>($"api/v1/stores/{storeId}/payment-methods/{cryptoCode}-CHAIN/wallet/transactions", query, HttpMethod.Get, token);
|
|
||||||
}
|
|
||||||
|
|
||||||
public virtual async Task<OnChainWalletTransactionData> GetOnChainWalletTransaction(
|
public virtual async Task<IEnumerable<OnChainWalletTransactionData>> ShowOnChainWalletTransactions(
|
||||||
string storeId, string cryptoCode, string transactionId,
|
string storeId, string cryptoCode, TransactionStatus[] statusFilter = null, string labelFilter = null,
|
||||||
CancellationToken token = default)
|
CancellationToken token = default)
|
||||||
{
|
|
||||||
return await SendHttpRequest<OnChainWalletTransactionData>($"api/v1/stores/{storeId}/payment-methods/{cryptoCode}-CHAIN/wallet/transactions/{transactionId}", null, HttpMethod.Get, token);
|
|
||||||
}
|
|
||||||
|
|
||||||
public virtual async Task<OnChainWalletTransactionData> PatchOnChainWalletTransaction(
|
|
||||||
string storeId, string cryptoCode, string transactionId,
|
|
||||||
PatchOnChainTransactionRequest request,
|
|
||||||
bool force = false, CancellationToken token = default)
|
|
||||||
{
|
|
||||||
return await SendHttpRequest<PatchOnChainTransactionRequest, OnChainWalletTransactionData>($"api/v1/stores/{storeId}/payment-methods/{cryptoCode}-CHAIN/wallet/transactions/{transactionId}",
|
|
||||||
new Dictionary<string, object> { {"force", force} }, request, HttpMethod.Patch, token);
|
|
||||||
}
|
|
||||||
|
|
||||||
public virtual async Task<IEnumerable<OnChainWalletUTXOData>> GetOnChainWalletUTXOs(string storeId,
|
|
||||||
string cryptoCode,
|
|
||||||
CancellationToken token = default)
|
|
||||||
{
|
|
||||||
return await SendHttpRequest<IEnumerable<OnChainWalletUTXOData>>($"api/v1/stores/{storeId}/payment-methods/{cryptoCode}-CHAIN/wallet/utxos", null, HttpMethod.Get, token);
|
|
||||||
}
|
|
||||||
|
|
||||||
public virtual async Task<OnChainWalletTransactionData> CreateOnChainTransaction(string storeId,
|
|
||||||
string cryptoCode, CreateOnChainTransactionRequest request,
|
|
||||||
CancellationToken token = default)
|
|
||||||
{
|
|
||||||
if (!request.ProceedWithBroadcast)
|
|
||||||
{
|
{
|
||||||
throw new ArgumentOutOfRangeException(nameof(request.ProceedWithBroadcast),
|
var query = new Dictionary<string, object>();
|
||||||
"Please use CreateOnChainTransactionButDoNotBroadcast when wanting to only create the transaction");
|
if (statusFilter?.Any() is true)
|
||||||
|
{
|
||||||
|
query.Add(nameof(statusFilter), statusFilter);
|
||||||
|
}
|
||||||
|
if (labelFilter != null)
|
||||||
|
{
|
||||||
|
query.Add(nameof(labelFilter), labelFilter);
|
||||||
|
}
|
||||||
|
var response =
|
||||||
|
await _httpClient.SendAsync(
|
||||||
|
CreateHttpRequest($"api/v1/stores/{storeId}/payment-methods/onchain/{cryptoCode}/wallet/transactions", query), token);
|
||||||
|
return await HandleResponse<IEnumerable<OnChainWalletTransactionData>>(response);
|
||||||
}
|
}
|
||||||
return await SendHttpRequest<OnChainWalletTransactionData>($"api/v1/stores/{storeId}/payment-methods/{cryptoCode}-CHAIN/wallet/transactions", request, HttpMethod.Post, token);
|
|
||||||
}
|
|
||||||
|
|
||||||
public virtual async Task<Transaction> CreateOnChainTransactionButDoNotBroadcast(string storeId,
|
public virtual async Task<OnChainWalletTransactionData> GetOnChainWalletTransaction(
|
||||||
string cryptoCode, CreateOnChainTransactionRequest request, Network network,
|
string storeId, string cryptoCode, string transactionId,
|
||||||
CancellationToken token = default)
|
CancellationToken token = default)
|
||||||
{
|
|
||||||
if (request.ProceedWithBroadcast)
|
|
||||||
{
|
{
|
||||||
throw new ArgumentOutOfRangeException(nameof(request.ProceedWithBroadcast),
|
var response =
|
||||||
"Please use CreateOnChainTransaction when wanting to also broadcast the transaction");
|
await _httpClient.SendAsync(
|
||||||
|
CreateHttpRequest($"api/v1/stores/{storeId}/payment-methods/onchain/{cryptoCode}/wallet/transactions/{transactionId}"), token);
|
||||||
|
return await HandleResponse<OnChainWalletTransactionData>(response);
|
||||||
|
}
|
||||||
|
|
||||||
|
public virtual async Task<OnChainWalletTransactionData> PatchOnChainWalletTransaction(
|
||||||
|
string storeId, string cryptoCode, string transactionId,
|
||||||
|
PatchOnChainTransactionRequest request,
|
||||||
|
bool force = false, CancellationToken token = default)
|
||||||
|
{
|
||||||
|
var response =
|
||||||
|
await _httpClient.SendAsync(
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
public virtual async Task<IEnumerable<OnChainWalletUTXOData>> GetOnChainWalletUTXOs(string storeId,
|
||||||
|
string cryptoCode,
|
||||||
|
CancellationToken token = default)
|
||||||
|
{
|
||||||
|
var response =
|
||||||
|
await _httpClient.SendAsync(
|
||||||
|
CreateHttpRequest($"api/v1/stores/{storeId}/payment-methods/onchain/{cryptoCode}/wallet/utxos"), token);
|
||||||
|
return await HandleResponse<IEnumerable<OnChainWalletUTXOData>>(response);
|
||||||
|
}
|
||||||
|
|
||||||
|
public virtual async Task<OnChainWalletTransactionData> CreateOnChainTransaction(string storeId,
|
||||||
|
string cryptoCode, CreateOnChainTransactionRequest request,
|
||||||
|
CancellationToken token = default)
|
||||||
|
{
|
||||||
|
if (!request.ProceedWithBroadcast)
|
||||||
|
{
|
||||||
|
throw new ArgumentOutOfRangeException(nameof(request.ProceedWithBroadcast),
|
||||||
|
"Please use CreateOnChainTransactionButDoNotBroadcast when wanting to only create the transaction");
|
||||||
|
}
|
||||||
|
var response =
|
||||||
|
await _httpClient.SendAsync(
|
||||||
|
CreateHttpRequest($"api/v1/stores/{storeId}/payment-methods/onchain/{cryptoCode}/wallet/transactions", null, request, HttpMethod.Post), token);
|
||||||
|
return await HandleResponse<OnChainWalletTransactionData>(response);
|
||||||
|
}
|
||||||
|
|
||||||
|
public virtual async Task<Transaction> CreateOnChainTransactionButDoNotBroadcast(string storeId,
|
||||||
|
string cryptoCode, CreateOnChainTransactionRequest request, Network network,
|
||||||
|
CancellationToken token = default)
|
||||||
|
{
|
||||||
|
if (request.ProceedWithBroadcast)
|
||||||
|
{
|
||||||
|
throw new ArgumentOutOfRangeException(nameof(request.ProceedWithBroadcast),
|
||||||
|
"Please use CreateOnChainTransaction when wanting to also broadcast the transaction");
|
||||||
|
}
|
||||||
|
var response =
|
||||||
|
await _httpClient.SendAsync(
|
||||||
|
CreateHttpRequest($"api/v1/stores/{storeId}/payment-methods/onchain/{cryptoCode}/wallet/transactions", null, request, HttpMethod.Post), token);
|
||||||
|
return Transaction.Parse(await HandleResponse<string>(response), network);
|
||||||
}
|
}
|
||||||
return Transaction.Parse(await SendHttpRequest<string>($"api/v1/stores/{storeId}/payment-methods/{cryptoCode}-CHAIN/wallet/transactions", request, HttpMethod.Post, token), network);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -5,49 +5,72 @@ using System.Threading;
|
|||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using BTCPayServer.Client.Models;
|
using BTCPayServer.Client.Models;
|
||||||
|
|
||||||
namespace BTCPayServer.Client;
|
namespace BTCPayServer.Client
|
||||||
|
|
||||||
public partial class BTCPayServerClient
|
|
||||||
{
|
{
|
||||||
public virtual async Task<IEnumerable<PaymentRequestData>> GetPaymentRequests(string storeId,
|
public partial class BTCPayServerClient
|
||||||
bool includeArchived = false,
|
|
||||||
CancellationToken token = default)
|
|
||||||
{
|
{
|
||||||
return await SendHttpRequest<IEnumerable<PaymentRequestData>>($"api/v1/stores/{storeId}/payment-requests",
|
public virtual async Task<IEnumerable<PaymentRequestData>> GetPaymentRequests(string storeId,
|
||||||
new Dictionary<string, object> { { nameof(includeArchived), includeArchived } }, HttpMethod.Get, token);
|
bool includeArchived = false,
|
||||||
}
|
CancellationToken token = default)
|
||||||
|
{
|
||||||
|
var response =
|
||||||
|
await _httpClient.SendAsync(
|
||||||
|
CreateHttpRequest($"api/v1/stores/{storeId}/payment-requests",
|
||||||
|
new Dictionary<string, object>() { { nameof(includeArchived), includeArchived } }), token);
|
||||||
|
return await HandleResponse<IEnumerable<PaymentRequestData>>(response);
|
||||||
|
}
|
||||||
|
|
||||||
public virtual async Task<PaymentRequestData> GetPaymentRequest(string storeId, string paymentRequestId,
|
public virtual async Task<PaymentRequestData> GetPaymentRequest(string storeId, string paymentRequestId,
|
||||||
CancellationToken token = default)
|
CancellationToken token = default)
|
||||||
{
|
{
|
||||||
return await SendHttpRequest<PaymentRequestData>($"api/v1/stores/{storeId}/payment-requests/{paymentRequestId}", null, HttpMethod.Get, token);
|
var response = await _httpClient.SendAsync(
|
||||||
}
|
CreateHttpRequest($"api/v1/stores/{storeId}/payment-requests/{paymentRequestId}"), token);
|
||||||
|
return await HandleResponse<PaymentRequestData>(response);
|
||||||
|
}
|
||||||
|
|
||||||
public virtual async Task ArchivePaymentRequest(string storeId, string paymentRequestId,
|
public virtual async Task ArchivePaymentRequest(string storeId, string paymentRequestId,
|
||||||
CancellationToken token = default)
|
CancellationToken token = default)
|
||||||
{
|
{
|
||||||
await SendHttpRequest($"api/v1/stores/{storeId}/payment-requests/{paymentRequestId}", null, HttpMethod.Delete, token);
|
var response = await _httpClient.SendAsync(
|
||||||
}
|
CreateHttpRequest($"api/v1/stores/{storeId}/payment-requests/{paymentRequestId}",
|
||||||
|
method: HttpMethod.Delete), token);
|
||||||
|
await HandleResponse(response);
|
||||||
|
}
|
||||||
|
|
||||||
public virtual async Task<Client.Models.InvoiceData> PayPaymentRequest(string storeId, string paymentRequestId, PayPaymentRequestRequest request, CancellationToken token = default)
|
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 (request == null)
|
||||||
if (storeId is null) throw new ArgumentNullException(nameof(storeId));
|
throw new ArgumentNullException(nameof(request));
|
||||||
if (paymentRequestId is null) throw new ArgumentNullException(nameof(paymentRequestId));
|
if (storeId is null)
|
||||||
return await SendHttpRequest<InvoiceData>($"api/v1/stores/{storeId}/payment-requests/{paymentRequestId}/pay", request, HttpMethod.Post, token);
|
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,
|
public virtual async Task<PaymentRequestData> CreatePaymentRequest(string storeId,
|
||||||
CreatePaymentRequestRequest request, CancellationToken token = default)
|
CreatePaymentRequestRequest request, CancellationToken token = default)
|
||||||
{
|
{
|
||||||
if (request == null) throw new ArgumentNullException(nameof(request));
|
if (request == null)
|
||||||
return await SendHttpRequest<PaymentRequestData>($"api/v1/stores/{storeId}/payment-requests", request, HttpMethod.Post, token);
|
throw new ArgumentNullException(nameof(request));
|
||||||
}
|
var response = await _httpClient.SendAsync(
|
||||||
|
CreateHttpRequest($"api/v1/stores/{storeId}/payment-requests", bodyPayload: request,
|
||||||
|
method: HttpMethod.Post), token);
|
||||||
|
return await HandleResponse<PaymentRequestData>(response);
|
||||||
|
}
|
||||||
|
|
||||||
public virtual async Task<PaymentRequestData> UpdatePaymentRequest(string storeId, string paymentRequestId,
|
public virtual async Task<PaymentRequestData> UpdatePaymentRequest(string storeId, string paymentRequestId,
|
||||||
UpdatePaymentRequestRequest request, CancellationToken token = default)
|
UpdatePaymentRequestRequest request, CancellationToken token = default)
|
||||||
{
|
{
|
||||||
if (request == null) throw new ArgumentNullException(nameof(request));
|
if (request == null)
|
||||||
return await SendHttpRequest<PaymentRequestData>($"api/v1/stores/{storeId}/payment-requests/{paymentRequestId}", request, HttpMethod.Put, token);
|
throw new ArgumentNullException(nameof(request));
|
||||||
|
var response = await _httpClient.SendAsync(
|
||||||
|
CreateHttpRequest($"api/v1/stores/{storeId}/payment-requests/{paymentRequestId}", bodyPayload: request,
|
||||||
|
method: HttpMethod.Put), token);
|
||||||
|
return await HandleResponse<PaymentRequestData>(response);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1,16 +1,18 @@
|
|||||||
#nullable enable
|
#nullable enable
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Net.Http;
|
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using BTCPayServer.Client.Models;
|
using BTCPayServer.Client.Models;
|
||||||
|
|
||||||
namespace BTCPayServer.Client;
|
namespace BTCPayServer.Client
|
||||||
|
|
||||||
public partial class BTCPayServerClient
|
|
||||||
{
|
{
|
||||||
public virtual async Task<IEnumerable<PayoutProcessorData>> GetPayoutProcessors(CancellationToken token = default)
|
public partial class BTCPayServerClient
|
||||||
{
|
{
|
||||||
return await SendHttpRequest<IEnumerable<PayoutProcessorData>>("api/v1/payout-processors", null, HttpMethod.Get, token);
|
public virtual async Task<IEnumerable<PayoutProcessorData>> GetPayoutProcessors(
|
||||||
|
CancellationToken token = default)
|
||||||
|
{
|
||||||
|
var response = await _httpClient.SendAsync(CreateHttpRequest("api/v1/payout-processors"), token);
|
||||||
|
return await HandleResponse<IEnumerable<PayoutProcessorData>>(response);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -5,90 +5,107 @@ using System.Threading.Tasks;
|
|||||||
using System.Web;
|
using System.Web;
|
||||||
using BTCPayServer.Client.Models;
|
using BTCPayServer.Client.Models;
|
||||||
|
|
||||||
namespace BTCPayServer.Client;
|
namespace BTCPayServer.Client
|
||||||
|
|
||||||
public partial class BTCPayServerClient
|
|
||||||
{
|
{
|
||||||
public virtual async Task<PullPaymentData> CreatePullPayment(string storeId, CreatePullPaymentRequest request, CancellationToken cancellationToken = default)
|
public partial class BTCPayServerClient
|
||||||
{
|
{
|
||||||
return await SendHttpRequest<PullPaymentData>($"api/v1/stores/{HttpUtility.UrlEncode(storeId)}/pull-payments", request, HttpMethod.Post, cancellationToken);
|
public virtual async Task<PullPaymentData> CreatePullPayment(string storeId, CreatePullPaymentRequest request, CancellationToken cancellationToken = default)
|
||||||
}
|
{
|
||||||
|
var response = await _httpClient.SendAsync(CreateHttpRequest($"api/v1/stores/{HttpUtility.UrlEncode(storeId)}/pull-payments", bodyPayload: request, method: HttpMethod.Post), cancellationToken);
|
||||||
|
return await HandleResponse<PullPaymentData>(response);
|
||||||
|
}
|
||||||
|
public virtual async Task<PullPaymentData> GetPullPayment(string pullPaymentId, CancellationToken cancellationToken = default)
|
||||||
|
{
|
||||||
|
var response = await _httpClient.SendAsync(CreateHttpRequest($"api/v1/pull-payments/{HttpUtility.UrlEncode(pullPaymentId)}", method: HttpMethod.Get), cancellationToken);
|
||||||
|
return await HandleResponse<PullPaymentData>(response);
|
||||||
|
}
|
||||||
|
|
||||||
public virtual async Task<PullPaymentData> GetPullPayment(string pullPaymentId, CancellationToken cancellationToken = default)
|
public virtual async Task<PullPaymentData[]> GetPullPayments(string storeId, bool includeArchived = false, CancellationToken cancellationToken = default)
|
||||||
{
|
{
|
||||||
return await SendHttpRequest<PullPaymentData>($"api/v1/pull-payments/{HttpUtility.UrlEncode(pullPaymentId)}", null, HttpMethod.Get, cancellationToken);
|
Dictionary<string, object> query = new Dictionary<string, object>();
|
||||||
}
|
query.Add("includeArchived", includeArchived);
|
||||||
|
var response = await _httpClient.SendAsync(CreateHttpRequest($"api/v1/stores/{HttpUtility.UrlEncode(storeId)}/pull-payments", queryPayload: query, method: HttpMethod.Get), cancellationToken);
|
||||||
|
return await HandleResponse<PullPaymentData[]>(response);
|
||||||
|
}
|
||||||
|
|
||||||
public virtual async Task<RegisterBoltcardResponse> RegisterBoltcard(string pullPaymentId, RegisterBoltcardRequest request, CancellationToken cancellationToken = default)
|
public virtual async Task ArchivePullPayment(string storeId, string pullPaymentId, CancellationToken cancellationToken = default)
|
||||||
{
|
{
|
||||||
return await SendHttpRequest<RegisterBoltcardResponse>($"api/v1/pull-payments/{HttpUtility.UrlEncode(pullPaymentId)}/boltcards", request, HttpMethod.Post, cancellationToken);
|
var response = await _httpClient.SendAsync(CreateHttpRequest($"api/v1/stores/{HttpUtility.UrlEncode(storeId)}/pull-payments/{HttpUtility.UrlEncode(pullPaymentId)}", method: HttpMethod.Delete), cancellationToken);
|
||||||
}
|
await HandleResponse(response);
|
||||||
|
}
|
||||||
|
|
||||||
public virtual async Task<PullPaymentData[]> GetPullPayments(string storeId, bool includeArchived = false, CancellationToken cancellationToken = default)
|
public virtual async Task<PayoutData[]> GetPayouts(string pullPaymentId, bool includeCancelled = false, CancellationToken cancellationToken = default)
|
||||||
{
|
{
|
||||||
var query = new Dictionary<string, object> { { "includeArchived", includeArchived } };
|
Dictionary<string, object> query = new Dictionary<string, object>();
|
||||||
return await SendHttpRequest<PullPaymentData[]>($"api/v1/stores/{HttpUtility.UrlEncode(storeId)}/pull-payments", query, HttpMethod.Get, cancellationToken);
|
query.Add("includeCancelled", includeCancelled);
|
||||||
}
|
var response = await _httpClient.SendAsync(CreateHttpRequest($"api/v1/pull-payments/{HttpUtility.UrlEncode(pullPaymentId)}/payouts", queryPayload: query, method: HttpMethod.Get), cancellationToken);
|
||||||
|
return await HandleResponse<PayoutData[]>(response);
|
||||||
|
}
|
||||||
|
public virtual async Task<PayoutData[]> GetStorePayouts(string storeId, bool includeCancelled = false, CancellationToken cancellationToken = default)
|
||||||
|
{
|
||||||
|
Dictionary<string, object> query = new Dictionary<string, object>();
|
||||||
|
query.Add("includeCancelled", includeCancelled);
|
||||||
|
var response = await _httpClient.SendAsync(CreateHttpRequest($"api/v1/stores/{storeId}/payouts", queryPayload: query, method: HttpMethod.Get), cancellationToken);
|
||||||
|
return await HandleResponse<PayoutData[]>(response);
|
||||||
|
}
|
||||||
|
public virtual async Task<PayoutData> CreatePayout(string pullPaymentId, CreatePayoutRequest payoutRequest, CancellationToken cancellationToken = default)
|
||||||
|
{
|
||||||
|
var response = await _httpClient.SendAsync(CreateHttpRequest($"api/v1/pull-payments/{HttpUtility.UrlEncode(pullPaymentId)}/payouts", bodyPayload: payoutRequest, method: HttpMethod.Post), cancellationToken);
|
||||||
|
return await HandleResponse<PayoutData>(response);
|
||||||
|
}
|
||||||
|
public 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);
|
||||||
|
return await HandleResponse<PayoutData>(response);
|
||||||
|
}
|
||||||
|
public virtual async Task CancelPayout(string storeId, string payoutId, CancellationToken cancellationToken = default)
|
||||||
|
{
|
||||||
|
var response = await _httpClient.SendAsync(CreateHttpRequest($"api/v1/stores/{HttpUtility.UrlEncode(storeId)}/payouts/{HttpUtility.UrlEncode(payoutId)}", method: HttpMethod.Delete), cancellationToken);
|
||||||
|
await HandleResponse(response);
|
||||||
|
}
|
||||||
|
public virtual async Task<PayoutData> ApprovePayout(string storeId, string payoutId, ApprovePayoutRequest request, CancellationToken cancellationToken = default)
|
||||||
|
{
|
||||||
|
var response = await _httpClient.SendAsync(CreateHttpRequest($"api/v1/stores/{HttpUtility.UrlEncode(storeId)}/payouts/{HttpUtility.UrlEncode(payoutId)}", bodyPayload: request, method: HttpMethod.Post), cancellationToken);
|
||||||
|
return await HandleResponse<PayoutData>(response);
|
||||||
|
}
|
||||||
|
|
||||||
public virtual async Task ArchivePullPayment(string storeId, string pullPaymentId, CancellationToken cancellationToken = default)
|
public virtual async Task MarkPayoutPaid(string storeId, string payoutId,
|
||||||
{
|
CancellationToken cancellationToken = default)
|
||||||
await SendHttpRequest($"api/v1/stores/{HttpUtility.UrlEncode(storeId)}/pull-payments/{HttpUtility.UrlEncode(pullPaymentId)}", null, HttpMethod.Delete, cancellationToken);
|
{
|
||||||
}
|
var response = await _httpClient.SendAsync(
|
||||||
|
CreateHttpRequest(
|
||||||
|
$"api/v1/stores/{HttpUtility.UrlEncode(storeId)}/payouts/{HttpUtility.UrlEncode(payoutId)}/mark-paid",
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
public virtual async Task<PayoutData[]> GetPayouts(string pullPaymentId, bool includeCancelled = false, CancellationToken cancellationToken = default)
|
public virtual async Task<PullPaymentLNURL> GetPullPaymentLNURL(string pullPaymentId,
|
||||||
{
|
CancellationToken cancellationToken = default)
|
||||||
var query = new Dictionary<string, object> { { "includeCancelled", includeCancelled } };
|
{
|
||||||
return await SendHttpRequest<PayoutData[]>($"api/v1/pull-payments/{HttpUtility.UrlEncode(pullPaymentId)}/payouts", query, HttpMethod.Get, cancellationToken);
|
var response = await _httpClient.SendAsync(
|
||||||
}
|
CreateHttpRequest(
|
||||||
|
$"/api/v1/pull-payments/{pullPaymentId}/lnurl",
|
||||||
public virtual async Task<PayoutData[]> GetStorePayouts(string storeId, bool includeCancelled = false, CancellationToken cancellationToken = default)
|
method: HttpMethod.Get), cancellationToken);
|
||||||
{
|
return await HandleResponse<PullPaymentLNURL>(response);
|
||||||
var query = new Dictionary<string, object> { { "includeCancelled", includeCancelled } };
|
}
|
||||||
return await SendHttpRequest<PayoutData[]>($"api/v1/stores/{storeId}/payouts", queryPayload: query, method: HttpMethod.Get, cancellationToken);
|
|
||||||
}
|
|
||||||
|
|
||||||
public virtual async Task<PayoutData> CreatePayout(string pullPaymentId, CreatePayoutRequest payoutRequest, CancellationToken cancellationToken = default)
|
|
||||||
{
|
|
||||||
return await SendHttpRequest<PayoutData>($"api/v1/pull-payments/{HttpUtility.UrlEncode(pullPaymentId)}/payouts", bodyPayload: payoutRequest, HttpMethod.Post, cancellationToken);
|
|
||||||
}
|
|
||||||
|
|
||||||
public virtual async Task<PayoutData> GetPullPaymentPayout(string pullPaymentId, string payoutId, CancellationToken cancellationToken = default)
|
|
||||||
{
|
|
||||||
return await SendHttpRequest<PayoutData>($"api/v1/pull-payments/{HttpUtility.UrlEncode(pullPaymentId)}/payouts/{payoutId}", null, HttpMethod.Get, cancellationToken);
|
|
||||||
}
|
|
||||||
|
|
||||||
public virtual async Task<PayoutData> GetStorePayout(string storeId, string payoutId, CancellationToken cancellationToken = default)
|
|
||||||
{
|
|
||||||
return await SendHttpRequest<PayoutData>($"api/v1/stores/{storeId}/payouts/{payoutId}", null, HttpMethod.Get, cancellationToken);
|
|
||||||
}
|
|
||||||
|
|
||||||
public virtual async Task<PayoutData> CreatePayout(string storeId, CreatePayoutThroughStoreRequest payoutRequest, CancellationToken cancellationToken = default)
|
|
||||||
{
|
|
||||||
return await SendHttpRequest<PayoutData>($"api/v1/stores/{storeId}/payouts", bodyPayload: payoutRequest, method: HttpMethod.Post, cancellationToken);
|
|
||||||
}
|
|
||||||
|
|
||||||
public virtual async Task CancelPayout(string storeId, string payoutId, CancellationToken cancellationToken = default)
|
|
||||||
{
|
|
||||||
await SendHttpRequest($"api/v1/stores/{HttpUtility.UrlEncode(storeId)}/payouts/{HttpUtility.UrlEncode(payoutId)}", null, HttpMethod.Delete, cancellationToken);
|
|
||||||
}
|
|
||||||
|
|
||||||
public virtual async Task<PayoutData> ApprovePayout(string storeId, string payoutId, ApprovePayoutRequest request, CancellationToken cancellationToken = default)
|
|
||||||
{
|
|
||||||
return await SendHttpRequest<PayoutData>($"api/v1/stores/{HttpUtility.UrlEncode(storeId)}/payouts/{HttpUtility.UrlEncode(payoutId)}", request, HttpMethod.Post, cancellationToken);
|
|
||||||
}
|
|
||||||
|
|
||||||
public virtual async Task MarkPayoutPaid(string storeId, string payoutId, CancellationToken cancellationToken = default)
|
|
||||||
{
|
|
||||||
await SendHttpRequest($"api/v1/stores/{HttpUtility.UrlEncode(storeId)}/payouts/{HttpUtility.UrlEncode(payoutId)}/mark-paid", null, HttpMethod.Post, cancellationToken);
|
|
||||||
}
|
|
||||||
|
|
||||||
public virtual async Task MarkPayout(string storeId, string payoutId, MarkPayoutRequest request, CancellationToken cancellationToken = default)
|
|
||||||
{
|
|
||||||
await SendHttpRequest($"api/v1/stores/{HttpUtility.UrlEncode(storeId)}/payouts/{HttpUtility.UrlEncode(payoutId)}/mark", request, HttpMethod.Post, cancellationToken);
|
|
||||||
}
|
|
||||||
|
|
||||||
public virtual async Task<PullPaymentLNURL> GetPullPaymentLNURL(string pullPaymentId, CancellationToken cancellationToken = default)
|
|
||||||
{
|
|
||||||
return await SendHttpRequest<PullPaymentLNURL>($"api/v1/pull-payments/{HttpUtility.UrlEncode(pullPaymentId)}/lnurl", null, HttpMethod.Get, cancellationToken);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1,20 +1,15 @@
|
|||||||
using System.Collections.Generic;
|
|
||||||
using System.Net.Http;
|
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using BTCPayServer.Client.Models;
|
using BTCPayServer.Client.Models;
|
||||||
|
|
||||||
namespace BTCPayServer.Client;
|
namespace BTCPayServer.Client
|
||||||
|
|
||||||
public partial class BTCPayServerClient
|
|
||||||
{
|
{
|
||||||
public virtual async Task<ServerInfoData> GetServerInfo(CancellationToken token = default)
|
public partial class BTCPayServerClient
|
||||||
{
|
{
|
||||||
return await SendHttpRequest<ServerInfoData>("api/v1/server/info", null, HttpMethod.Get, token);
|
public virtual async Task<ServerInfoData> GetServerInfo(CancellationToken token = default)
|
||||||
}
|
{
|
||||||
|
var response = await _httpClient.SendAsync(CreateHttpRequest("api/v1/server/info"), token);
|
||||||
public virtual async Task<List<RoleData>> GetServerRoles(CancellationToken token = default)
|
return await HandleResponse<ServerInfoData>(response);
|
||||||
{
|
}
|
||||||
return await SendHttpRequest<List<RoleData>>("api/v1/server/roles", null, HttpMethod.Get, token);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -3,22 +3,35 @@ using System.Threading;
|
|||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using BTCPayServer.Client.Models;
|
using BTCPayServer.Client.Models;
|
||||||
|
|
||||||
namespace BTCPayServer.Client;
|
namespace BTCPayServer.Client
|
||||||
|
|
||||||
public partial class BTCPayServerClient
|
|
||||||
{
|
{
|
||||||
public virtual async Task<EmailSettingsData> GetStoreEmailSettings(string storeId, CancellationToken token = default)
|
public partial class BTCPayServerClient
|
||||||
{
|
{
|
||||||
return await SendHttpRequest<EmailSettingsData>($"api/v1/stores/{storeId}/email", null, HttpMethod.Get, token);
|
public virtual async Task<EmailSettingsData> GetStoreEmailSettings(string storeId,
|
||||||
}
|
CancellationToken token = default)
|
||||||
|
{
|
||||||
|
using var response = await _httpClient.SendAsync(
|
||||||
|
CreateHttpRequest($"api/v1/stores/{storeId}/email", method: HttpMethod.Get),
|
||||||
|
token);
|
||||||
|
return await HandleResponse<EmailSettingsData>(response);
|
||||||
|
}
|
||||||
|
|
||||||
public virtual async Task<EmailSettingsData> UpdateStoreEmailSettings(string storeId, EmailSettingsData request, CancellationToken token = default)
|
public virtual async Task<EmailSettingsData> UpdateStoreEmailSettings(string storeId, EmailSettingsData request,
|
||||||
{
|
CancellationToken token = default)
|
||||||
return await SendHttpRequest<EmailSettingsData>($"api/v1/stores/{storeId}/email", request, method: HttpMethod.Put, token);
|
{
|
||||||
}
|
using var response = await _httpClient.SendAsync(
|
||||||
|
CreateHttpRequest($"api/v1/stores/{storeId}/email", bodyPayload: request, method: HttpMethod.Put),
|
||||||
|
token);
|
||||||
|
return await HandleResponse<EmailSettingsData>(response);
|
||||||
|
}
|
||||||
|
|
||||||
public virtual async Task SendEmail(string storeId, SendEmailRequest request, CancellationToken token = default)
|
public virtual async Task SendEmail(string storeId, SendEmailRequest request,
|
||||||
{
|
CancellationToken token = default)
|
||||||
await SendHttpRequest($"api/v1/stores/{storeId}/email/send", request, HttpMethod.Post, token);
|
{
|
||||||
|
using var response = await _httpClient.SendAsync(
|
||||||
|
CreateHttpRequest($"api/v1/stores/{storeId}/email/send", bodyPayload: request, method: HttpMethod.Post),
|
||||||
|
token);
|
||||||
|
await HandleResponse(response);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1,45 +1,27 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Net.Http;
|
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using BTCPayServer.Client.Models;
|
using BTCPayServer.Client.Models;
|
||||||
|
|
||||||
namespace BTCPayServer.Client;
|
namespace BTCPayServer.Client
|
||||||
|
|
||||||
public partial class BTCPayServerClient
|
|
||||||
{
|
{
|
||||||
public virtual async Task<GenericPaymentMethodData> UpdateStorePaymentMethod(string storeId, string paymentMethodId, UpdatePaymentMethodRequest request, CancellationToken token = default)
|
public partial class BTCPayServerClient
|
||||||
{
|
{
|
||||||
return await SendHttpRequest<GenericPaymentMethodData>($"api/v1/stores/{storeId}/payment-methods/{paymentMethodId}", request, HttpMethod.Put, token);
|
public virtual async Task<Dictionary<string, GenericPaymentMethodData>> GetStorePaymentMethods(string storeId,
|
||||||
}
|
bool? enabled = null,
|
||||||
|
CancellationToken token = default)
|
||||||
public virtual async Task RemoveStorePaymentMethod(string storeId, string paymentMethodId)
|
|
||||||
{
|
|
||||||
await SendHttpRequest($"api/v1/stores/{storeId}/payment-methods/{paymentMethodId}", null, HttpMethod.Delete, CancellationToken.None);
|
|
||||||
}
|
|
||||||
|
|
||||||
public virtual async Task<GenericPaymentMethodData> GetStorePaymentMethod(string storeId, string paymentMethodId, bool? includeConfig = null, CancellationToken token = default)
|
|
||||||
{
|
|
||||||
var query = new Dictionary<string, object>();
|
|
||||||
if (includeConfig != null)
|
|
||||||
{
|
{
|
||||||
query.Add(nameof(includeConfig), includeConfig);
|
var query = new Dictionary<string, object>();
|
||||||
}
|
if (enabled != null)
|
||||||
return await SendHttpRequest<GenericPaymentMethodData>($"api/v1/stores/{storeId}/payment-methods/{paymentMethodId}", query, HttpMethod.Get, token);
|
{
|
||||||
}
|
query.Add(nameof(enabled), enabled);
|
||||||
|
}
|
||||||
|
|
||||||
public virtual async Task<GenericPaymentMethodData[]> GetStorePaymentMethods(string storeId, bool? onlyEnabled = null, bool? includeConfig = null, CancellationToken token = default)
|
var response =
|
||||||
{
|
await _httpClient.SendAsync(
|
||||||
var query = new Dictionary<string, object>();
|
CreateHttpRequest($"api/v1/stores/{storeId}/payment-methods",
|
||||||
if (onlyEnabled != null)
|
query), token);
|
||||||
{
|
return await HandleResponse<Dictionary<string, GenericPaymentMethodData>>(response);
|
||||||
query.Add(nameof(onlyEnabled), onlyEnabled);
|
|
||||||
}
|
}
|
||||||
if (includeConfig != null)
|
|
||||||
{
|
|
||||||
query.Add(nameof(includeConfig), includeConfig);
|
|
||||||
}
|
|
||||||
|
|
||||||
return await SendHttpRequest<GenericPaymentMethodData[]>($"api/v1/stores/{storeId}/payment-methods", query, HttpMethod.Get, token);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -5,37 +5,44 @@ using System.Threading;
|
|||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using BTCPayServer.Client.Models;
|
using BTCPayServer.Client.Models;
|
||||||
|
|
||||||
namespace BTCPayServer.Client;
|
namespace BTCPayServer.Client
|
||||||
|
|
||||||
public partial class BTCPayServerClient
|
|
||||||
{
|
{
|
||||||
public virtual async Task<IEnumerable<PayoutProcessorData>> GetPayoutProcessors(string storeId, CancellationToken token = default)
|
public partial class BTCPayServerClient
|
||||||
{
|
{
|
||||||
return await SendHttpRequest<IEnumerable<PayoutProcessorData>>($"api/v1/stores/{storeId}/payout-processors", null, HttpMethod.Get, token);
|
public virtual async Task<IEnumerable<PayoutProcessorData>> GetPayoutProcessors(string storeId,
|
||||||
}
|
CancellationToken token = default)
|
||||||
|
{
|
||||||
|
var response = await _httpClient.SendAsync(CreateHttpRequest($"api/v1/stores/{storeId}/payout-processors"), token);
|
||||||
|
return await HandleResponse<IEnumerable<PayoutProcessorData>>(response);
|
||||||
|
}
|
||||||
|
public virtual async Task RemovePayoutProcessor(string storeId, string processor, string paymentMethod, CancellationToken token = default)
|
||||||
|
{
|
||||||
|
var response = await _httpClient.SendAsync(CreateHttpRequest($"api/v1/stores/{storeId}/payout-processors/{processor}/{paymentMethod}", null, HttpMethod.Delete), token);
|
||||||
|
await HandleResponse(response);
|
||||||
|
}
|
||||||
|
|
||||||
public virtual async Task RemovePayoutProcessor(string storeId, string processor, string paymentMethod, CancellationToken token = default)
|
public virtual async Task<IEnumerable<LightningAutomatedPayoutSettings>> GetStoreLightningAutomatedPayoutProcessors(string storeId, string? paymentMethod = null,
|
||||||
{
|
CancellationToken token = default)
|
||||||
await SendHttpRequest($"api/v1/stores/{storeId}/payout-processors/{processor}/{paymentMethod}", null, HttpMethod.Delete, token);
|
{
|
||||||
}
|
var response = await _httpClient.SendAsync(CreateHttpRequest($"api/v1/stores/{storeId}/payout-processors/LightningAutomatedPayoutSenderFactory{(paymentMethod is null ? string.Empty : $"/{paymentMethod}")}"), token);
|
||||||
|
return await HandleResponse<IEnumerable<LightningAutomatedPayoutSettings>>(response);
|
||||||
|
}
|
||||||
|
public virtual async Task<LightningAutomatedPayoutSettings> UpdateStoreLightningAutomatedPayoutProcessors(string storeId, string paymentMethod, LightningAutomatedPayoutSettings request, CancellationToken token = default)
|
||||||
|
{
|
||||||
|
var response = await _httpClient.SendAsync(CreateHttpRequest($"api/v1/stores/{storeId}/payout-processors/LightningAutomatedPayoutSenderFactory/{paymentMethod}", null, request, HttpMethod.Put), token);
|
||||||
|
return await HandleResponse<LightningAutomatedPayoutSettings>(response);
|
||||||
|
}
|
||||||
|
public virtual async Task<OnChainAutomatedPayoutSettings> UpdateStoreOnChainAutomatedPayoutProcessors(string storeId, string paymentMethod, OnChainAutomatedPayoutSettings request, CancellationToken token = default)
|
||||||
|
{
|
||||||
|
var response = await _httpClient.SendAsync(CreateHttpRequest($"api/v1/stores/{storeId}/payout-processors/OnChainAutomatedPayoutSenderFactory/{paymentMethod}", null, request, HttpMethod.Put), token);
|
||||||
|
return await HandleResponse<OnChainAutomatedPayoutSettings>(response);
|
||||||
|
}
|
||||||
|
|
||||||
public virtual async Task<IEnumerable<LightningAutomatedPayoutSettings>> GetStoreLightningAutomatedPayoutProcessors(string storeId, string? payoutMethodId = null, CancellationToken token = default)
|
public virtual async Task<IEnumerable<OnChainAutomatedPayoutSettings>> GetStoreOnChainAutomatedPayoutProcessors(string storeId, string? paymentMethod = null,
|
||||||
{
|
CancellationToken token = default)
|
||||||
return await SendHttpRequest<IEnumerable<LightningAutomatedPayoutSettings>>($"api/v1/stores/{storeId}/payout-processors/LightningAutomatedPayoutSenderFactory{(payoutMethodId is null ? string.Empty : $"/{payoutMethodId}")}", null, HttpMethod.Get, token);
|
{
|
||||||
}
|
var response = await _httpClient.SendAsync(CreateHttpRequest($"api/v1/stores/{storeId}/payout-processors/OnChainAutomatedPayoutSenderFactory{(paymentMethod is null ? string.Empty : $"/{paymentMethod}")}"), token);
|
||||||
|
return await HandleResponse<IEnumerable<OnChainAutomatedPayoutSettings>>(response);
|
||||||
public virtual async Task<LightningAutomatedPayoutSettings> UpdateStoreLightningAutomatedPayoutProcessors(string storeId, string payoutMethodId, LightningAutomatedPayoutSettings request, CancellationToken token = default)
|
}
|
||||||
{
|
|
||||||
return await SendHttpRequest<LightningAutomatedPayoutSettings>($"api/v1/stores/{storeId}/payout-processors/LightningAutomatedPayoutSenderFactory/{payoutMethodId}", request, HttpMethod.Put, token);
|
|
||||||
}
|
|
||||||
|
|
||||||
public virtual async Task<OnChainAutomatedPayoutSettings> UpdateStoreOnChainAutomatedPayoutProcessors(string storeId, string paymentMethod, OnChainAutomatedPayoutSettings request, CancellationToken token = default)
|
|
||||||
{
|
|
||||||
return await SendHttpRequest<OnChainAutomatedPayoutSettings>($"api/v1/stores/{storeId}/payout-processors/OnChainAutomatedPayoutSenderFactory/{paymentMethod}", request, HttpMethod.Put, token);
|
|
||||||
}
|
|
||||||
|
|
||||||
public virtual async Task<IEnumerable<OnChainAutomatedPayoutSettings>> GetStoreOnChainAutomatedPayoutProcessors(string storeId, string? paymentMethod = null, CancellationToken token = default)
|
|
||||||
{
|
|
||||||
return await SendHttpRequest<IEnumerable<OnChainAutomatedPayoutSettings>>($"api/v1/stores/{storeId}/payout-processors/OnChainAutomatedPayoutSenderFactory{(paymentMethod is null ? string.Empty : $"/{paymentMethod}")}", null, HttpMethod.Get, token);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -4,34 +4,61 @@ using System.Threading;
|
|||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using BTCPayServer.Client.Models;
|
using BTCPayServer.Client.Models;
|
||||||
|
|
||||||
namespace BTCPayServer.Client;
|
namespace BTCPayServer.Client
|
||||||
|
|
||||||
public partial class BTCPayServerClient
|
|
||||||
{
|
{
|
||||||
public virtual async Task<StoreRateConfiguration> GetStoreRateConfiguration(string storeId, CancellationToken token = default)
|
public partial class BTCPayServerClient
|
||||||
{
|
{
|
||||||
return await SendHttpRequest<StoreRateConfiguration>($"api/v1/stores/{storeId}/rates/configuration", null, HttpMethod.Get, token);
|
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)
|
public virtual async Task<List<RateSource>> GetRateSources(
|
||||||
{
|
CancellationToken token = default)
|
||||||
return await SendHttpRequest<List<RateSource>>("misc/rate-sources", null, HttpMethod.Get, token);
|
{
|
||||||
}
|
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)
|
public virtual async Task<StoreRateConfiguration> UpdateStoreRateConfiguration(string storeId,
|
||||||
{
|
StoreRateConfiguration request,
|
||||||
return await SendHttpRequest<StoreRateConfiguration>($"api/v1/stores/{storeId}/rates/configuration", request, HttpMethod.Put, token);
|
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<StoreRateResult>> PreviewUpdateStoreRateConfiguration(string storeId, StoreRateConfiguration request, string[] currencyPair = null, CancellationToken token = default)
|
public virtual async Task<List<StoreRateResult>> PreviewUpdateStoreRateConfiguration(string storeId,
|
||||||
{
|
StoreRateConfiguration request,
|
||||||
var queryPayload = currencyPair == null ? null : new Dictionary<string, object> { { "currencyPair", currencyPair } };
|
string[] currencyPair,
|
||||||
return await SendHttpRequest<StoreRateConfiguration, List<StoreRateResult>>($"api/v1/stores/{storeId}/rates/configuration/preview", queryPayload, request, HttpMethod.Post, token);
|
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<StoreRateResult>>(response);
|
||||||
|
}
|
||||||
|
|
||||||
public virtual async Task<List<StoreRateResult>> GetStoreRates(string storeId, string[] currencyPair = null, CancellationToken token = default)
|
public virtual async Task<List<StoreRateResult>> GetStoreRates(string storeId, string[] currencyPair,
|
||||||
{
|
CancellationToken token = default)
|
||||||
var queryPayload = currencyPair == null ? null : new Dictionary<string, object> { { "currencyPair", currencyPair } };
|
{
|
||||||
return await SendHttpRequest<List<StoreRateResult>>($"api/v1/stores/{storeId}/rates", queryPayload, HttpMethod.Get, token);
|
using var response = await _httpClient.SendAsync(
|
||||||
|
CreateHttpRequest($"api/v1/stores/{storeId}/rates",
|
||||||
|
queryPayload: new Dictionary<string, object>() { { "currencyPair", currencyPair } },
|
||||||
|
method: HttpMethod.Get),
|
||||||
|
token);
|
||||||
|
return await HandleResponse<List<StoreRateResult>>(response);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -5,34 +5,33 @@ using System.Threading;
|
|||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using BTCPayServer.Client.Models;
|
using BTCPayServer.Client.Models;
|
||||||
|
|
||||||
namespace BTCPayServer.Client;
|
namespace BTCPayServer.Client
|
||||||
|
|
||||||
public partial class BTCPayServerClient
|
|
||||||
{
|
{
|
||||||
public virtual async Task<List<RoleData>> GetStoreRoles(string storeId, CancellationToken token = default)
|
public partial class BTCPayServerClient
|
||||||
{
|
{
|
||||||
return await SendHttpRequest<List<RoleData>>($"api/v1/stores/{storeId}/roles", null, HttpMethod.Get,token);
|
public virtual async Task<IEnumerable<StoreUserData>> GetStoreUsers(string storeId,
|
||||||
}
|
CancellationToken token = default)
|
||||||
|
{
|
||||||
public virtual async Task<IEnumerable<StoreUserData>> GetStoreUsers(string storeId, CancellationToken token = default)
|
using var response = await _httpClient.SendAsync(CreateHttpRequest($"api/v1/stores/{storeId}/users"), token);
|
||||||
{
|
return await HandleResponse<IEnumerable<StoreUserData>>(response);
|
||||||
return await SendHttpRequest<IEnumerable<StoreUserData>>($"api/v1/stores/{storeId}/users", null, HttpMethod.Get, token);
|
}
|
||||||
}
|
|
||||||
|
|
||||||
public virtual async Task RemoveStoreUser(string storeId, string userId, CancellationToken token = default)
|
public virtual async Task RemoveStoreUser(string storeId, string userId, CancellationToken token = default)
|
||||||
{
|
{
|
||||||
await SendHttpRequest($"api/v1/stores/{storeId}/users/{userId}", null, HttpMethod.Delete, token);
|
using var response = await _httpClient.SendAsync(
|
||||||
}
|
CreateHttpRequest($"api/v1/stores/{storeId}/users/{userId}", method: HttpMethod.Delete), token);
|
||||||
|
await HandleResponse(response);
|
||||||
|
}
|
||||||
|
|
||||||
public virtual async Task AddStoreUser(string storeId, StoreUserData request, CancellationToken token = default)
|
public virtual async Task AddStoreUser(string storeId, StoreUserData request,
|
||||||
{
|
CancellationToken token = default)
|
||||||
if (request == null) throw new ArgumentNullException(nameof(request));
|
{
|
||||||
await SendHttpRequest<StoreUserData>($"api/v1/stores/{storeId}/users", request, HttpMethod.Post, token);
|
if (request == null)
|
||||||
}
|
throw new ArgumentNullException(nameof(request));
|
||||||
|
using var response = await _httpClient.SendAsync(
|
||||||
public virtual async Task UpdateStoreUser(string storeId, string userId, StoreUserData request, CancellationToken token = default)
|
CreateHttpRequest($"api/v1/stores/{storeId}/users", bodyPayload: request, method: HttpMethod.Post),
|
||||||
{
|
token);
|
||||||
if (request == null) throw new ArgumentNullException(nameof(request));
|
await HandleResponse(response);
|
||||||
await SendHttpRequest<StoreUserData>($"api/v1/stores/{storeId}/users/{userId}", request, HttpMethod.Put, token);
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -5,45 +5,47 @@ using System.Threading;
|
|||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using BTCPayServer.Client.Models;
|
using BTCPayServer.Client.Models;
|
||||||
|
|
||||||
namespace BTCPayServer.Client;
|
namespace BTCPayServer.Client
|
||||||
|
|
||||||
public partial class BTCPayServerClient
|
|
||||||
{
|
{
|
||||||
public virtual async Task<IEnumerable<StoreData>> GetStores(CancellationToken token = default)
|
public partial class BTCPayServerClient
|
||||||
{
|
{
|
||||||
return await SendHttpRequest<IEnumerable<StoreData>>("api/v1/stores", null, HttpMethod.Get, token);
|
public virtual async Task<IEnumerable<StoreData>> GetStores(CancellationToken token = default)
|
||||||
}
|
{
|
||||||
|
var response = await _httpClient.SendAsync(CreateHttpRequest("api/v1/stores"), token);
|
||||||
|
return await HandleResponse<IEnumerable<StoreData>>(response);
|
||||||
|
}
|
||||||
|
|
||||||
public virtual async Task<StoreData> GetStore(string storeId, CancellationToken token = default)
|
public virtual async Task<StoreData> GetStore(string storeId, CancellationToken token = default)
|
||||||
{
|
{
|
||||||
return await SendHttpRequest<StoreData>($"api/v1/stores/{storeId}", null, HttpMethod.Get, token);
|
var response = await _httpClient.SendAsync(
|
||||||
}
|
CreateHttpRequest($"api/v1/stores/{storeId}"), token);
|
||||||
|
return await HandleResponse<StoreData>(response);
|
||||||
|
}
|
||||||
|
|
||||||
public virtual async Task RemoveStore(string storeId, CancellationToken token = default)
|
public virtual async Task RemoveStore(string storeId, CancellationToken token = default)
|
||||||
{
|
{
|
||||||
await SendHttpRequest($"api/v1/stores/{storeId}", null, HttpMethod.Delete, token);
|
var response = await _httpClient.SendAsync(
|
||||||
}
|
CreateHttpRequest($"api/v1/stores/{storeId}", method: HttpMethod.Delete), token);
|
||||||
|
await HandleResponse(response);
|
||||||
|
}
|
||||||
|
|
||||||
public virtual async Task<StoreData> CreateStore(CreateStoreRequest request, CancellationToken token = default)
|
public virtual async Task<StoreData> CreateStore(CreateStoreRequest request, CancellationToken token = default)
|
||||||
{
|
{
|
||||||
if (request == null) throw new ArgumentNullException(nameof(request));
|
if (request == null)
|
||||||
return await SendHttpRequest<StoreData>("api/v1/stores", request, HttpMethod.Post, token);
|
throw new ArgumentNullException(nameof(request));
|
||||||
}
|
var response = await _httpClient.SendAsync(CreateHttpRequest("api/v1/stores", bodyPayload: request, method: HttpMethod.Post), token);
|
||||||
|
return await HandleResponse<StoreData>(response);
|
||||||
|
}
|
||||||
|
|
||||||
public virtual async Task<StoreData> UpdateStore(string storeId, UpdateStoreRequest request, CancellationToken token = default)
|
public virtual async Task<StoreData> UpdateStore(string storeId, UpdateStoreRequest request, CancellationToken token = default)
|
||||||
{
|
{
|
||||||
if (request == null) throw new ArgumentNullException(nameof(request));
|
if (request == null)
|
||||||
if (storeId == null) throw new ArgumentNullException(nameof(storeId));
|
throw new ArgumentNullException(nameof(request));
|
||||||
return await SendHttpRequest<StoreData>($"api/v1/stores/{storeId}", request, HttpMethod.Put, token);
|
if (storeId == null)
|
||||||
}
|
throw new ArgumentNullException(nameof(storeId));
|
||||||
|
var response = await _httpClient.SendAsync(CreateHttpRequest($"api/v1/stores/{storeId}", bodyPayload: request, method: HttpMethod.Put), token);
|
||||||
|
return await HandleResponse<StoreData>(response);
|
||||||
|
}
|
||||||
|
|
||||||
public virtual async Task<StoreData> UploadStoreLogo(string storeId, string filePath, string mimeType, CancellationToken token = default)
|
|
||||||
{
|
|
||||||
return await UploadFileRequest<StoreData>($"api/v1/stores/{storeId}/logo", filePath, mimeType, "file", HttpMethod.Post, token);
|
|
||||||
}
|
|
||||||
|
|
||||||
public virtual async Task DeleteStoreLogo(string storeId, CancellationToken token = default)
|
|
||||||
{
|
|
||||||
await SendHttpRequest($"api/v1/stores/{storeId}/logo", null, HttpMethod.Delete, token);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -4,68 +4,52 @@ using System.Threading;
|
|||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using BTCPayServer.Client.Models;
|
using BTCPayServer.Client.Models;
|
||||||
|
|
||||||
namespace BTCPayServer.Client;
|
namespace BTCPayServer.Client
|
||||||
|
|
||||||
public partial class BTCPayServerClient
|
|
||||||
{
|
{
|
||||||
public virtual async Task<ApplicationUserData> GetCurrentUser(CancellationToken token = default)
|
public partial class BTCPayServerClient
|
||||||
{
|
{
|
||||||
return await SendHttpRequest<ApplicationUserData>("api/v1/users/me", null, HttpMethod.Get, token);
|
public virtual async Task<ApplicationUserData> GetCurrentUser(CancellationToken token = default)
|
||||||
}
|
{
|
||||||
|
var response = await _httpClient.SendAsync(CreateHttpRequest("api/v1/users/me"), token);
|
||||||
|
return await HandleResponse<ApplicationUserData>(response);
|
||||||
|
}
|
||||||
|
|
||||||
public virtual async Task<ApplicationUserData> UpdateCurrentUser(UpdateApplicationUserRequest request, CancellationToken token = default)
|
public virtual async Task<ApplicationUserData> CreateUser(CreateApplicationUserRequest request,
|
||||||
{
|
CancellationToken token = default)
|
||||||
return await SendHttpRequest<ApplicationUserData>("api/v1/users/me", request, HttpMethod.Put, token);
|
{
|
||||||
}
|
var response = await _httpClient.SendAsync(CreateHttpRequest("api/v1/users", null, request, HttpMethod.Post), token);
|
||||||
|
return await HandleResponse<ApplicationUserData>(response);
|
||||||
|
}
|
||||||
|
|
||||||
public virtual async Task<ApplicationUserData> UploadCurrentUserProfilePicture(string filePath, string mimeType, CancellationToken token = default)
|
public virtual async Task DeleteUser(string userId, CancellationToken token = default)
|
||||||
{
|
{
|
||||||
return await UploadFileRequest<ApplicationUserData>("api/v1/users/me/picture", filePath, mimeType, "file", HttpMethod.Post, token);
|
var response = await _httpClient.SendAsync(CreateHttpRequest($"api/v1/users/{userId}", null, HttpMethod.Delete), token);
|
||||||
}
|
await HandleResponse(response);
|
||||||
|
}
|
||||||
|
|
||||||
public virtual async Task DeleteCurrentUserProfilePicture(CancellationToken token = default)
|
public virtual async Task<ApplicationUserData> GetUserByIdOrEmail(string idOrEmail, CancellationToken token = default)
|
||||||
{
|
{
|
||||||
await SendHttpRequest("api/v1/users/me/picture", null, HttpMethod.Delete, token);
|
var response = await _httpClient.SendAsync(CreateHttpRequest($"api/v1/users/{idOrEmail}", null, HttpMethod.Get), token);
|
||||||
}
|
return await HandleResponse<ApplicationUserData>(response);
|
||||||
|
}
|
||||||
public virtual async Task<ApplicationUserData> CreateUser(CreateApplicationUserRequest request, CancellationToken token = default)
|
|
||||||
{
|
|
||||||
return await SendHttpRequest<ApplicationUserData>("api/v1/users", request, HttpMethod.Post, token);
|
|
||||||
}
|
|
||||||
|
|
||||||
public virtual async Task DeleteUser(string userId, CancellationToken token = default)
|
public virtual async Task<bool> LockUser(string idOrEmail, bool locked, CancellationToken token = default)
|
||||||
{
|
{
|
||||||
await SendHttpRequest($"api/v1/users/{userId}", null, HttpMethod.Delete, token);
|
var response = await _httpClient.SendAsync(CreateHttpRequest($"api/v1/users/{idOrEmail}/lock", null,
|
||||||
}
|
new LockUserRequest { Locked = locked }, HttpMethod.Post), token);
|
||||||
|
await HandleResponse(response);
|
||||||
|
return response.IsSuccessStatusCode;
|
||||||
|
}
|
||||||
|
|
||||||
public virtual async Task<ApplicationUserData> GetUserByIdOrEmail(string idOrEmail, CancellationToken token = default)
|
public virtual async Task<ApplicationUserData[]> GetUsers(CancellationToken token = default)
|
||||||
{
|
{
|
||||||
return await SendHttpRequest<ApplicationUserData>($"api/v1/users/{idOrEmail}", null, HttpMethod.Get, token);
|
var response = await _httpClient.SendAsync(CreateHttpRequest($"api/v1/users/", null, HttpMethod.Get), token);
|
||||||
}
|
return await HandleResponse<ApplicationUserData[]>(response);
|
||||||
|
}
|
||||||
|
|
||||||
public virtual async Task<bool> LockUser(string idOrEmail, bool locked, CancellationToken token = default)
|
public virtual async Task DeleteCurrentUser(CancellationToken token = default)
|
||||||
{
|
{
|
||||||
var response = await _httpClient.SendAsync(CreateHttpRequest($"api/v1/users/{idOrEmail}/lock", null,
|
await DeleteUser("me", token);
|
||||||
new LockUserRequest { Locked = locked }, HttpMethod.Post), token);
|
}
|
||||||
await HandleResponse(response);
|
|
||||||
return response.IsSuccessStatusCode;
|
|
||||||
}
|
|
||||||
|
|
||||||
public virtual async Task<bool> ApproveUser(string idOrEmail, bool approved, CancellationToken token = default)
|
|
||||||
{
|
|
||||||
var response = await _httpClient.SendAsync(CreateHttpRequest($"api/v1/users/{idOrEmail}/approve", null,
|
|
||||||
new ApproveUserRequest { Approved = approved }, HttpMethod.Post), token);
|
|
||||||
await HandleResponse(response);
|
|
||||||
return response.IsSuccessStatusCode;
|
|
||||||
}
|
|
||||||
|
|
||||||
public virtual async Task<ApplicationUserData[]> GetUsers(CancellationToken token = default)
|
|
||||||
{
|
|
||||||
return await SendHttpRequest<ApplicationUserData[]>("api/v1/users/", null, HttpMethod.Get, token);
|
|
||||||
}
|
|
||||||
|
|
||||||
public virtual async Task DeleteCurrentUser(CancellationToken token = default)
|
|
||||||
{
|
|
||||||
await DeleteUser("me", token);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -3,56 +3,61 @@ using System.Threading;
|
|||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using BTCPayServer.Client.Models;
|
using BTCPayServer.Client.Models;
|
||||||
|
|
||||||
namespace BTCPayServer.Client;
|
namespace BTCPayServer.Client
|
||||||
|
|
||||||
public partial class BTCPayServerClient
|
|
||||||
{
|
{
|
||||||
public virtual async Task<StoreWebhookData> CreateWebhook(string storeId, CreateStoreWebhookRequest create, CancellationToken token = default)
|
public partial class BTCPayServerClient
|
||||||
{
|
{
|
||||||
return await SendHttpRequest<StoreWebhookData>($"api/v1/stores/{storeId}/webhooks", create, HttpMethod.Post, token);
|
public virtual async Task<StoreWebhookData> CreateWebhook(string storeId, Client.Models.CreateStoreWebhookRequest create, CancellationToken token = default)
|
||||||
}
|
{
|
||||||
|
var response = await _httpClient.SendAsync(CreateHttpRequest($"api/v1/stores/{storeId}/webhooks", bodyPayload: create, method: HttpMethod.Post), token);
|
||||||
|
return await HandleResponse<StoreWebhookData>(response);
|
||||||
|
}
|
||||||
|
public virtual async Task<StoreWebhookData> GetWebhook(string storeId, string webhookId, CancellationToken token = default)
|
||||||
|
{
|
||||||
|
var response = await _httpClient.SendAsync(CreateHttpRequest($"api/v1/stores/{storeId}/webhooks/{webhookId}"), token);
|
||||||
|
if (response.StatusCode == System.Net.HttpStatusCode.NotFound)
|
||||||
|
return null;
|
||||||
|
return await HandleResponse<StoreWebhookData>(response);
|
||||||
|
}
|
||||||
|
public virtual async Task<StoreWebhookData> UpdateWebhook(string storeId, string webhookId, Models.UpdateStoreWebhookRequest update, CancellationToken token = default)
|
||||||
|
{
|
||||||
|
var response = await _httpClient.SendAsync(CreateHttpRequest($"api/v1/stores/{storeId}/webhooks/{webhookId}", bodyPayload: update, method: HttpMethod.Put), token);
|
||||||
|
return await HandleResponse<StoreWebhookData>(response);
|
||||||
|
}
|
||||||
|
public virtual async Task<bool> DeleteWebhook(string storeId, string webhookId, CancellationToken token = default)
|
||||||
|
{
|
||||||
|
var response = await _httpClient.SendAsync(CreateHttpRequest($"api/v1/stores/{storeId}/webhooks/{webhookId}", method: HttpMethod.Delete), token);
|
||||||
|
return response.IsSuccessStatusCode;
|
||||||
|
}
|
||||||
|
public virtual async Task<StoreWebhookData[]> GetWebhooks(string storeId, CancellationToken token = default)
|
||||||
|
{
|
||||||
|
var response = await _httpClient.SendAsync(CreateHttpRequest($"api/v1/stores/{storeId}/webhooks"), token);
|
||||||
|
return await HandleResponse<StoreWebhookData[]>(response);
|
||||||
|
}
|
||||||
|
public virtual async Task<WebhookDeliveryData[]> GetWebhookDeliveries(string storeId, string webhookId, CancellationToken token = default)
|
||||||
|
{
|
||||||
|
var response = await _httpClient.SendAsync(CreateHttpRequest($"api/v1/stores/{storeId}/webhooks/{webhookId}/deliveries"), token);
|
||||||
|
return await HandleResponse<WebhookDeliveryData[]>(response);
|
||||||
|
}
|
||||||
|
public virtual async Task<WebhookDeliveryData> GetWebhookDelivery(string storeId, string webhookId, string deliveryId, CancellationToken token = default)
|
||||||
|
{
|
||||||
|
var response = await _httpClient.SendAsync(CreateHttpRequest($"api/v1/stores/{storeId}/webhooks/{webhookId}/deliveries/{deliveryId}"), token);
|
||||||
|
if (response.StatusCode == System.Net.HttpStatusCode.NotFound)
|
||||||
|
return null;
|
||||||
|
return await HandleResponse<WebhookDeliveryData>(response);
|
||||||
|
}
|
||||||
|
public virtual async Task<string> RedeliverWebhook(string storeId, string webhookId, string deliveryId, CancellationToken token = default)
|
||||||
|
{
|
||||||
|
var response = await _httpClient.SendAsync(CreateHttpRequest($"api/v1/stores/{storeId}/webhooks/{webhookId}/deliveries/{deliveryId}/redeliver", null, HttpMethod.Post), token);
|
||||||
|
return await HandleResponse<string>(response);
|
||||||
|
}
|
||||||
|
|
||||||
public virtual async Task<StoreWebhookData> GetWebhook(string storeId, string webhookId, CancellationToken token = default)
|
public virtual async Task<WebhookEvent> GetWebhookDeliveryRequest(string storeId, string webhookId, string deliveryId, CancellationToken token = default)
|
||||||
{
|
{
|
||||||
var response = await _httpClient.SendAsync(CreateHttpRequest($"api/v1/stores/{storeId}/webhooks/{webhookId}"), token);
|
var response = await _httpClient.SendAsync(CreateHttpRequest($"api/v1/stores/{storeId}/webhooks/{webhookId}/deliveries/{deliveryId}/request"), token);
|
||||||
return response.StatusCode == System.Net.HttpStatusCode.NotFound ? null : await HandleResponse<StoreWebhookData>(response);
|
if (response.StatusCode == System.Net.HttpStatusCode.NotFound)
|
||||||
}
|
return null;
|
||||||
|
return await HandleResponse<WebhookEvent>(response);
|
||||||
public virtual async Task<StoreWebhookData> UpdateWebhook(string storeId, string webhookId, UpdateStoreWebhookRequest update, CancellationToken token = default)
|
}
|
||||||
{
|
|
||||||
return await SendHttpRequest<StoreWebhookData>($"api/v1/stores/{storeId}/webhooks/{webhookId}", update, HttpMethod.Put, token);
|
|
||||||
}
|
|
||||||
|
|
||||||
public virtual async Task<bool> DeleteWebhook(string storeId, string webhookId, CancellationToken token = default)
|
|
||||||
{
|
|
||||||
var response = await _httpClient.SendAsync(CreateHttpRequest($"api/v1/stores/{storeId}/webhooks/{webhookId}", method: HttpMethod.Delete), token);
|
|
||||||
return response.IsSuccessStatusCode;
|
|
||||||
}
|
|
||||||
|
|
||||||
public virtual async Task<StoreWebhookData[]> GetWebhooks(string storeId, CancellationToken token = default)
|
|
||||||
{
|
|
||||||
return await SendHttpRequest<StoreWebhookData[]>($"api/v1/stores/{storeId}/webhooks", null, HttpMethod.Get, token);
|
|
||||||
}
|
|
||||||
|
|
||||||
public virtual async Task<WebhookDeliveryData[]> GetWebhookDeliveries(string storeId, string webhookId, CancellationToken token = default)
|
|
||||||
{
|
|
||||||
return await SendHttpRequest<WebhookDeliveryData[]>($"api/v1/stores/{storeId}/webhooks/{webhookId}/deliveries", null, HttpMethod.Get, token);
|
|
||||||
}
|
|
||||||
|
|
||||||
public virtual async Task<WebhookDeliveryData> GetWebhookDelivery(string storeId, string webhookId, string deliveryId, CancellationToken token = default)
|
|
||||||
{
|
|
||||||
var response = await _httpClient.SendAsync(CreateHttpRequest($"api/v1/stores/{storeId}/webhooks/{webhookId}/deliveries/{deliveryId}"), token);
|
|
||||||
return response.StatusCode == System.Net.HttpStatusCode.NotFound ? null : await HandleResponse<WebhookDeliveryData>(response);
|
|
||||||
}
|
|
||||||
|
|
||||||
public virtual async Task<string> RedeliverWebhook(string storeId, string webhookId, string deliveryId, CancellationToken token = default)
|
|
||||||
{
|
|
||||||
return await SendHttpRequest<string>($"api/v1/stores/{storeId}/webhooks/{webhookId}/deliveries/{deliveryId}/redeliver", null, HttpMethod.Post, token);
|
|
||||||
}
|
|
||||||
|
|
||||||
public virtual async Task<WebhookEvent> GetWebhookDeliveryRequest(string storeId, string webhookId, string deliveryId, CancellationToken token = default)
|
|
||||||
{
|
|
||||||
var response = await _httpClient.SendAsync(CreateHttpRequest($"api/v1/stores/{storeId}/webhooks/{webhookId}/deliveries/{deliveryId}/request"), token);
|
|
||||||
return response.StatusCode == System.Net.HttpStatusCode.NotFound ? null : await HandleResponse<WebhookEvent>(response);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1,7 +1,6 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections;
|
using System.Collections;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Net.Http;
|
using System.Net.Http;
|
||||||
using System.Net.Http.Headers;
|
using System.Net.Http.Headers;
|
||||||
@@ -10,192 +9,153 @@ using System.Threading;
|
|||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
|
|
||||||
namespace BTCPayServer.Client;
|
namespace BTCPayServer.Client
|
||||||
|
|
||||||
public partial class BTCPayServerClient
|
|
||||||
{
|
{
|
||||||
private readonly string _apiKey;
|
public partial class BTCPayServerClient
|
||||||
private readonly Uri _btcpayHost;
|
|
||||||
private readonly string _username;
|
|
||||||
private readonly string _password;
|
|
||||||
protected readonly HttpClient _httpClient;
|
|
||||||
public Uri Host => _btcpayHost;
|
|
||||||
|
|
||||||
public string APIKey => _apiKey;
|
|
||||||
|
|
||||||
public BTCPayServerClient(Uri btcpayHost, HttpClient httpClient = null)
|
|
||||||
{
|
{
|
||||||
if (btcpayHost == null) throw new ArgumentNullException(nameof(btcpayHost));
|
private readonly string _apiKey;
|
||||||
_btcpayHost = btcpayHost;
|
private readonly Uri _btcpayHost;
|
||||||
_httpClient = httpClient ?? new HttpClient();
|
private readonly string _username;
|
||||||
}
|
private readonly string _password;
|
||||||
|
private readonly HttpClient _httpClient;
|
||||||
|
public Uri Host => _btcpayHost;
|
||||||
|
|
||||||
public BTCPayServerClient(Uri btcpayHost, string APIKey, HttpClient httpClient = null)
|
public string APIKey => _apiKey;
|
||||||
{
|
|
||||||
_apiKey = APIKey;
|
|
||||||
_btcpayHost = btcpayHost;
|
|
||||||
_httpClient = httpClient ?? new HttpClient();
|
|
||||||
}
|
|
||||||
|
|
||||||
public BTCPayServerClient(Uri btcpayHost, string username, string password, HttpClient httpClient = null)
|
public BTCPayServerClient(Uri btcpayHost, HttpClient httpClient = null)
|
||||||
{
|
|
||||||
_apiKey = APIKey;
|
|
||||||
_btcpayHost = btcpayHost;
|
|
||||||
_username = username;
|
|
||||||
_password = password;
|
|
||||||
_httpClient = httpClient ?? new HttpClient();
|
|
||||||
}
|
|
||||||
|
|
||||||
protected async Task HandleResponse(HttpResponseMessage message)
|
|
||||||
{
|
|
||||||
if (!message.IsSuccessStatusCode && message.Content?.Headers?.ContentType?.MediaType?.StartsWith("application/json", StringComparison.OrdinalIgnoreCase) is true)
|
|
||||||
{
|
{
|
||||||
if (message.StatusCode == System.Net.HttpStatusCode.UnprocessableEntity)
|
if (btcpayHost == null)
|
||||||
|
throw new ArgumentNullException(nameof(btcpayHost));
|
||||||
|
_btcpayHost = btcpayHost;
|
||||||
|
_httpClient = httpClient ?? new HttpClient();
|
||||||
|
}
|
||||||
|
public BTCPayServerClient(Uri btcpayHost, string APIKey, HttpClient httpClient = null)
|
||||||
|
{
|
||||||
|
_apiKey = APIKey;
|
||||||
|
_btcpayHost = btcpayHost;
|
||||||
|
_httpClient = httpClient ?? new HttpClient();
|
||||||
|
}
|
||||||
|
|
||||||
|
public BTCPayServerClient(Uri btcpayHost, string username, string password, HttpClient httpClient = null)
|
||||||
|
{
|
||||||
|
_apiKey = APIKey;
|
||||||
|
_btcpayHost = btcpayHost;
|
||||||
|
_username = username;
|
||||||
|
_password = password;
|
||||||
|
_httpClient = httpClient ?? new HttpClient();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected async Task HandleResponse(HttpResponseMessage message)
|
||||||
|
{
|
||||||
|
if (!message.IsSuccessStatusCode && message.Content?.Headers?.ContentType?.MediaType?.StartsWith("application/json", StringComparison.OrdinalIgnoreCase) is true)
|
||||||
{
|
{
|
||||||
var aa = await message.Content.ReadAsStringAsync();
|
if (message.StatusCode == System.Net.HttpStatusCode.UnprocessableEntity)
|
||||||
var err = JsonConvert.DeserializeObject<Models.GreenfieldValidationError[]>(aa);
|
{
|
||||||
throw new GreenfieldValidationException(err);
|
var err = JsonConvert.DeserializeObject<Models.GreenfieldValidationError[]>(await message.Content.ReadAsStringAsync());
|
||||||
|
throw new GreenfieldValidationException(err);
|
||||||
|
}
|
||||||
|
if (message.StatusCode == System.Net.HttpStatusCode.Forbidden)
|
||||||
|
{
|
||||||
|
var err = JsonConvert.DeserializeObject<Models.GreenfieldPermissionAPIError>(await message.Content.ReadAsStringAsync());
|
||||||
|
throw new GreenfieldAPIException((int)message.StatusCode, err);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
var err = JsonConvert.DeserializeObject<Models.GreenfieldAPIError>(await message.Content.ReadAsStringAsync());
|
||||||
|
if (err.Code != null)
|
||||||
|
throw new GreenfieldAPIException((int)message.StatusCode, err);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (message.StatusCode == System.Net.HttpStatusCode.Forbidden)
|
message.EnsureSuccessStatusCode();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected async Task<T> HandleResponse<T>(HttpResponseMessage message)
|
||||||
|
{
|
||||||
|
await HandleResponse(message);
|
||||||
|
var str = await message.Content.ReadAsStringAsync();
|
||||||
|
return JsonConvert.DeserializeObject<T>(str);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<T> SendHttpRequest<T>(string path,
|
||||||
|
Dictionary<string, object> queryPayload = null,
|
||||||
|
HttpMethod method = null, CancellationToken cancellationToken = default)
|
||||||
|
{
|
||||||
|
using var resp = await _httpClient.SendAsync(CreateHttpRequest(path, queryPayload, method), cancellationToken);
|
||||||
|
return await HandleResponse<T>(resp);
|
||||||
|
}
|
||||||
|
public async Task<T> SendHttpRequest<T>(string path,
|
||||||
|
object bodyPayload = null,
|
||||||
|
HttpMethod method = null, CancellationToken cancellationToken = default)
|
||||||
|
{
|
||||||
|
using var resp = await _httpClient.SendAsync(CreateHttpRequest(path: path, bodyPayload: bodyPayload, method: method), cancellationToken);
|
||||||
|
return await HandleResponse<T>(resp);
|
||||||
|
}
|
||||||
|
protected virtual HttpRequestMessage CreateHttpRequest(string path,
|
||||||
|
Dictionary<string, object> queryPayload = null,
|
||||||
|
HttpMethod method = null)
|
||||||
|
{
|
||||||
|
UriBuilder uriBuilder = new UriBuilder(_btcpayHost) { Path = path };
|
||||||
|
if (queryPayload != null && queryPayload.Any())
|
||||||
{
|
{
|
||||||
var err = JsonConvert.DeserializeObject<Models.GreenfieldPermissionAPIError>(await message.Content.ReadAsStringAsync());
|
AppendPayloadToQuery(uriBuilder, queryPayload);
|
||||||
throw new GreenfieldAPIException((int)message.StatusCode, err);
|
}
|
||||||
|
|
||||||
|
var httpRequest = new HttpRequestMessage(method ?? HttpMethod.Get, uriBuilder.Uri);
|
||||||
|
if (_apiKey != null)
|
||||||
|
httpRequest.Headers.Authorization = new AuthenticationHeaderValue("token", _apiKey);
|
||||||
|
else if (!string.IsNullOrEmpty(_username))
|
||||||
|
{
|
||||||
|
httpRequest.Headers.Authorization = new AuthenticationHeaderValue("Basic", System.Convert.ToBase64String(Encoding.ASCII.GetBytes(_username + ":" + _password)));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
return httpRequest;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected virtual HttpRequestMessage CreateHttpRequest<T>(string path,
|
||||||
|
Dictionary<string, object> queryPayload = null,
|
||||||
|
T bodyPayload = default, HttpMethod method = null)
|
||||||
|
{
|
||||||
|
var request = CreateHttpRequest(path, queryPayload, method);
|
||||||
|
if (typeof(T).IsPrimitive || !EqualityComparer<T>.Default.Equals(bodyPayload, default(T)))
|
||||||
|
{
|
||||||
|
request.Content = new StringContent(JsonConvert.SerializeObject(bodyPayload), Encoding.UTF8, "application/json");
|
||||||
|
}
|
||||||
|
|
||||||
|
return request;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void AppendPayloadToQuery(UriBuilder uri, KeyValuePair<string, object> keyValuePair)
|
||||||
|
{
|
||||||
|
if (uri.Query.Length > 1)
|
||||||
|
uri.Query += "&";
|
||||||
|
|
||||||
|
UriBuilder uriBuilder = uri;
|
||||||
|
if (!(keyValuePair.Value is string) &&
|
||||||
|
keyValuePair.Value.GetType().GetInterfaces().Contains((typeof(IEnumerable))))
|
||||||
|
{
|
||||||
|
foreach (var item in (IEnumerable)keyValuePair.Value)
|
||||||
|
{
|
||||||
|
uriBuilder.Query = uriBuilder.Query + Uri.EscapeDataString(keyValuePair.Key) + "=" +
|
||||||
|
Uri.EscapeDataString(item.ToString()) + "&";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
|
||||||
var err = JsonConvert.DeserializeObject<Models.GreenfieldAPIError>(await message.Content.ReadAsStringAsync());
|
|
||||||
if (err.Code != null)
|
|
||||||
throw new GreenfieldAPIException((int)message.StatusCode, err);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
message.EnsureSuccessStatusCode();
|
|
||||||
}
|
|
||||||
|
|
||||||
protected virtual async Task<T> HandleResponse<T>(HttpResponseMessage message)
|
|
||||||
{
|
|
||||||
await HandleResponse(message);
|
|
||||||
var str = await message.Content.ReadAsStringAsync();
|
|
||||||
return JsonConvert.DeserializeObject<T>(str);
|
|
||||||
}
|
|
||||||
|
|
||||||
public virtual async Task SendHttpRequest(string path,
|
|
||||||
Dictionary<string, object> queryPayload = null,
|
|
||||||
HttpMethod method = null, CancellationToken cancellationToken = default)
|
|
||||||
{
|
|
||||||
using var resp = await _httpClient.SendAsync(CreateHttpRequest(path, queryPayload, method), cancellationToken);
|
|
||||||
await HandleResponse(resp);
|
|
||||||
}
|
|
||||||
|
|
||||||
public virtual async Task<T> SendHttpRequest<T>(string path,
|
|
||||||
Dictionary<string, object> queryPayload = null,
|
|
||||||
HttpMethod method = null, CancellationToken cancellationToken = default)
|
|
||||||
{
|
|
||||||
using var resp = await _httpClient.SendAsync(CreateHttpRequest(path, queryPayload, method), cancellationToken);
|
|
||||||
return await HandleResponse<T>(resp);
|
|
||||||
}
|
|
||||||
|
|
||||||
public virtual async Task SendHttpRequest(string path,
|
|
||||||
object bodyPayload = null,
|
|
||||||
HttpMethod method = null, CancellationToken cancellationToken = default)
|
|
||||||
{
|
|
||||||
using var resp = await _httpClient.SendAsync(CreateHttpRequest(path: path, bodyPayload: bodyPayload, method: method), cancellationToken);
|
|
||||||
await HandleResponse(resp);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected virtual async Task<T> SendHttpRequest<T>(string path,
|
|
||||||
object bodyPayload = null,
|
|
||||||
HttpMethod method = null, CancellationToken cancellationToken = default)
|
|
||||||
{
|
|
||||||
using var resp = await _httpClient.SendAsync(CreateHttpRequest(path: path, bodyPayload: bodyPayload, method: method), cancellationToken);
|
|
||||||
return await HandleResponse<T>(resp);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected virtual async Task<TRes> SendHttpRequest<TReq, TRes>(string path,
|
|
||||||
Dictionary<string, object> queryPayload = null,
|
|
||||||
TReq bodyPayload = default, HttpMethod method = null, CancellationToken cancellationToken = default)
|
|
||||||
{
|
|
||||||
using var resp = await _httpClient.SendAsync(CreateHttpRequest(path: path, bodyPayload: bodyPayload, queryPayload: queryPayload, method: method), cancellationToken);
|
|
||||||
return await HandleResponse<TRes>(resp);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected virtual HttpRequestMessage CreateHttpRequest(string path,
|
|
||||||
Dictionary<string, object> queryPayload = null,
|
|
||||||
HttpMethod method = null)
|
|
||||||
{
|
|
||||||
var uriBuilder = new UriBuilder(_btcpayHost);
|
|
||||||
uriBuilder.Path += (uriBuilder.Path.EndsWith("/") || path.StartsWith("/") ? "" : "/") + path;
|
|
||||||
if (queryPayload != null && queryPayload.Any())
|
|
||||||
{
|
|
||||||
AppendPayloadToQuery(uriBuilder, queryPayload);
|
|
||||||
}
|
|
||||||
|
|
||||||
var httpRequest = new HttpRequestMessage(method ?? HttpMethod.Get, uriBuilder.Uri);
|
|
||||||
if (_apiKey != null)
|
|
||||||
httpRequest.Headers.Authorization = new AuthenticationHeaderValue("token", _apiKey);
|
|
||||||
else if (!string.IsNullOrEmpty(_username))
|
|
||||||
{
|
|
||||||
httpRequest.Headers.Authorization = new AuthenticationHeaderValue("Basic", Convert.ToBase64String(Encoding.ASCII.GetBytes(_username + ":" + _password)));
|
|
||||||
}
|
|
||||||
|
|
||||||
return httpRequest;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected virtual HttpRequestMessage CreateHttpRequest<T>(string path,
|
|
||||||
Dictionary<string, object> queryPayload = null,
|
|
||||||
T bodyPayload = default, HttpMethod method = null)
|
|
||||||
{
|
|
||||||
var request = CreateHttpRequest(path, queryPayload, method);
|
|
||||||
if (typeof(T).IsPrimitive || !EqualityComparer<T>.Default.Equals(bodyPayload, default(T)))
|
|
||||||
{
|
|
||||||
request.Content = new StringContent(JsonConvert.SerializeObject(bodyPayload), Encoding.UTF8, "application/json");
|
|
||||||
}
|
|
||||||
|
|
||||||
return request;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected virtual async Task<T> UploadFileRequest<T>(string apiPath, string filePath, string mimeType, string formFieldName, HttpMethod method = null, CancellationToken token = default)
|
|
||||||
{
|
|
||||||
using MultipartFormDataContent multipartContent = new();
|
|
||||||
using var fileContent = new StreamContent(File.OpenRead(filePath));
|
|
||||||
var fileName = Path.GetFileName(filePath);
|
|
||||||
fileContent.Headers.ContentType = MediaTypeHeaderValue.Parse(mimeType);
|
|
||||||
multipartContent.Add(fileContent, formFieldName, fileName);
|
|
||||||
var req = CreateHttpRequest(apiPath, null, method ?? HttpMethod.Post);
|
|
||||||
req.Content = multipartContent;
|
|
||||||
using var resp = await _httpClient.SendAsync(req, token);
|
|
||||||
return await HandleResponse<T>(resp);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void AppendPayloadToQuery(UriBuilder uri, KeyValuePair<string, object> keyValuePair)
|
|
||||||
{
|
|
||||||
if (uri.Query.Length > 1)
|
|
||||||
uri.Query += "&";
|
|
||||||
|
|
||||||
UriBuilder uriBuilder = uri;
|
|
||||||
if (!(keyValuePair.Value is string) &&
|
|
||||||
keyValuePair.Value.GetType().GetInterfaces().Contains((typeof(IEnumerable))))
|
|
||||||
{
|
|
||||||
foreach (var item in (IEnumerable)keyValuePair.Value)
|
|
||||||
{
|
{
|
||||||
uriBuilder.Query = uriBuilder.Query + Uri.EscapeDataString(keyValuePair.Key) + "=" +
|
uriBuilder.Query = uriBuilder.Query + Uri.EscapeDataString(keyValuePair.Key) + "=" +
|
||||||
Uri.EscapeDataString(item.ToString()) + "&";
|
Uri.EscapeDataString(keyValuePair.Value.ToString()) + "&";
|
||||||
}
|
}
|
||||||
|
uri.Query = uri.Query.Trim('&');
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
uriBuilder.Query = uriBuilder.Query + Uri.EscapeDataString(keyValuePair.Key) + "=" +
|
|
||||||
Uri.EscapeDataString(keyValuePair.Value.ToString()) + "&";
|
|
||||||
}
|
|
||||||
uri.Query = uri.Query.Trim('&');
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void AppendPayloadToQuery(UriBuilder uri, Dictionary<string, object> payload)
|
public static void AppendPayloadToQuery(UriBuilder uri, Dictionary<string, object> payload)
|
||||||
{
|
|
||||||
if (uri.Query.Length > 1)
|
|
||||||
uri.Query += "&";
|
|
||||||
foreach (KeyValuePair<string, object> keyValuePair in payload)
|
|
||||||
{
|
{
|
||||||
AppendPayloadToQuery(uri, keyValuePair);
|
if (uri.Query.Length > 1)
|
||||||
|
uri.Query += "&";
|
||||||
|
foreach (KeyValuePair<string, object> keyValuePair in payload)
|
||||||
|
{
|
||||||
|
AppendPayloadToQuery(uri, keyValuePair);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1,15 +1,17 @@
|
|||||||
using System;
|
using System;
|
||||||
|
|
||||||
namespace BTCPayServer.Client;
|
namespace BTCPayServer.Client
|
||||||
|
|
||||||
public class GreenfieldAPIException : Exception
|
|
||||||
{
|
{
|
||||||
public GreenfieldAPIException(int httpCode, Models.GreenfieldAPIError error) : base(error.Message)
|
public class GreenfieldAPIException : Exception
|
||||||
{
|
{
|
||||||
if (error == null) throw new ArgumentNullException(nameof(error));
|
public GreenfieldAPIException(int httpCode, Models.GreenfieldAPIError error) : base(error.Message)
|
||||||
HttpCode = httpCode;
|
{
|
||||||
APIError = error;
|
if (error == null)
|
||||||
|
throw new ArgumentNullException(nameof(error));
|
||||||
|
HttpCode = httpCode;
|
||||||
|
APIError = error;
|
||||||
|
}
|
||||||
|
public Models.GreenfieldAPIError APIError { get; }
|
||||||
|
public int HttpCode { get; set; }
|
||||||
}
|
}
|
||||||
public Models.GreenfieldAPIError APIError { get; }
|
|
||||||
public int HttpCode { get; set; }
|
|
||||||
}
|
}
|
||||||
|
@@ -2,25 +2,27 @@ using System;
|
|||||||
using System.Text;
|
using System.Text;
|
||||||
using BTCPayServer.Client.Models;
|
using BTCPayServer.Client.Models;
|
||||||
|
|
||||||
namespace BTCPayServer.Client;
|
namespace BTCPayServer.Client
|
||||||
|
|
||||||
public class GreenfieldValidationException : Exception
|
|
||||||
{
|
{
|
||||||
public GreenfieldValidationException(GreenfieldValidationError[] errors) : base(BuildMessage(errors))
|
public class GreenfieldValidationException : Exception
|
||||||
{
|
{
|
||||||
ValidationErrors = errors;
|
public GreenfieldValidationException(Models.GreenfieldValidationError[] errors) : base(BuildMessage(errors))
|
||||||
}
|
|
||||||
|
|
||||||
private static string BuildMessage(GreenfieldValidationError[] errors)
|
|
||||||
{
|
|
||||||
if (errors == null) throw new ArgumentNullException(nameof(errors));
|
|
||||||
var builder = new StringBuilder();
|
|
||||||
foreach (var error in errors)
|
|
||||||
{
|
{
|
||||||
builder.AppendLine($"{error.Path}: {error.Message}");
|
ValidationErrors = errors;
|
||||||
}
|
}
|
||||||
return builder.ToString();
|
|
||||||
}
|
|
||||||
|
|
||||||
public GreenfieldValidationError[] ValidationErrors { get; }
|
private static string BuildMessage(GreenfieldValidationError[] errors)
|
||||||
|
{
|
||||||
|
if (errors == null)
|
||||||
|
throw new ArgumentNullException(nameof(errors));
|
||||||
|
StringBuilder builder = new StringBuilder();
|
||||||
|
foreach (var error in errors)
|
||||||
|
{
|
||||||
|
builder.AppendLine($"{error.Path}: {error.Message}");
|
||||||
|
}
|
||||||
|
return builder.ToString();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Models.GreenfieldValidationError[] ValidationErrors { get; }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1,43 +0,0 @@
|
|||||||
using NBitcoin;
|
|
||||||
using NBitcoin.DataEncoders;
|
|
||||||
using NBitcoin.JsonConverters;
|
|
||||||
using Newtonsoft.Json;
|
|
||||||
using System;
|
|
||||||
using System.IO;
|
|
||||||
using System.Reflection;
|
|
||||||
|
|
||||||
namespace BTCPayServer.Client.JsonConverters
|
|
||||||
{
|
|
||||||
public class SaneOutpointJsonConverter : JsonConverter
|
|
||||||
{
|
|
||||||
public override bool CanConvert(Type objectType)
|
|
||||||
{
|
|
||||||
return typeof(OutPoint).GetTypeInfo().IsAssignableFrom(objectType.GetTypeInfo());
|
|
||||||
}
|
|
||||||
|
|
||||||
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
|
|
||||||
{
|
|
||||||
if (reader.TokenType == JsonToken.Null)
|
|
||||||
return null;
|
|
||||||
|
|
||||||
if (reader.TokenType != JsonToken.String)
|
|
||||||
throw new JsonObjectException($"Unexpected json token type, expected is {JsonToken.String} and actual is {reader.TokenType}", reader);
|
|
||||||
try
|
|
||||||
{
|
|
||||||
if (!OutPoint.TryParse((string)reader.Value, out var outpoint))
|
|
||||||
throw new JsonObjectException("Invalid bitcoin object of type OutPoint", reader);
|
|
||||||
return outpoint;
|
|
||||||
}
|
|
||||||
catch (EndOfStreamException)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
throw new JsonObjectException("Invalid bitcoin object of type OutPoint", reader);
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
|
|
||||||
{
|
|
||||||
if (value is { })
|
|
||||||
writer.WriteValue(value.ToString());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,5 +1,4 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Globalization;
|
|
||||||
using NBitcoin.JsonConverters;
|
using NBitcoin.JsonConverters;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
|
|
||||||
@@ -59,8 +58,6 @@ namespace BTCPayServer.Client.JsonConverters
|
|||||||
return null;
|
return null;
|
||||||
return TimeSpan.Zero;
|
return TimeSpan.Zero;
|
||||||
}
|
}
|
||||||
if (reader.TokenType == JsonToken.String && TimeSpan.TryParse(reader.Value?.ToString(), CultureInfo.InvariantCulture, out var res))
|
|
||||||
return res;
|
|
||||||
if (reader.TokenType != JsonToken.Integer)
|
if (reader.TokenType != JsonToken.Integer)
|
||||||
throw new JsonObjectException("Invalid timespan, expected integer", reader);
|
throw new JsonObjectException("Invalid timespan, expected integer", reader);
|
||||||
return ToTimespan((long)reader.Value);
|
return ToTimespan((long)reader.Value);
|
||||||
|
@@ -0,0 +1,36 @@
|
|||||||
|
using System;
|
||||||
|
using System.Globalization;
|
||||||
|
using BTCPayServer.Client.Models;
|
||||||
|
using BTCPayServer.Lightning;
|
||||||
|
using NBitcoin.JsonConverters;
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
using Newtonsoft.Json.Linq;
|
||||||
|
|
||||||
|
namespace BTCPayServer.Client.JsonConverters
|
||||||
|
{
|
||||||
|
public class TradeQuantityJsonConverter : JsonConverter<TradeQuantity>
|
||||||
|
{
|
||||||
|
public override TradeQuantity ReadJson(JsonReader reader, Type objectType, TradeQuantity existingValue, bool hasExistingValue, JsonSerializer serializer)
|
||||||
|
{
|
||||||
|
JToken token = JToken.Load(reader);
|
||||||
|
switch (token.Type)
|
||||||
|
{
|
||||||
|
case JTokenType.Float:
|
||||||
|
case JTokenType.Integer:
|
||||||
|
case JTokenType.String:
|
||||||
|
if (TradeQuantity.TryParse(token.ToString(), out var q))
|
||||||
|
return q;
|
||||||
|
break;
|
||||||
|
case JTokenType.Null:
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
throw new JsonObjectException("Invalid TradeQuantity, expected string. Expected: \"1.50\" or \"50%\"", reader);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void WriteJson(JsonWriter writer, TradeQuantity value, JsonSerializer serializer)
|
||||||
|
{
|
||||||
|
if (value is not null)
|
||||||
|
writer.WriteValue(value.ToString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -1,25 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using Newtonsoft.Json;
|
|
||||||
using Newtonsoft.Json.Linq;
|
|
||||||
|
|
||||||
namespace BTCPayServer.Client.Models;
|
|
||||||
|
|
||||||
public class AppBaseData
|
|
||||||
{
|
|
||||||
public string Id { get; set; }
|
|
||||||
public string AppType { get; set; }
|
|
||||||
public string AppName { get; set; }
|
|
||||||
public string StoreId { get; set; }
|
|
||||||
[JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
|
|
||||||
public bool? Archived { get; set; }
|
|
||||||
[JsonConverter(typeof(NBitcoin.JsonConverters.DateTimeToUnixTimeConverter))]
|
|
||||||
public DateTimeOffset Created { get; set; }
|
|
||||||
[JsonExtensionData]
|
|
||||||
public IDictionary<string, JToken> AdditionalData { get; set; } = new Dictionary<string, JToken>();
|
|
||||||
}
|
|
||||||
|
|
||||||
public interface IAppRequest
|
|
||||||
{
|
|
||||||
public string AppName { get; set; }
|
|
||||||
}
|
|
@@ -1,13 +0,0 @@
|
|||||||
using BTCPayServer.JsonConverters;
|
|
||||||
using Newtonsoft.Json;
|
|
||||||
|
|
||||||
namespace BTCPayServer.Client.Models;
|
|
||||||
|
|
||||||
public class AppCartItem
|
|
||||||
{
|
|
||||||
public string Id { get; set; }
|
|
||||||
public string Title { get; set; }
|
|
||||||
public int Count { get; set; }
|
|
||||||
[JsonConverter(typeof(NumericStringJsonConverter))]
|
|
||||||
public decimal Price { get; set; }
|
|
||||||
}
|
|
@@ -1,35 +0,0 @@
|
|||||||
using System.Collections.Generic;
|
|
||||||
using BTCPayServer.JsonConverters;
|
|
||||||
using Newtonsoft.Json;
|
|
||||||
using Newtonsoft.Json.Converters;
|
|
||||||
using Newtonsoft.Json.Linq;
|
|
||||||
|
|
||||||
namespace BTCPayServer.Client.Models;
|
|
||||||
|
|
||||||
public enum AppItemPriceType
|
|
||||||
{
|
|
||||||
Fixed,
|
|
||||||
Topup,
|
|
||||||
Minimum
|
|
||||||
}
|
|
||||||
|
|
||||||
public class AppItem
|
|
||||||
{
|
|
||||||
public string Id { get; set; }
|
|
||||||
public string Title { get; set; }
|
|
||||||
public bool Disabled { get; set; }
|
|
||||||
public string Description { get; set; }
|
|
||||||
public string[] Categories { get; set; }
|
|
||||||
public string Image { get; set; }
|
|
||||||
|
|
||||||
[JsonConverter(typeof(StringEnumConverter))]
|
|
||||||
public AppItemPriceType PriceType { get; set; }
|
|
||||||
|
|
||||||
[JsonConverter(typeof(NumericStringJsonConverter))]
|
|
||||||
public decimal? Price { get; set; }
|
|
||||||
public string BuyButtonText { get; set; }
|
|
||||||
public int? Inventory { get; set; }
|
|
||||||
|
|
||||||
[JsonExtensionData]
|
|
||||||
public Dictionary<string, JToken> AdditionalData { get; set; }
|
|
||||||
}
|
|
@@ -1,15 +0,0 @@
|
|||||||
using BTCPayServer.JsonConverters;
|
|
||||||
using Newtonsoft.Json;
|
|
||||||
|
|
||||||
namespace BTCPayServer.Client.Models;
|
|
||||||
|
|
||||||
public class AppItemStats
|
|
||||||
{
|
|
||||||
public string ItemCode { get; set; }
|
|
||||||
public string Title { get; set; }
|
|
||||||
public int SalesCount { get; set; }
|
|
||||||
|
|
||||||
[JsonConverter(typeof(NumericStringJsonConverter))]
|
|
||||||
public decimal Total { get; set; }
|
|
||||||
public string TotalFormatted { get; set; }
|
|
||||||
}
|
|
@@ -1,19 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using Newtonsoft.Json;
|
|
||||||
|
|
||||||
namespace BTCPayServer.Client.Models;
|
|
||||||
|
|
||||||
public class AppSalesStats
|
|
||||||
{
|
|
||||||
public int SalesCount { get; set; }
|
|
||||||
public IEnumerable<AppSalesStatsItem> Series { get; set; }
|
|
||||||
}
|
|
||||||
|
|
||||||
public class AppSalesStatsItem
|
|
||||||
{
|
|
||||||
[JsonConverter(typeof(NBitcoin.JsonConverters.DateTimeToUnixTimeConverter))]
|
|
||||||
public DateTime Date { get; set; }
|
|
||||||
public string Label { get; set; }
|
|
||||||
public int SalesCount { get; set; }
|
|
||||||
}
|
|
@@ -14,16 +14,6 @@ namespace BTCPayServer.Client.Models
|
|||||||
/// the email AND username of the user
|
/// the email AND username of the user
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string Email { get; set; }
|
public string Email { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// the name of the user
|
|
||||||
/// </summary>
|
|
||||||
public string Name { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// the image url of the user
|
|
||||||
/// </summary>
|
|
||||||
public string ImageUrl { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Whether the user has verified their email
|
/// Whether the user has verified their email
|
||||||
@@ -35,16 +25,6 @@ namespace BTCPayServer.Client.Models
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public bool RequiresEmailConfirmation { get; set; }
|
public bool RequiresEmailConfirmation { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Whether the user was approved by an admin
|
|
||||||
/// </summary>
|
|
||||||
public bool Approved { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// whether the user needed approval on account creation
|
|
||||||
/// </summary>
|
|
||||||
public bool RequiresApproval { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// the roles of the user
|
/// the roles of the user
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@@ -1,6 +0,0 @@
|
|||||||
namespace BTCPayServer.Client;
|
|
||||||
|
|
||||||
public class ApproveUserRequest
|
|
||||||
{
|
|
||||||
public bool Approved { get; set; }
|
|
||||||
}
|
|
84
BTCPayServer.Client/Models/CreateAppRequest.cs
Normal file
84
BTCPayServer.Client/Models/CreateAppRequest.cs
Normal 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 FormId { 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;
|
||||||
|
}
|
||||||
|
}
|
@@ -2,16 +2,6 @@ namespace BTCPayServer.Client.Models
|
|||||||
{
|
{
|
||||||
public class CreateApplicationUserRequest
|
public class CreateApplicationUserRequest
|
||||||
{
|
{
|
||||||
/// <summary>
|
|
||||||
/// the name of the new user
|
|
||||||
/// </summary>
|
|
||||||
public string Name { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// the image url of the new user
|
|
||||||
/// </summary>
|
|
||||||
public string ImageUrl { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// the email AND username of the new user
|
/// the email AND username of the new user
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
12
BTCPayServer.Client/Models/CreateCustodianAccountRequest.cs
Normal file
12
BTCPayServer.Client/Models/CreateCustodianAccountRequest.cs
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
using Newtonsoft.Json.Linq;
|
||||||
|
|
||||||
|
namespace BTCPayServer.Client.Models
|
||||||
|
{
|
||||||
|
public class CreateCustodianAccountRequest
|
||||||
|
{
|
||||||
|
public string CustodianCode { get; set; }
|
||||||
|
public string Name { get; set; }
|
||||||
|
|
||||||
|
public JObject Config { get; set; }
|
||||||
|
}
|
||||||
|
}
|
@@ -1,5 +1,4 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using BTCPayServer.Client.JsonConverters;
|
|
||||||
using BTCPayServer.JsonConverters;
|
using BTCPayServer.JsonConverters;
|
||||||
using NBitcoin;
|
using NBitcoin;
|
||||||
using NBitcoin.JsonConverters;
|
using NBitcoin.JsonConverters;
|
||||||
@@ -22,7 +21,7 @@ namespace BTCPayServer.Client.Models
|
|||||||
public bool ProceedWithPayjoin { get; set; } = true;
|
public bool ProceedWithPayjoin { get; set; } = true;
|
||||||
public bool ProceedWithBroadcast { get; set; } = true;
|
public bool ProceedWithBroadcast { get; set; } = true;
|
||||||
public bool NoChange { get; set; } = false;
|
public bool NoChange { get; set; } = false;
|
||||||
[JsonProperty(ItemConverterType = typeof(SaneOutpointJsonConverter))]
|
[JsonProperty(ItemConverterType = typeof(OutpointJsonConverter))]
|
||||||
public List<OutPoint> SelectedInputs { get; set; } = null;
|
public List<OutPoint> SelectedInputs { get; set; } = null;
|
||||||
public List<CreateOnChainTransactionRequestDestination> Destinations { get; set; }
|
public List<CreateOnChainTransactionRequestDestination> Destinations { get; set; }
|
||||||
[JsonProperty("rbf")]
|
[JsonProperty("rbf")]
|
||||||
|
@@ -8,6 +8,6 @@ namespace BTCPayServer.Client.Models
|
|||||||
public string Destination { get; set; }
|
public string Destination { get; set; }
|
||||||
[JsonConverter(typeof(NumericStringJsonConverter))]
|
[JsonConverter(typeof(NumericStringJsonConverter))]
|
||||||
public decimal? Amount { get; set; }
|
public decimal? Amount { get; set; }
|
||||||
public string PayoutMethodId { get; set; }
|
public string PaymentMethod { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1,11 +1,8 @@
|
|||||||
#nullable enable
|
#nullable enable
|
||||||
using Newtonsoft.Json.Linq;
|
|
||||||
|
|
||||||
namespace BTCPayServer.Client.Models;
|
namespace BTCPayServer.Client.Models;
|
||||||
|
|
||||||
public class CreatePayoutThroughStoreRequest : CreatePayoutRequest
|
public class CreatePayoutThroughStoreRequest : CreatePayoutRequest
|
||||||
{
|
{
|
||||||
public string? PullPaymentId { get; set; }
|
public string? PullPaymentId { get; set; }
|
||||||
public bool? Approved { get; set; }
|
public bool? Approved { get; set; }
|
||||||
public JObject? Metadata { get; set; }
|
|
||||||
}
|
}
|
||||||
|
@@ -1,25 +0,0 @@
|
|||||||
using System.Collections.Generic;
|
|
||||||
using BTCPayServer.JsonConverters;
|
|
||||||
using Newtonsoft.Json;
|
|
||||||
|
|
||||||
namespace BTCPayServer.Client.Models;
|
|
||||||
|
|
||||||
public class CreatePosInvoiceRequest
|
|
||||||
{
|
|
||||||
public string AppId { get; set; }
|
|
||||||
public List<AppCartItem> Cart { get; set; }
|
|
||||||
[JsonProperty(ItemConverterType = typeof(NumericStringJsonConverter))]
|
|
||||||
public List<decimal> Amounts { get; set; }
|
|
||||||
public int? DiscountPercent { get; set; }
|
|
||||||
public int? TipPercent { get; set; }
|
|
||||||
[JsonConverter(typeof(NumericStringJsonConverter))]
|
|
||||||
public decimal? DiscountAmount { get; set; }
|
|
||||||
[JsonConverter(typeof(NumericStringJsonConverter))]
|
|
||||||
public decimal? Tip { get; set; }
|
|
||||||
[JsonConverter(typeof(NumericStringJsonConverter))]
|
|
||||||
public decimal? Subtotal { get; set; }
|
|
||||||
[JsonConverter(typeof(NumericStringJsonConverter))]
|
|
||||||
public decimal? Total { get; set; }
|
|
||||||
public string PosData { get; set; }
|
|
||||||
}
|
|
||||||
|
|
@@ -12,6 +12,8 @@ namespace BTCPayServer.Client.Models
|
|||||||
[JsonProperty(ItemConverterType = typeof(NumericStringJsonConverter))]
|
[JsonProperty(ItemConverterType = typeof(NumericStringJsonConverter))]
|
||||||
public decimal Amount { get; set; }
|
public decimal Amount { get; set; }
|
||||||
public string Currency { get; set; }
|
public string Currency { get; set; }
|
||||||
|
[JsonConverter(typeof(TimeSpanJsonConverter.Seconds))]
|
||||||
|
public TimeSpan? Period { get; set; }
|
||||||
[JsonConverter(typeof(TimeSpanJsonConverter.Days))]
|
[JsonConverter(typeof(TimeSpanJsonConverter.Days))]
|
||||||
[JsonProperty("BOLT11Expiration")]
|
[JsonProperty("BOLT11Expiration")]
|
||||||
public TimeSpan? BOLT11Expiration { get; set; }
|
public TimeSpan? BOLT11Expiration { get; set; }
|
||||||
@@ -19,7 +21,7 @@ namespace BTCPayServer.Client.Models
|
|||||||
public DateTimeOffset? ExpiresAt { get; set; }
|
public DateTimeOffset? ExpiresAt { get; set; }
|
||||||
[JsonConverter(typeof(NBitcoin.JsonConverters.DateTimeToUnixTimeConverter))]
|
[JsonConverter(typeof(NBitcoin.JsonConverters.DateTimeToUnixTimeConverter))]
|
||||||
public DateTimeOffset? StartsAt { get; set; }
|
public DateTimeOffset? StartsAt { get; set; }
|
||||||
public string[] PayoutMethods { get; set; }
|
public string[] PaymentMethods { get; set; }
|
||||||
public bool AutoApproveClaims { get; set; }
|
public bool AutoApproveClaims { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user