Add restapi module (code from dao-node)

This commit is contained in:
HenrikJannsen 2024-06-06 14:23:49 +07:00
parent 348e66e55e
commit e4cdfa731a
No known key found for this signature in database
GPG Key ID: 02AA2BAE387C8307
34 changed files with 13252 additions and 6 deletions

7
.gitignore vendored
View File

@ -35,3 +35,10 @@ deploy
/apitest/src/main/resources/dao-setup*
/.run
/regtest/data_dirs
/build-logic/app-start-plugin/out/*
/build-logic/docker-image-builder/out/*
/build-logic/gradle-tasks/out/*
/build-logic/packaging/out/*
/build-logic/regtest/out/*
/build-logic/toolchain-resolver/out/*
/build-logic/tor-binary/out/*

View File

@ -17,6 +17,7 @@ fontawesomefx-materialdesign-font = { strictly = '2.0.26-9.1.2' }
fxmisc-easybind = { strictly = '1.0.3' }
glassfish-jaxb-lib = { strictly = '3.0.2' }
google-findbugs = { strictly = '3.0.2' }
google-gson = { strictly = '2.8.6' }
google-guava = { strictly = '30.1.1-jre' }
@ -28,6 +29,7 @@ hamcrest = { strictly = '2.2' }
jackson = { strictly = '2.17.1' }
javax-annotation = { strictly = '1.2' }
jcsv = { strictly = '1.4.0' }
jersey-lib = { strictly = '3.0.4' }
jetbrains-annotations = { strictly = '13.0' }
jfoenix = { strictly = '9.0.10' }
jopt = { strictly = '5.0.4' }
@ -48,7 +50,7 @@ qrgen = { strictly = '1.3' }
javacv = { strictly = '1.5.10' }
slf4j = { strictly = '1.7.30' }
spark = { strictly = '2.9.4' }
swagger-lib = { strictly = '2.2.0' }
[libraries]
apache-httpclient = { module = "org.apache.httpcomponents:httpclient", version.ref = "apache-httpclient" }
@ -69,6 +71,7 @@ fontawesomefx-materialdesign-font = { module = "de.jensd:fontawesomefx-materiald
fxmisc-easybind = { module = "org.fxmisc.easybind:easybind", version.ref = "fxmisc-easybind" }
glassfish-jaxb = { module = 'org.glassfish.jaxb:jaxb-runtime', version.ref = 'glassfish-jaxb-lib' }
google-findbugs = { module = "com.google.code.findbugs:jsr305", version.ref = "google-findbugs" }
google-gson = { module = "com.google.code.gson:gson", version.ref = "google-gson" }
google-guava = { module = "com.google.guava:guava", version.ref = "google-guava" }
@ -88,6 +91,9 @@ jackson-databind = { module = "com.fasterxml.jackson.core:jackson-databind", ver
javax-annotation = { module = "javax.annotation:javax.annotation-api", version.ref = "javax-annotation" }
jcsv = { module = "com.googlecode.jcsv:jcsv", version.ref = "jcsv" }
jersey-container-jdk-http = { module = 'org.glassfish.jersey.containers:jersey-container-jdk-http', version.ref = 'jersey-lib' }
jersey-media-json-jackson = { module = 'org.glassfish.jersey.media:jersey-media-json-jackson', version.ref = 'jersey-lib' }
jersey-inject-jersey-hk2 = { module = 'org.glassfish.jersey.inject:jersey-hk2', version.ref = 'jersey-lib' }
jetbrains-annotations = { module = "org.jetbrains:annotations", version.ref = "jetbrains-annotations" }
jfoenix = { module = "com.jfoenix:jfoenix", version.ref = "jfoenix" }
jopt = { module = "net.sf.jopt-simple:jopt-simple", version.ref = "jopt" }
@ -117,4 +123,9 @@ qrgen = { module = "net.glxn:qrgen", version.ref = "qrgen" }
javacv = { module = "org.bytedeco:javacv-platform", version.ref = "javacv" }
slf4j-api = { module = "org.slf4j:slf4j-api", version.ref = "slf4j" }
spark-core = { module = "com.sparkjava:spark-core", version.ref = "spark" }
swagger = { module = 'io.swagger.core.v3:swagger-jaxrs2-jakarta', version.ref = 'swagger-lib' }
[bundles]
jersey-libs = ['jersey-container-jdk-http', 'jersey-media-json-jackson', 'jersey-inject-jersey-hk2']

View File

@ -51,21 +51,71 @@
<sha256 value="af650fa4dd400bc5769320bcef08ed93813f349cabe8213d469acafbbd945d8a" origin="Generated by Gradle"/>
</artifact>
</component>
<component group="com.fasterxml" name="oss-parent" version="43">
<artifact name="oss-parent-43.pom">
<sha256 value="e5585cc1c37079b2e3817a8997945736f158831844d59d0e4d3a45b27611f926" origin="Generated by Gradle"/>
</artifact>
</component>
<component group="com.fasterxml" name="oss-parent" version="58">
<artifact name="oss-parent-58.pom">
<sha256 value="5670e6ac1c4ddcc9d413cf87997a5da2efaa4d2abe439363af9ef102a0a09e40" origin="Generated by Gradle"/>
</artifact>
</component>
<component group="com.fasterxml.jackson" name="jackson-base" version="2.12.1">
<artifact name="jackson-base-2.12.1.pom">
<sha256 value="93a8c78755a31977508021dbb3883c0dd740a06bb1c67ff4942e096c132419f5" origin="Manually computed by Alva"/>
</artifact>
</component>
<component group="com.fasterxml.jackson" name="jackson-base" version="2.13.0">
<artifact name="jackson-base-2.13.0.pom">
<sha256 value="2b2227ad9e2c4744aab7db57fe122e93ca97ccc9668bc204e94c29957dd11dd6" origin="Generated by Gradle"/>
</artifact>
</component>
<component group="com.fasterxml.jackson" name="jackson-base" version="2.13.2">
<artifact name="jackson-base-2.13.2.pom">
<sha256 value="32cfe9eb0c630db42822e567d9a36463edae3a6a4950b95d33b0ed31a68f19a6" origin="Generated by Gradle"/>
</artifact>
</component>
<component group="com.fasterxml.jackson" name="jackson-base" version="2.17.1">
<artifact name="jackson-base-2.17.1.pom">
<sha256 value="e0aefc61d38fcddd955ffeec01bb75104f1bbfffa3a6ecb58dbe74afb715e322" origin="Generated by Gradle"/>
</artifact>
</component>
<component group="com.fasterxml.jackson" name="jackson-bom" version="2.12.1">
<artifact name="jackson-bom-2.12.1.pom">
<sha256 value="083b20a4231bb0516d6e1a08248c9fbce473583a122a07fd2e0eadeff6908a38" origin="Generated by Gradle"/>
</artifact>
</component>
<component group="com.fasterxml.jackson" name="jackson-bom" version="2.13.0">
<artifact name="jackson-bom-2.13.0.pom">
<sha256 value="897dfb86d2f168801983b0f0d1cb1b3cc1825c9b1c1cc31f50f52d9a34884af6" origin="Generated by Gradle"/>
</artifact>
</component>
<component group="com.fasterxml.jackson" name="jackson-bom" version="2.13.2">
<artifact name="jackson-bom-2.13.2.pom">
<sha256 value="05e57b016bdc58d739b2536e23816800936947d5155c2d03fa8e43dfed63b6be" origin="Generated by Gradle"/>
</artifact>
</component>
<component group="com.fasterxml.jackson" name="jackson-bom" version="2.17.1">
<artifact name="jackson-bom-2.17.1.pom">
<sha256 value="9f4461228e129103eed7a302dc1001ab2e4c82dd3cea915c2a7dbb8cc61efd25" origin="Generated by Gradle"/>
</artifact>
</component>
<component group="com.fasterxml.jackson" name="jackson-parent" version="2.12">
<artifact name="jackson-parent-2.12.pom">
<sha256 value="62aa1c1679ade09f173dbf1b6c32d35c55e75800238fd5e48f13aa4337c0875b" origin="Generated by Gradle"/>
</artifact>
</component>
<component group="com.fasterxml.jackson" name="jackson-parent" version="2.13">
<artifact name="jackson-parent-2.13.pom">
<sha256 value="2bba89978172af1effcb4d143d09921a3f3082ca4dcf122b1ded98bf55b2ad57" origin="Generated by Gradle"/>
</artifact>
</component>
<component group="com.fasterxml.jackson" name="jackson-parent" version="2.17">
<artifact name="jackson-parent-2.17.pom">
<sha256 value="aee6de4a97283b040e43f4dad575e7b74796cd984d89276f7ec7567380c8a29d" origin="Generated by Gradle"/>
</artifact>
</component>
<component group="com.fasterxml.jackson.core" name="jackson-annotations" version="2.12.1">
<artifact name="jackson-annotations-2.12.1.jar">
<sha256 value="203cefdfa6c81e6aa84e11f292f29ca97344a3c3bc0293abea065cd837592873" origin="Generated by Gradle"/>
@ -74,6 +124,27 @@
<sha256 value="93a1d3d9c8d1d694431057ccbe9730e032921b1b2b166b1570017da1eeb6483e" origin="Generated by Gradle"/>
</artifact>
</component>
<component group="com.fasterxml.jackson.core" name="jackson-annotations" version="2.13.0">
<artifact name="jackson-annotations-2.13.0.module">
<sha256 value="87fd0ece1ef9266281255b7812186af488f5cd74e6ba4c4dc877cf20574820d7" origin="Generated by Gradle"/>
</artifact>
</component>
<component group="com.fasterxml.jackson.core" name="jackson-annotations" version="2.13.2">
<artifact name="jackson-annotations-2.13.2.jar">
<sha256 value="7d3df5aafa2dc61ad1dbad30f411548c0184ed92d94628c63168721f08237cd4" origin="Generated by Gradle"/>
</artifact>
<artifact name="jackson-annotations-2.13.2.module">
<sha256 value="c2fd4366b1647233c99c70c17a2e90c89bf1ea60843749cca99d794525df9cd2" origin="Generated by Gradle"/>
</artifact>
</component>
<component group="com.fasterxml.jackson.core" name="jackson-annotations" version="2.17.1">
<artifact name="jackson-annotations-2.17.1.jar">
<sha256 value="fccad82e13172c0e4384db71577219c9b8631c0820f4b18daaa57016fb661c76" origin="Generated by Gradle"/>
</artifact>
<artifact name="jackson-annotations-2.17.1.module">
<sha256 value="54d4d51da013a696be09e1f48031f7f40b77718078aa936e64c023a4fd9b9593" origin="Generated by Gradle"/>
</artifact>
</component>
<component group="com.fasterxml.jackson.core" name="jackson-core" version="2.12.1">
<artifact name="jackson-core-2.12.1.jar">
<sha256 value="cc899cb6eae0c80b87d590eea86528797369cc4feb7b79463207d6bb18f0c257" origin="Generated by Gradle"/>
@ -82,6 +153,27 @@
<sha256 value="7e4c0c921ccee0b555f0f5b36fd86707b4e556de5b02f3e6bfc315bc3fcd6fc4" origin="Generated by Gradle"/>
</artifact>
</component>
<component group="com.fasterxml.jackson.core" name="jackson-core" version="2.13.0">
<artifact name="jackson-core-2.13.0.module">
<sha256 value="73418063b7ef9ffeafb897c868cd4a4bb8ebc9cd9750e9a8ddd362269b9bf17a" origin="Generated by Gradle"/>
</artifact>
</component>
<component group="com.fasterxml.jackson.core" name="jackson-core" version="2.13.2">
<artifact name="jackson-core-2.13.2.jar">
<sha256 value="9bfa278ad05179fb68087851caf607652702ca25424bec8358a3716e751405c8" origin="Generated by Gradle"/>
</artifact>
<artifact name="jackson-core-2.13.2.module">
<sha256 value="4bdce8fae6ce8be002b68ba522ff7d17a45abd8d2ffe1ece6500270b1bfaa4d0" origin="Generated by Gradle"/>
</artifact>
</component>
<component group="com.fasterxml.jackson.core" name="jackson-core" version="2.17.1">
<artifact name="jackson-core-2.17.1.jar">
<sha256 value="ddb26c8a1f1a84535e8213c48b35b253370434e3287b3cf15777856fc4e58ce6" origin="Generated by Gradle"/>
</artifact>
<artifact name="jackson-core-2.17.1.module">
<sha256 value="8a8c0964fdfc26cedbb28d825df4621817fb8cd22b9e7a59d9c74a3a5f1bdd1d" origin="Generated by Gradle"/>
</artifact>
</component>
<component group="com.fasterxml.jackson.core" name="jackson-databind" version="2.12.1">
<artifact name="jackson-databind-2.12.1.jar">
<sha256 value="f2ca3c28ebded59c98447d51afe945323df961540af66a063c015597af936aa0" origin="Generated by Gradle"/>
@ -90,6 +182,165 @@
<sha256 value="b493b42a9c95eebb3059e030d598005ebe5bed153cbd01c0dfccc814a0c37890" origin="Generated by Gradle"/>
</artifact>
</component>
<component group="com.fasterxml.jackson.core" name="jackson-databind" version="2.13.0">
<artifact name="jackson-databind-2.13.0.module">
<sha256 value="f4cbf031bd4118501f4fa458535d133df0df995c2462bf4ef90377b8ca600899" origin="Generated by Gradle"/>
</artifact>
</component>
<component group="com.fasterxml.jackson.core" name="jackson-databind" version="2.13.2">
<artifact name="jackson-databind-2.13.2.jar">
<sha256 value="0d5459b7f18184c4ce8f07264b1b7feced51529e550a098d6f9e2dfe091138ad" origin="Generated by Gradle"/>
</artifact>
<artifact name="jackson-databind-2.13.2.module">
<sha256 value="d9d81730972864b95369d6026c4eb7a944ca87f8140e754b7e5fef347a39b68d" origin="Generated by Gradle"/>
</artifact>
</component>
<component group="com.fasterxml.jackson.core" name="jackson-databind" version="2.13.2.2">
<artifact name="jackson-databind-2.13.2.2.jar">
<sha256 value="efb86b148712a838b94b3cfc95769785a116b3461f709b4cc510055a58b804b2" origin="Generated by Gradle"/>
</artifact>
<artifact name="jackson-databind-2.13.2.2.module">
<sha256 value="64eccb5e2ae32fa1e98449b229cc5c69c5b82ac6a044e50c259d84fda9aa42e8" origin="Generated by Gradle"/>
</artifact>
</component>
<component group="com.fasterxml.jackson.core" name="jackson-databind" version="2.17.1">
<artifact name="jackson-databind-2.17.1.jar">
<sha256 value="b6ca2f7d5b1ab245cec5495ec339773d2d90554c48592590673fb18f4400a948" origin="Generated by Gradle"/>
</artifact>
<artifact name="jackson-databind-2.17.1.module">
<sha256 value="0babc646a062f0d9d3584402a50271884edc3e17a41942c1e31e0e10d71dbee6" origin="Generated by Gradle"/>
</artifact>
</component>
<component group="com.fasterxml.jackson.dataformat" name="jackson-dataformat-yaml" version="2.13.2">
<artifact name="jackson-dataformat-yaml-2.13.2.jar">
<sha256 value="e0a4d674e5aaf30ed3cd045e7fd94e9b82f0a7fbe94b25c8c496f70977966ba3" origin="Generated by Gradle"/>
</artifact>
<artifact name="jackson-dataformat-yaml-2.13.2.module">
<sha256 value="defa5a1113cdfca8f4776f81a29f5f308fe79af4b499216365ed0aa66c47730b" origin="Generated by Gradle"/>
</artifact>
</component>
<component group="com.fasterxml.jackson.dataformat" name="jackson-dataformat-yaml" version="2.17.1">
<artifact name="jackson-dataformat-yaml-2.17.1.jar">
<sha256 value="83f38459593bc10caeb1fa2653616813b1743b6bed67163c8ae8e5a4d32a5456" origin="Generated by Gradle"/>
</artifact>
<artifact name="jackson-dataformat-yaml-2.17.1.module">
<sha256 value="66acdfa412d42b1ea148a2b668cc68b75d684f9de799f436b9cb0334a095814c" origin="Generated by Gradle"/>
</artifact>
</component>
<component group="com.fasterxml.jackson.dataformat" name="jackson-dataformats-text" version="2.13.2">
<artifact name="jackson-dataformats-text-2.13.2.pom">
<sha256 value="7c5c402b2941e698ba652eccd783e9c92af555c3da49cc190a0266015b860fbd" origin="Generated by Gradle"/>
</artifact>
</component>
<component group="com.fasterxml.jackson.dataformat" name="jackson-dataformats-text" version="2.17.1">
<artifact name="jackson-dataformats-text-2.17.1.pom">
<sha256 value="04883f62cca7a92b15d97bd76fccde3e3082c18ecb0494943b220bae2a0b872b" origin="Generated by Gradle"/>
</artifact>
</component>
<component group="com.fasterxml.jackson.datatype" name="jackson-datatype-jsr310" version="2.13.2">
<artifact name="jackson-datatype-jsr310-2.13.2.jar">
<sha256 value="cf5034791afbbec5139d539c1a94194f172d52a516ad9c25aad5f235a937c747" origin="Generated by Gradle"/>
</artifact>
<artifact name="jackson-datatype-jsr310-2.13.2.module">
<sha256 value="13c911a5a8e6e37bbe5f91a6fbb5d41306a177d3c9e9458b73292c4aa01f9c56" origin="Generated by Gradle"/>
</artifact>
</component>
<component group="com.fasterxml.jackson.datatype" name="jackson-datatype-jsr310" version="2.17.1">
<artifact name="jackson-datatype-jsr310-2.17.1.jar">
<sha256 value="56765d55ac8cffdd757c1a534ec965e70b01176f64dfd7e70b0db34d8babc9fa" origin="Generated by Gradle"/>
</artifact>
<artifact name="jackson-datatype-jsr310-2.17.1.module">
<sha256 value="a2c55672419321dc82ebad3394c21225570c55e68c3e9c48b07c9b096939431c" origin="Generated by Gradle"/>
</artifact>
</component>
<component group="com.fasterxml.jackson.jakarta.rs" name="jackson-jakarta-rs-base" version="2.13.2">
<artifact name="jackson-jakarta-rs-base-2.13.2.jar">
<sha256 value="581a7cdf5b4f6f884e34537ca30ba56282fbe1ffa931355d25f210f257feb28a" origin="Generated by Gradle"/>
</artifact>
<artifact name="jackson-jakarta-rs-base-2.13.2.module">
<sha256 value="4b1201c3e3d0b7023712e133a894663eff09851952ebfb811b01807f723c2de0" origin="Generated by Gradle"/>
</artifact>
</component>
<component group="com.fasterxml.jackson.jakarta.rs" name="jackson-jakarta-rs-base" version="2.17.1">
<artifact name="jackson-jakarta-rs-base-2.17.1.jar">
<sha256 value="acb5056a215286850f83d8304cb56b169dce4554ea938d8fc56f3df1d2e030b9" origin="Generated by Gradle"/>
</artifact>
<artifact name="jackson-jakarta-rs-base-2.17.1.module">
<sha256 value="44e6c2d64adcff6c3c84633cd9595e3440a005b7113e370c3fe570aaae1b7418" origin="Generated by Gradle"/>
</artifact>
</component>
<component group="com.fasterxml.jackson.jakarta.rs" name="jackson-jakarta-rs-json-provider" version="2.13.2">
<artifact name="jackson-jakarta-rs-json-provider-2.13.2.jar">
<sha256 value="8c0446912e0444e36b005b2432ed4c650275966ed3a72ec905b02f9964d034aa" origin="Generated by Gradle"/>
</artifact>
<artifact name="jackson-jakarta-rs-json-provider-2.13.2.module">
<sha256 value="1d13ce49dfccc2ab634acbfb15660d22cf75078c995df64c4bf1e848d12c8787" origin="Generated by Gradle"/>
</artifact>
</component>
<component group="com.fasterxml.jackson.jakarta.rs" name="jackson-jakarta-rs-json-provider" version="2.17.1">
<artifact name="jackson-jakarta-rs-json-provider-2.17.1.jar">
<sha256 value="970714be0d0c56a4557db7233fbfd2a957a20784aa6b4196b15e30125e8d75d9" origin="Generated by Gradle"/>
</artifact>
<artifact name="jackson-jakarta-rs-json-provider-2.17.1.module">
<sha256 value="01675e42f140f81ae63df29cb1b2fbf8a75640168d2f9b5583945c6f4ae9a675" origin="Generated by Gradle"/>
</artifact>
</component>
<component group="com.fasterxml.jackson.jakarta.rs" name="jackson-jakarta-rs-providers" version="2.13.2">
<artifact name="jackson-jakarta-rs-providers-2.13.2.pom">
<sha256 value="b5a48400737ecbc208888a7848df4b90add3e668d7f49f9b8822dc963ba078f1" origin="Generated by Gradle"/>
</artifact>
</component>
<component group="com.fasterxml.jackson.jakarta.rs" name="jackson-jakarta-rs-providers" version="2.17.1">
<artifact name="jackson-jakarta-rs-providers-2.17.1.pom">
<sha256 value="dcd6d24ea9d8f23095d1688420e8a8a93f3dfb5c76c8d6446fd7f75586be9fa6" origin="Generated by Gradle"/>
</artifact>
</component>
<component group="com.fasterxml.jackson.module" name="jackson-module-jakarta-xmlbind-annotations" version="2.13.0">
<artifact name="jackson-module-jakarta-xmlbind-annotations-2.13.0.module">
<sha256 value="36bfaeff88c973c843025485093f4fd943c1f8ae5ecd367fd292bbffaeddb437" origin="Generated by Gradle"/>
</artifact>
</component>
<component group="com.fasterxml.jackson.module" name="jackson-module-jakarta-xmlbind-annotations" version="2.13.2">
<artifact name="jackson-module-jakarta-xmlbind-annotations-2.13.2.jar">
<sha256 value="26cdf9ab359a00007a33570649a5813f1705e9b337af23469b59620b539cd4ef" origin="Generated by Gradle"/>
</artifact>
<artifact name="jackson-module-jakarta-xmlbind-annotations-2.13.2.module">
<sha256 value="7ec1ca4ce333cc8d5d201f3e9dbe2989b728329482f2a6b8ab54fbb0c3369252" origin="Generated by Gradle"/>
</artifact>
</component>
<component group="com.fasterxml.jackson.module" name="jackson-module-jakarta-xmlbind-annotations" version="2.17.1">
<artifact name="jackson-module-jakarta-xmlbind-annotations-2.17.1.jar">
<sha256 value="45818eafe371ca1b0f53fd06d066b55d82d758a144423b0dfc62b4beff73f157" origin="Generated by Gradle"/>
</artifact>
<artifact name="jackson-module-jakarta-xmlbind-annotations-2.17.1.module">
<sha256 value="e9765e65ff3efb0e2471d7f97eed3809a5dd6ca4217ba40975e248654c259099" origin="Generated by Gradle"/>
</artifact>
</component>
<component group="com.fasterxml.jackson.module" name="jackson-modules-base" version="2.13.0">
<artifact name="jackson-modules-base-2.13.0.pom">
<sha256 value="8eb8b01a63cd65a83f94bfa0701f70ce213fe5298ad161caa16aa80422363b4a" origin="Generated by Gradle"/>
</artifact>
</component>
<component group="com.fasterxml.jackson.module" name="jackson-modules-base" version="2.13.2">
<artifact name="jackson-modules-base-2.13.2.pom">
<sha256 value="976e15788e611ea47a64a8246273ead43a7f461dbfd0ff59b2c9cab190a2c773" origin="Generated by Gradle"/>
</artifact>
</component>
<component group="com.fasterxml.jackson.module" name="jackson-modules-base" version="2.17.1">
<artifact name="jackson-modules-base-2.17.1.pom">
<sha256 value="7f33ca245d4384efa04d506840862e980d50318c06920f9a3adf05d48f0b7943" origin="Generated by Gradle"/>
</artifact>
</component>
<component group="com.fasterxml.jackson.module" name="jackson-modules-java8" version="2.13.2">
<artifact name="jackson-modules-java8-2.13.2.pom">
<sha256 value="f221a49c7286d64079c261d4737b5e396752de29c47c22a25f3be47c67492861" origin="Generated by Gradle"/>
</artifact>
</component>
<component group="com.fasterxml.jackson.module" name="jackson-modules-java8" version="2.17.1">
<artifact name="jackson-modules-java8-2.17.1.pom">
<sha256 value="b5c5069359edd71be0c7fe1f09f7d2da8a2da73323b3f466d3ca3166dc3c7a43" origin="Generated by Gradle"/>
</artifact>
</component>
<component group="com.github.bisq-network" name="bitcoinj" version="42bbae9">
<artifact name="bitcoinj-42bbae9.jar">
<sha256 value="eccd3b5250d40ac3147d0e087e856ebaa8665720351b802d30ac53cf17b559c5" origin="Generated by Gradle"/>
@ -695,6 +946,52 @@
<sha256 value="94cad20a9255ae7c948ab5cbb9b02076c0c7c5166f6234996d2c8da744671692" origin="Generated by Gradle"/>
</artifact>
</component>
<component group="com.sun.activation" name="all" version="2.0.1">
<artifact name="all-2.0.1.pom">
<sha256 value="648d5d62b6153f42f190ced2d6e70c1e6442550c9cfeb66fbee0961c6616b2cc" origin="Generated by Gradle"/>
</artifact>
</component>
<component group="com.sun.activation" name="jakarta.activation" version="2.0.1">
<artifact name="jakarta.activation-2.0.1.jar">
<sha256 value="b9e24b7dd6e07495562ea96531be3130c96dba4d78e1dfd88adbbdebf4332871" origin="Generated by Gradle"/>
</artifact>
<artifact name="jakarta.activation-2.0.1.pom">
<sha256 value="8a068592db08e6853204ff0b625a301438e3c36ea5f1ae65babfed208502781a" origin="Generated by Gradle"/>
</artifact>
</component>
<component group="com.sun.istack" name="istack-commons" version="4.0.1">
<artifact name="istack-commons-4.0.1.pom">
<sha256 value="cc3bcf26d42c2e023a4a90e47f331793e0d9476baf2727ad9ddc8bbe735216c2" origin="Generated by Gradle"/>
</artifact>
</component>
<component group="com.sun.istack" name="istack-commons-runtime" version="4.0.1">
<artifact name="istack-commons-runtime-4.0.1.jar">
<sha256 value="9f91115f449384886f572bd62c8812ee1004273d4b5c85cac65179ad4c16990f" origin="Generated by Gradle"/>
</artifact>
<artifact name="istack-commons-runtime-4.0.1.pom">
<sha256 value="38fb6ac1b3d9b549adf21f7dc84cd15c1bb7c75cceb58126e9bd16cbe6ddeeef" origin="Generated by Gradle"/>
</artifact>
</component>
<component group="com.sun.xml.bind" name="jaxb-bom-ext" version="3.0.2">
<artifact name="jaxb-bom-ext-3.0.2.pom">
<sha256 value="8d448852996c758311a5bb3da1e7234c6a8679f4d13b52275b14a9f517af8c10" origin="Generated by Gradle"/>
</artifact>
</component>
<component group="com.sun.xml.bind.mvn" name="jaxb-parent" version="3.0.2">
<artifact name="jaxb-parent-3.0.2.pom">
<sha256 value="1df0217784257f7fc3ab45c8cee214ec2058ae76c41fbcd9cf8394d5e98c9673" origin="Generated by Gradle"/>
</artifact>
</component>
<component group="com.sun.xml.bind.mvn" name="jaxb-runtime-parent" version="3.0.2">
<artifact name="jaxb-runtime-parent-3.0.2.pom">
<sha256 value="985009de59b42555e88fee17f2d4467d84f6c227646f83e6fc1b31f346b8ebdd" origin="Generated by Gradle"/>
</artifact>
</component>
<component group="com.sun.xml.bind.mvn" name="jaxb-txw-parent" version="3.0.2">
<artifact name="jaxb-txw-parent-3.0.2.pom">
<sha256 value="0d5abccc805a2ebbf25c3f2ec1b3e42dcdeb16ea9c905b985674620168c1a0ab" origin="Generated by Gradle"/>
</artifact>
</component>
<component group="commons-codec" name="commons-codec" version="1.13">
<artifact name="commons-codec-1.13.jar">
<sha256 value="61f7a3079e92b9fdd605238d0295af5fd11ac411a0a0af48deace1f6c5ffa072" origin="Generated by Gradle"/>
@ -764,6 +1061,14 @@
<sha256 value="1109f1f71a54254d590337d8b9d443f9dfc08728c9c1d8335655cc1dcc88c0b9" origin="Generated by Gradle"/>
</artifact>
</component>
<component group="io.github.classgraph" name="classgraph" version="4.8.138">
<artifact name="classgraph-4.8.138.jar">
<sha256 value="272ffa06f76c8ed227d36ddbba1e5bbd1c7754c6541197b948a3a5c59d724bad" origin="Generated by Gradle"/>
</artifact>
<artifact name="classgraph-4.8.138.pom">
<sha256 value="1049cf5607610c0c38d432ede3a7cb11398edc14aad883aaddf8f03f09ef73b9" origin="Generated by Gradle"/>
</artifact>
</component>
<component group="io.github.microutils" name="kotlin-logging" version="1.5.4">
<artifact name="kotlin-logging-1.5.4.jar">
<sha256 value="4992504fd3c6ecdf9ed10874b9508e758bb908af9e9d7af19a61e9afb6b7e27a" origin="Generated by Gradle"/>
@ -962,6 +1267,96 @@
<sha256 value="84a12f34817d1f2f79df810bcbaacb29900678384d3dd0502df0bd963a4f3fdb" origin="Generated by Gradle"/>
</artifact>
</component>
<component group="io.swagger.core.v3" name="swagger-annotations-jakarta" version="2.2.0">
<artifact name="swagger-annotations-jakarta-2.2.0.jar">
<sha256 value="f0ab0fea60092329d82840ab49b9dd8f237a9393342611bdc7b3b006d7115851" origin="Generated by Gradle"/>
</artifact>
<artifact name="swagger-annotations-jakarta-2.2.0.pom">
<sha256 value="c8782bf99856c2aac4040c4e8dcaf610e74f335dcb29983b53032c5b1c0a1b6f" origin="Generated by Gradle"/>
</artifact>
</component>
<component group="io.swagger.core.v3" name="swagger-core-jakarta" version="2.2.0">
<artifact name="swagger-core-jakarta-2.2.0.jar">
<sha256 value="4d2924e3bec3d62ce77aa8d48ef8e940d54433f34d864721dcb146ad9c143e1e" origin="Generated by Gradle"/>
</artifact>
<artifact name="swagger-core-jakarta-2.2.0.pom">
<sha256 value="8b08d71d7b098fbe3ab0fed3de8e2c7b40aaecf13082a5b02482cc235d736378" origin="Generated by Gradle"/>
</artifact>
</component>
<component group="io.swagger.core.v3" name="swagger-integration-jakarta" version="2.2.0">
<artifact name="swagger-integration-jakarta-2.2.0.jar">
<sha256 value="69235e2a5032681726d0b901907405fa3bb0e62862fc32dac6139d311000b185" origin="Generated by Gradle"/>
</artifact>
<artifact name="swagger-integration-jakarta-2.2.0.pom">
<sha256 value="a2e296b3a7220a02a05a2a893324986e1df322e1b351e327fe4353d84d64ed2e" origin="Generated by Gradle"/>
</artifact>
</component>
<component group="io.swagger.core.v3" name="swagger-jaxrs2-jakarta" version="2.2.0">
<artifact name="swagger-jaxrs2-jakarta-2.2.0.jar">
<sha256 value="26313ef0b4032ad815a338aa939b847614577a0171bb307c8007be8fbe2831fb" origin="Generated by Gradle"/>
</artifact>
<artifact name="swagger-jaxrs2-jakarta-2.2.0.pom">
<sha256 value="0f2bde585d9e4fd20071333ebd04152915ddb801d765e1eed5e0c73d7a9ecc81" origin="Generated by Gradle"/>
</artifact>
</component>
<component group="io.swagger.core.v3" name="swagger-models-jakarta" version="2.2.0">
<artifact name="swagger-models-jakarta-2.2.0.jar">
<sha256 value="e04dad52c9dad1defae12414f93ed7e001bcb62813c282eadc1e2a751b3e23b2" origin="Generated by Gradle"/>
</artifact>
<artifact name="swagger-models-jakarta-2.2.0.pom">
<sha256 value="da3027040ae7dc16bdba56500412fb62c3163d61017dd3a30d88f33e7de0acf1" origin="Generated by Gradle"/>
</artifact>
</component>
<component group="io.swagger.core.v3" name="swagger-project-jakarta" version="2.2.0">
<artifact name="swagger-project-jakarta-2.2.0.pom">
<sha256 value="193732d7f2518ac45803f1f66c8d8fcb9714c7ac810ad91446e339a600678bc0" origin="Generated by Gradle"/>
</artifact>
</component>
<component group="jakarta.annotation" name="jakarta.annotation-api" version="2.0.0">
<artifact name="jakarta.annotation-api-2.0.0.jar">
<sha256 value="2f0a0a2a5fe653794bdb1b9531bc9bea53c92c11e0b693e74cf8e396aa2ff325" origin="Generated by Gradle"/>
</artifact>
<artifact name="jakarta.annotation-api-2.0.0.pom">
<sha256 value="ecf9e55fb69bad030906fe8fe7b9f5584989c30d2a01c709f291820e23845934" origin="Generated by Gradle"/>
</artifact>
</component>
<component group="jakarta.inject" name="jakarta.inject-api" version="2.0.0">
<artifact name="jakarta.inject-api-2.0.0.jar">
<sha256 value="842ccf3b892aca3fbd384c99d1516a8b7c448c55cee560ab2724488016198706" origin="Generated by Gradle"/>
</artifact>
<artifact name="jakarta.inject-api-2.0.0.pom">
<sha256 value="d7fe9d15ed31e3f656cbc973f838bd5f708006fd770f1513448811e1974f7fde" origin="Generated by Gradle"/>
</artifact>
</component>
<component group="jakarta.validation" name="jakarta.validation-api" version="3.0.0">
<artifact name="jakarta.validation-api-3.0.0.jar">
<sha256 value="c9bb1a2e061cdd8b1ff6fd9115b58c4541fb41d5a20210e57936dac2777e4a19" origin="Generated by Gradle"/>
</artifact>
<artifact name="jakarta.validation-api-3.0.0.pom">
<sha256 value="af7a9a1a584a3c83d2ec9082c89c071c0d6d92dd9fd7bec0a0a96500377bd026" origin="Generated by Gradle"/>
</artifact>
</component>
<component group="jakarta.ws.rs" name="jakarta.ws.rs-api" version="3.0.0">
<artifact name="jakarta.ws.rs-api-3.0.0.jar">
<sha256 value="0bcb2cf4522831ad83cc7e936b8db60e2afb2582d19d672eb17d01da2c777322" origin="Generated by Gradle"/>
</artifact>
<artifact name="jakarta.ws.rs-api-3.0.0.pom">
<sha256 value="ce7fd5cf84911924789313538d813120fe1e2019fca045f62bd843a8271d9432" origin="Generated by Gradle"/>
</artifact>
</component>
<component group="jakarta.xml.bind" name="jakarta.xml.bind-api" version="3.0.1">
<artifact name="jakarta.xml.bind-api-3.0.1.jar">
<sha256 value="b8fb4bee3ff5b5c1ef77144d8411316018d7bbd41fcf1ede0646f7978546b867" origin="Generated by Gradle"/>
</artifact>
<artifact name="jakarta.xml.bind-api-3.0.1.pom">
<sha256 value="a273dac9741412fd9dccce9911298706d789e582dcb35197075f6fd2a5b0ebea" origin="Generated by Gradle"/>
</artifact>
</component>
<component group="jakarta.xml.bind" name="jakarta.xml.bind-api-parent" version="3.0.1">
<artifact name="jakarta.xml.bind-api-parent-3.0.1.pom">
<sha256 value="9f1fb5d4a02e9f8fdd62ef3beab94b8fea7b81643748c86f68a31f40f774ad56" origin="Generated by Gradle"/>
</artifact>
</component>
<component group="javax.annotation" name="javax.annotation-api" version="1.2">
<artifact name="javax.annotation-api-1.2.jar">
<sha256 value="5909b396ca3a2be10d0eea32c74ef78d816e1b4ead21de1d78de1f890d033e04" origin="Generated by Gradle"/>
@ -1109,6 +1504,11 @@
<sha256 value="bc10624e0623f36577fac5639ca2936d3240ed152fb6d8d533ab4d270543491c" origin="Generated by Gradle"/>
</artifact>
</component>
<component group="org.apache" name="apache" version="30">
<artifact name="apache-30.pom">
<sha256 value="63dd4a393a9c0dfcb314efe83871a41d243bc8d200cbc7f2d197f30da78239d8" origin="Generated by Gradle"/>
</artifact>
</component>
<component group="org.apache" name="apache" version="7">
<artifact name="apache-7.pom">
<sha256 value="1397ce1db433adc9f223dbf07496d133681448751f4ae29e58f68e78fb4b6c25" origin="Generated by Gradle"/>
@ -1151,6 +1551,22 @@
<sha256 value="980d665d83fed04665134f0578e507442a0e750691073784391b0a7988724a75" origin="Generated by Gradle"/>
</artifact>
</component>
<component group="org.apache.commons" name="commons-lang3" version="3.12.0">
<artifact name="commons-lang3-3.12.0.jar">
<sha256 value="d919d904486c037f8d193412da0c92e22a9fa24230b9d67a57855c5c31c7e94e" origin="Generated by Gradle"/>
</artifact>
<artifact name="commons-lang3-3.12.0.pom">
<sha256 value="82d31f1dcc4583effd744e979165b16da64bf86bca623fc5d1b03ed94f45c85a" origin="Generated by Gradle"/>
</artifact>
</component>
<component group="org.apache.commons" name="commons-lang3" version="3.14.0">
<artifact name="commons-lang3-3.14.0.jar">
<sha256 value="7b96bf3ee68949abb5bc465559ac270e0551596fa34523fddf890ec418dde13c" origin="Generated by Gradle"/>
</artifact>
<artifact name="commons-lang3-3.14.0.pom">
<sha256 value="110438863bad37c28f906bf87016e38c7a8c758ba321e09d11dc5a2363a8e79e" origin="Generated by Gradle"/>
</artifact>
</component>
<component group="org.apache.commons" name="commons-parent" version="17">
<artifact name="commons-parent-17.pom">
<sha256 value="96e718baf534874ee62ce4d42de265f2ddacd88391a540e030d59d98fa7c4408" origin="Generated by Gradle"/>
@ -1186,6 +1602,11 @@
<sha256 value="75dbe8f34e98e4c3ff42daae4a2f9eb4cbcd3b5f1047d54460ace906dbb4502e" origin="Generated by Gradle"/>
</artifact>
</component>
<component group="org.apache.commons" name="commons-parent" version="64">
<artifact name="commons-parent-64.pom">
<sha256 value="6f19638994e8357b4ed734696f992057efaafa1235673998133299798e2ccddb" origin="Generated by Gradle"/>
</artifact>
</component>
<component group="org.apache.httpcomponents" name="httpclient" version="4.5.12">
<artifact name="httpclient-4.5.12.jar">
<sha256 value="bc5f065aba5dd815ee559dd24d9bcb797fb102ff9cfa036f5091ebc529bd3b93" origin="Generated by Gradle"/>
@ -2147,6 +2568,166 @@
<sha256 value="28323c619c05bd0ef05bae81cd056b04f382d7d09ae9e46311e4ec828b611f2a" origin="Generated by Gradle"/>
</artifact>
</component>
<component group="org.glassfish.hk2" name="external" version="3.0.1">
<artifact name="external-3.0.1.pom">
<sha256 value="9b3f3b3ee880438c04d98afd33392e8e1c7b22c99eb39ccc785f01915d97da47" origin="Generated by Gradle"/>
</artifact>
</component>
<component group="org.glassfish.hk2" name="hk2-api" version="3.0.1">
<artifact name="hk2-api-3.0.1.jar">
<sha256 value="428684e4ade0d881da034c2a9f301defc686e0ecc09be606708191f60c89ac58" origin="Generated by Gradle"/>
</artifact>
<artifact name="hk2-api-3.0.1.pom">
<sha256 value="03649f4a128900d0c9dde853817dde818deb9beb16e72c183efed0508329fae1" origin="Generated by Gradle"/>
</artifact>
</component>
<component group="org.glassfish.hk2" name="hk2-locator" version="3.0.1">
<artifact name="hk2-locator-3.0.1.jar">
<sha256 value="dddcafe0c45f438b449dd94be33fc3e0c0ff3d63f27640c04591852464c69ce9" origin="Generated by Gradle"/>
</artifact>
<artifact name="hk2-locator-3.0.1.pom">
<sha256 value="66c49b5b9dc5dcf48944a7a09216c63e1cc4c1a8cddb7814441966c206439690" origin="Generated by Gradle"/>
</artifact>
</component>
<component group="org.glassfish.hk2" name="hk2-parent" version="3.0.1">
<artifact name="hk2-parent-3.0.1.pom">
<sha256 value="7638ac45e235ebfd24295a951da8c7df366766c6af805a853f055f9732c5ab0c" origin="Generated by Gradle"/>
</artifact>
</component>
<component group="org.glassfish.hk2" name="hk2-utils" version="3.0.1">
<artifact name="hk2-utils-3.0.1.jar">
<sha256 value="73c6c0c6148ede0190028194aec370932ac4add3ac1ad73250c05d682a2b13fb" origin="Generated by Gradle"/>
</artifact>
<artifact name="hk2-utils-3.0.1.pom">
<sha256 value="efee7201d5b1c41f2cf71b781e036857dabab765144b6908836090c82edb13ea" origin="Generated by Gradle"/>
</artifact>
</component>
<component group="org.glassfish.hk2" name="osgi-resource-locator" version="1.0.3">
<artifact name="osgi-resource-locator-1.0.3.jar">
<sha256 value="aab5d7849f7cfcda2cc7c541ba1bd365151d42276f151c825387245dfde3dd74" origin="Generated by Gradle"/>
</artifact>
<artifact name="osgi-resource-locator-1.0.3.pom">
<sha256 value="8b6622eb81e557299fbd9aa854bc5ac76d307f7ae5e770586489a58bb5338b2a" origin="Generated by Gradle"/>
</artifact>
</component>
<component group="org.glassfish.hk2.external" name="aopalliance-repackaged" version="3.0.1">
<artifact name="aopalliance-repackaged-3.0.1.jar">
<sha256 value="6c69d95ad2562f44a7611eab356c4a5955a7b55c5da2e3cb0f42e6d530e02f36" origin="Generated by Gradle"/>
</artifact>
<artifact name="aopalliance-repackaged-3.0.1.pom">
<sha256 value="02f67e312f70fb7337af63e32af7147d1641ea604b6b3c547a45bdcd398356fc" origin="Generated by Gradle"/>
</artifact>
</component>
<component group="org.glassfish.jaxb" name="jaxb-bom" version="3.0.2">
<artifact name="jaxb-bom-3.0.2.pom">
<sha256 value="062a1332f8cb4bed0dd9cd58bb4cc07501fa44c90daa17fec1079f450b9d5703" origin="Generated by Gradle"/>
</artifact>
</component>
<component group="org.glassfish.jaxb" name="jaxb-core" version="3.0.2">
<artifact name="jaxb-core-3.0.2.jar">
<sha256 value="f9a360b939597643b2676e35fc497afb561d20e8a513128a5c0070366db11bbd" origin="Generated by Gradle"/>
</artifact>
<artifact name="jaxb-core-3.0.2.pom">
<sha256 value="60c2e1a9bb7ab16ba9ca526c471e0330db57c8739e2c0bad0d990e9ed6c7ce8e" origin="Generated by Gradle"/>
</artifact>
</component>
<component group="org.glassfish.jaxb" name="jaxb-runtime" version="3.0.2">
<artifact name="jaxb-runtime-3.0.2.jar">
<sha256 value="7b3a3784b9c6e343a8d38fc108602ba810177f03f2d8d1e7258b1cef7fd9d4c7" origin="Generated by Gradle"/>
</artifact>
<artifact name="jaxb-runtime-3.0.2.pom">
<sha256 value="018d81f023f29ee7c555d6f597206e2d4c2fb80b6dbc18545ae8ad7baf8b1907" origin="Generated by Gradle"/>
</artifact>
</component>
<component group="org.glassfish.jaxb" name="txw2" version="3.0.2">
<artifact name="txw2-3.0.2.jar">
<sha256 value="b4bcf94fb0a759456e2521724513baec94b78e93127544af162e3cff08d93343" origin="Generated by Gradle"/>
</artifact>
<artifact name="txw2-3.0.2.pom">
<sha256 value="699fa82ac3076fd64dba37e4c3c0d22556a53f847500b2be10dfc729423e78b9" origin="Generated by Gradle"/>
</artifact>
</component>
<component group="org.glassfish.jersey" name="project" version="3.0.4">
<artifact name="project-3.0.4.pom">
<sha256 value="58368bc91ac747503c973aa1959bbd41f7d214a7c1a48137b6d301119eae70a0" origin="Generated by Gradle"/>
</artifact>
</component>
<component group="org.glassfish.jersey.containers" name="jersey-container-jdk-http" version="3.0.4">
<artifact name="jersey-container-jdk-http-3.0.4.jar">
<sha256 value="c7655050ed3b1b934e459480c7d1ddc1c9a76309ccdddfa880ad475e7119ad1b" origin="Generated by Gradle"/>
</artifact>
<artifact name="jersey-container-jdk-http-3.0.4.pom">
<sha256 value="074e6f36dcbffdc6a80a88aa33ef36679f0f7ab69c1f254a501ab0fe8ef7db89" origin="Generated by Gradle"/>
</artifact>
</component>
<component group="org.glassfish.jersey.containers" name="project" version="3.0.4">
<artifact name="project-3.0.4.pom">
<sha256 value="84b67e1234201c83e42aabe4faa5692f17b776b7e00de84df59dd5c5dcd8e5bf" origin="Generated by Gradle"/>
</artifact>
</component>
<component group="org.glassfish.jersey.core" name="jersey-client" version="3.0.4">
<artifact name="jersey-client-3.0.4.jar">
<sha256 value="15ff11c974a4d8fcf230ba237f66a90af349b6bb2e2e33e27cb60840c8b605d8" origin="Generated by Gradle"/>
</artifact>
<artifact name="jersey-client-3.0.4.pom">
<sha256 value="27398f02dda9654c70e49f6b21ae1fb7d4cb440bd6a6fef42fedb9336759256c" origin="Generated by Gradle"/>
</artifact>
</component>
<component group="org.glassfish.jersey.core" name="jersey-common" version="3.0.4">
<artifact name="jersey-common-3.0.4.jar">
<sha256 value="44e5b20a3f212e62d9cac442505557ed38a2538ea803a63ae4a40dd6e0e89892" origin="Generated by Gradle"/>
</artifact>
<artifact name="jersey-common-3.0.4.pom">
<sha256 value="9e9f69ebe2132faecf1baa3d11c421c39d4d74283fa3211d5ca51b87412a9b52" origin="Generated by Gradle"/>
</artifact>
</component>
<component group="org.glassfish.jersey.core" name="jersey-server" version="3.0.4">
<artifact name="jersey-server-3.0.4.jar">
<sha256 value="ab6cbc4c1f5ce50f68407312c88d247f909dc055f1725929e5823cc8d23f6767" origin="Generated by Gradle"/>
</artifact>
<artifact name="jersey-server-3.0.4.pom">
<sha256 value="40af0e2bcb13a1ecd3099039bdddd7f233b24d49a8ae3f1d3385127ea22811c5" origin="Generated by Gradle"/>
</artifact>
</component>
<component group="org.glassfish.jersey.ext" name="jersey-entity-filtering" version="3.0.4">
<artifact name="jersey-entity-filtering-3.0.4.jar">
<sha256 value="6a3aeb0a078b764fb343f04b4d9b9fbbafcc128f10fc5c07b9162bef3f179300" origin="Generated by Gradle"/>
</artifact>
<artifact name="jersey-entity-filtering-3.0.4.pom">
<sha256 value="165e5d2fe59eb50869686dd55483e1d22251067c116671de3df80c08b599508d" origin="Generated by Gradle"/>
</artifact>
</component>
<component group="org.glassfish.jersey.ext" name="project" version="3.0.4">
<artifact name="project-3.0.4.pom">
<sha256 value="2862c1d7666e4c10a8187b66c0327047629436bdaafa9fed9f5a3eea6a3c126f" origin="Generated by Gradle"/>
</artifact>
</component>
<component group="org.glassfish.jersey.inject" name="jersey-hk2" version="3.0.4">
<artifact name="jersey-hk2-3.0.4.jar">
<sha256 value="9e78e8973bb6c5123f8934c2c135e1996a8faa6155c63d7cbf2c375989bfcd35" origin="Generated by Gradle"/>
</artifact>
<artifact name="jersey-hk2-3.0.4.pom">
<sha256 value="eb549ae9ba2cf81f4d56176e2175bb605f546a3b18a6d22dfcc429b7a1d2c309" origin="Generated by Gradle"/>
</artifact>
</component>
<component group="org.glassfish.jersey.inject" name="project" version="3.0.4">
<artifact name="project-3.0.4.pom">
<sha256 value="6b39b35587aba71fa5e77eb5b87f5f4b9ac85590cd91b4d071c705043b7adf10" origin="Generated by Gradle"/>
</artifact>
</component>
<component group="org.glassfish.jersey.media" name="jersey-media-json-jackson" version="3.0.4">
<artifact name="jersey-media-json-jackson-3.0.4.jar">
<sha256 value="ca312bf737be26ca1e7fd263d80774c011beb4e6f3835adcec82ce8a4853f9a3" origin="Generated by Gradle"/>
</artifact>
<artifact name="jersey-media-json-jackson-3.0.4.pom">
<sha256 value="0f04c37569e99dc8c90da8996c02aa78505fe954a49eaa4e8981e0d182d40361" origin="Generated by Gradle"/>
</artifact>
</component>
<component group="org.glassfish.jersey.media" name="project" version="3.0.4">
<artifact name="project-3.0.4.pom">
<sha256 value="78cec28521f180375eb695d7b3c262a8091d0a78a060ff324fcc1655c5cf8515" origin="Generated by Gradle"/>
</artifact>
</component>
<component group="org.gradle.kotlin" name="gradle-kotlin-dsl-plugins" version="2.4.1">
<artifact name="gradle-kotlin-dsl-plugins-2.4.1.jar">
<sha256 value="24d7f385cdffff81648f11098688fd0a2f1986c5286364183c08958927e5307d" origin="Generated by Gradle"/>
@ -2244,6 +2825,14 @@
<sha256 value="c9d3790f030276541d118a11be67fd271bf81e301b962780e542c2e5f636c1b1" origin="Generated by Gradle"/>
</artifact>
</component>
<component group="org.javassist" name="javassist" version="3.25.0-GA">
<artifact name="javassist-3.25.0-GA.jar">
<sha256 value="5d49abd02997134f80041645e9668e1ff97afd69d2c2c55ae9fbd40dc073f97b" origin="Generated by Gradle"/>
</artifact>
<artifact name="javassist-3.25.0-GA.pom">
<sha256 value="ed029ade7c0f9076a44c058b02eeb41cee50abb7aaf08d32ea8db71a9a65723a" origin="Generated by Gradle"/>
</artifact>
</component>
<component group="org.jboss" name="jboss-parent" version="36">
<artifact name="jboss-parent-36.pom">
<sha256 value="000dd616298aebd21a9d5731874df083d7298424b91e037b73cbdd07ebc83e0e" origin="Generated by Gradle"/>
@ -2569,6 +3158,22 @@
<sha256 value="9105d34daa35bbebc34c3a238e2cd0f975849823665ba65799f826033005bf4b" origin="Generated by Gradle"/>
</artifact>
</component>
<component group="org.junit" name="junit-bom" version="5.10.0">
<artifact name="junit-bom-5.10.0.module">
<sha256 value="eb3ee6127608010694a898056e7407d117296003aba5f5db801df430b9887fcf" origin="Generated by Gradle"/>
</artifact>
<artifact name="junit-bom-5.10.0.pom">
<sha256 value="e006dd8894f9fc7b75fc32bb12fe5ed8be65667d5b454f99e2e0b8c5bb8d30b3" origin="Generated by Gradle"/>
</artifact>
</component>
<component group="org.junit" name="junit-bom" version="5.10.2">
<artifact name="junit-bom-5.10.2.module">
<sha256 value="de23b114b3e4119a8fe6eb17bed5a3852816698bace67071579d6d927ebb080a" origin="Generated by Gradle"/>
</artifact>
<artifact name="junit-bom-5.10.2.pom">
<sha256 value="169dd904a4b0f6520cffe658cc62292bfe9f3c14a989fa92120724cde43a9968" origin="Generated by Gradle"/>
</artifact>
</component>
<component group="org.junit" name="junit-bom" version="5.7.0">
<artifact name="junit-bom-5.7.0.module">
<sha256 value="25de454b3add67654d6691b53de7593b502967b5ff549547b104d7961f1a52bd" origin="Generated by Gradle"/>
@ -2577,6 +3182,22 @@
<sha256 value="35fb15f8d0bee2b5900a22832762366552f9a349c56ced60ba123ce47738ff00" origin="Generated by Gradle"/>
</artifact>
</component>
<component group="org.junit" name="junit-bom" version="5.7.1">
<artifact name="junit-bom-5.7.1.module">
<sha256 value="9854e3894d64b2485207e0046bca07b3d42d169e782f4fa8c9ce229a78faee04" origin="Generated by Gradle"/>
</artifact>
<artifact name="junit-bom-5.7.1.pom">
<sha256 value="0b9b14a3d62106fafe8c68a717b87b87ad18685899451b753c04fa41b6857784" origin="Generated by Gradle"/>
</artifact>
</component>
<component group="org.junit.jupiter" name="junit-jupiter-api" version="5.10.2">
<artifact name="junit-jupiter-api-5.10.2.jar">
<sha256 value="afff77c186cd317275803872fa5133aa801fd6ac40bd91c78a6cf8009b4b17cc" origin="Generated by Gradle"/>
</artifact>
<artifact name="junit-jupiter-api-5.10.2.module">
<sha256 value="411b4a96c2a6db0998d6e58e899367f0d1254163f3041c9d98e7aedfca374419" origin="Generated by Gradle"/>
</artifact>
</component>
<component group="org.junit" name="junit-bom" version="5.8.2">
<artifact name="junit-bom-5.8.2.module">
<sha256 value="40cfad993fa70ecdf2af74d0c56da1484ee220964be8f932cfe632be9a2733fa" origin="Generated by Gradle"/>
@ -2593,6 +3214,14 @@
<sha256 value="d1a7bae6cd44ad6d96715261410eef2338a494436d667280d1373a47c17e241c" origin="Generated by Gradle"/>
</artifact>
</component>
<component group="org.junit.jupiter" name="junit-jupiter-engine" version="5.10.2">
<artifact name="junit-jupiter-engine-5.10.2.jar">
<sha256 value="b6df35da750a546ae932376f11b3c0df841f0c90c7cb2944cd39adb432886e4b" origin="Generated by Gradle"/>
</artifact>
<artifact name="junit-jupiter-engine-5.10.2.module">
<sha256 value="143ef275ae6695119d78212a93245acebbf9235b5375b9f4c1d4af732f3b530a" origin="Generated by Gradle"/>
</artifact>
</component>
<component group="org.junit.jupiter" name="junit-jupiter-engine" version="5.7.0">
<artifact name="junit-jupiter-engine-5.7.0.jar">
<sha256 value="dfa26af94644ac2612dde6625852fcb550a0d21caa243257de54cba738ba87af" origin="Generated by Gradle"/>
@ -2601,6 +3230,14 @@
<sha256 value="c36bda48228eef5c40cdc9a9d6303bb848382cdb0884b3677d49182b4ec7a1a4" origin="Generated by Gradle"/>
</artifact>
</component>
<component group="org.junit.jupiter" name="junit-jupiter-params" version="5.10.2">
<artifact name="junit-jupiter-params-5.10.2.jar">
<sha256 value="edb1e43ff0b8067626ffb55e5e9eeca1d9ab2478141a7c7f253d115b29cc7cf2" origin="Generated by Gradle"/>
</artifact>
<artifact name="junit-jupiter-params-5.10.2.module">
<sha256 value="20c2e65d52a39c85496e8e170e08c6ed2935c7f35e651013d964dc1bb75c827b" origin="Generated by Gradle"/>
</artifact>
</component>
<component group="org.junit.jupiter" name="junit-jupiter-params" version="5.7.0">
<artifact name="junit-jupiter-params-5.7.0.jar">
<sha256 value="ca9f555c37b9bf79effd2e834af549e4feb52ad8ac9e348fe5b430d4d8a482b7" origin="Generated by Gradle"/>
@ -2609,6 +3246,14 @@
<sha256 value="23561cb313916ed459a3a4c325c1573f7dc41f89c14fbea4328aa8c87782baaf" origin="Generated by Gradle"/>
</artifact>
</component>
<component group="org.junit.platform" name="junit-platform-commons" version="1.10.2">
<artifact name="junit-platform-commons-1.10.2.jar">
<sha256 value="b56a5ec000a479df4973b18bba24c98fe0db8faa14c8907d3ef451d8c71fd8ae" origin="Generated by Gradle"/>
</artifact>
<artifact name="junit-platform-commons-1.10.2.module">
<sha256 value="1e81421a62f872bca4d20220b39ea19e27b135f36b7b781704f92fad54319618" origin="Generated by Gradle"/>
</artifact>
</component>
<component group="org.junit.platform" name="junit-platform-commons" version="1.7.0">
<artifact name="junit-platform-commons-1.7.0.jar">
<sha256 value="5330ee87cc7586e6e25175a34e9251624ff12ff525269d3415d0b4ca519b6fea" origin="Generated by Gradle"/>
@ -2625,6 +3270,14 @@
<sha256 value="6ba4c84613e5b89e668ee6a89971f0d90d0e1b81721b8b5fe0c80058f0ceb9ee" origin="Generated by Gradle"/>
</artifact>
</component>
<component group="org.junit.platform" name="junit-platform-engine" version="1.10.2">
<artifact name="junit-platform-engine-1.10.2.jar">
<sha256 value="905cba9b4998ccc29d1239085a7fb1fe0e28024d7526152356d810edec0a49a3" origin="Generated by Gradle"/>
</artifact>
<artifact name="junit-platform-engine-1.10.2.module">
<sha256 value="e1d1badcfedc27244541e0be5d5e84b72a2270d7af61686b26f11cfc4770da42" origin="Generated by Gradle"/>
</artifact>
</component>
<component group="org.junit.platform" name="junit-platform-engine" version="1.7.0">
<artifact name="junit-platform-engine-1.7.0.jar">
<sha256 value="75f21a20dc594afdc875736725b408cec6d0344874d29f34b2dd3075500236f2" origin="Generated by Gradle"/>
@ -2756,6 +3409,14 @@
<sha256 value="a96e671816c1ff8803bdec74c9241f025bdfb277da5d2b4ee02266405936f994" origin="Generated by Gradle"/>
</artifact>
</component>
<component group="org.opentest4j" name="opentest4j" version="1.3.0">
<artifact name="opentest4j-1.3.0.jar">
<sha256 value="48e2df636cab6563ced64dcdff8abb2355627cb236ef0bf37598682ddf742f1b" origin="Generated by Gradle"/>
</artifact>
<artifact name="opentest4j-1.3.0.module">
<sha256 value="48bf1d6c8b5dc94f74652bd17900f654deb714350248cf5e8fca27b9090c8e0d" origin="Generated by Gradle"/>
</artifact>
</component>
<component group="org.ow2" name="ow2" version="1.5">
<artifact name="ow2-1.5.pom">
<sha256 value="0f8a1b116e760b8fe6389c51b84e4b07a70fc11082d4f936e453b583dd50b43b" origin="Generated by Gradle"/>
@ -2890,5 +3551,21 @@
<sha256 value="4a139306cbe0aa3765bd9fd837a71253a911a9c4e55c50e062a4bd6843ee19a1" origin="Generated by Gradle"/>
</artifact>
</component>
<component group="org.yaml" name="snakeyaml" version="1.30">
<artifact name="snakeyaml-1.30.jar">
<sha256 value="f43a4e40a946b8cdfd0321bc1c9a839bc3f119c57e4ca84fb87c367f51c8b2b3" origin="Generated by Gradle"/>
</artifact>
<artifact name="snakeyaml-1.30.pom">
<sha256 value="d3e5fdff90ec58d37fd2b696230f3456f0d8f8e1d5e9ee911b19e6904ae0ebfe" origin="Generated by Gradle"/>
</artifact>
</component>
<component group="org.yaml" name="snakeyaml" version="2.2">
<artifact name="snakeyaml-2.2.jar">
<sha256 value="1467931448a0817696ae2805b7b8b20bfb082652bf9c4efaed528930dc49389b" origin="Generated by Gradle"/>
</artifact>
<artifact name="snakeyaml-2.2.pom">
<sha256 value="e982eadc788c69cf2e4de50a9f632b182c31dba50612830d348fc4b4ba8dd7d6" origin="Generated by Gradle"/>
</artifact>
</component>
</components>
</verification-metadata>

22
restapi/README.md Normal file
View File

@ -0,0 +1,22 @@
# Rest API application
The Rest API application provides access to Bisq network data as well as Bisq DAO data.
It is used for Bisq 2 to request data about the DAO state as well as account age and account witness data for reputation use cases.
Program arguments to run 'RestApiMain' with Bitcoin Regtest and localhost mode:
```
--baseCurrencyNetwork=BTC_REGTEST
--useDevPrivilegeKeys=true
--useLocalhostForP2P=true
--appName=[your app name]
--fullDaoNode=true
--rpcUser=[Bitcoin rpc username]
--rpcPassword=[Bitcoin rpc password]
--rpcPort=18443
--rpcBlockNotificationPort=[port used in blocknotify]
```
To run 'RestApiMain' you need to have Bitcoin node running and have 'blocknotify' in the `bitcoin.conf` set up.

34
restapi/build.gradle Normal file
View File

@ -0,0 +1,34 @@
plugins {
id 'bisq.application'
id 'bisq.gradle.app_start_plugin.AppStartPlugin'
}
mainClassName = 'bisq.restapi.RestApiMain'
dependencies {
implementation project(':common')
implementation project(':p2p')
implementation project(':core')
annotationProcessor libs.lombok
compileOnly libs.lombok
implementation libs.slf4j.api
implementation(libs.google.guice) {
exclude(module: 'guava')
}
implementation libs.google.guava
implementation libs.google.guice
implementation libs.glassfish.jaxb
implementation libs.bundles.jersey.libs
implementation libs.swagger
implementation libs.logback.core
implementation libs.logback.classic
compileOnly libs.lombok
annotationProcessor libs.lombok
implementation libs.slf4j.api
testAnnotationProcessor libs.lombok
testCompileOnly libs.lombok
}

View File

@ -0,0 +1,218 @@
/*
* This file is part of Bisq.
*
* Bisq is free software: you can redistribute it and/or modify it
* under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or (at
* your option) any later version.
*
* Bisq is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
* License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with Bisq. If not, see <http://www.gnu.org/licenses/>.
*/
package bisq.daonode;
import bisq.core.account.witness.AccountAgeWitnessService;
import bisq.core.app.TorSetup;
import bisq.core.app.misc.AppSetupWithP2PAndDAO;
import bisq.core.app.misc.ExecutableForAppWithP2p;
import bisq.core.app.misc.ModuleForAppWithP2p;
import bisq.core.dao.SignVerifyService;
import bisq.core.dao.governance.bond.reputation.BondedReputationRepository;
import bisq.core.dao.governance.bond.role.BondedRolesRepository;
import bisq.core.dao.state.DaoStateService;
import bisq.core.dao.state.DaoStateSnapshotService;
import bisq.core.user.Cookie;
import bisq.core.user.CookieKey;
import bisq.core.user.Preferences;
import bisq.core.user.User;
import bisq.network.p2p.P2PService;
import bisq.network.p2p.P2PServiceListener;
import bisq.network.p2p.peers.PeerManager;
import bisq.common.Timer;
import bisq.common.UserThread;
import bisq.common.app.AppModule;
import bisq.common.app.Version;
import bisq.common.config.BaseCurrencyNetwork;
import bisq.common.config.Config;
import bisq.common.handlers.ResultHandler;
import com.google.inject.Key;
import com.google.inject.name.Names;
import lombok.Getter;
import lombok.extern.slf4j.Slf4j;
//todo not sure if the restart handling from seed nodes is required
@Slf4j
public class RestApi extends ExecutableForAppWithP2p {
private static final long CHECK_CONNECTION_LOSS_SEC = 30;
private Timer checkConnectionLossTime;
@Getter
private DaoStateService daoStateService;
@Getter
private BondedReputationRepository bondedReputationRepository;
@Getter
private AccountAgeWitnessService accountAgeWitnessService;
@Getter
private BondedRolesRepository bondedRolesRepository;
@Getter
private SignVerifyService signVerifyService;
public RestApi() {
super("Bisq Data Node", "bisq-data-node", "bisq_data_node", Version.VERSION);
}
public Config getConfig() {
return config;
}
@Override
protected void doExecute() {
super.doExecute();
checkMemory(config, this);
}
@Override
protected void launchApplication() {
UserThread.execute(() -> {
try {
onApplicationLaunched();
} catch (Exception e) {
e.printStackTrace();
}
});
}
///////////////////////////////////////////////////////////////////////////////////////////
// We continue with a series of synchronous execution tasks
///////////////////////////////////////////////////////////////////////////////////////////
@Override
protected AppModule getModule() {
return new ModuleForAppWithP2p(config);
}
@Override
protected void applyInjector() {
super.applyInjector();
injector.getInstance(DaoStateSnapshotService.class).setDaoRequiresRestartHandler(this::gracefulShutDown);
}
@Override
protected void startApplication() {
super.startApplication();
Cookie cookie = injector.getInstance(User.class).getCookie();
cookie.getAsOptionalBoolean(CookieKey.CLEAN_TOR_DIR_AT_RESTART).ifPresent(wasCleanTorDirSet -> {
if (wasCleanTorDirSet) {
injector.getInstance(TorSetup.class).cleanupTorFiles(() -> {
log.info("Tor directory reset");
cookie.remove(CookieKey.CLEAN_TOR_DIR_AT_RESTART);
}, log::error);
}
});
injector.getInstance(Preferences.class).setUseFullModeDaoMonitor(false);
injector.getInstance(AppSetupWithP2PAndDAO.class).start();
daoStateService = injector.getInstance(DaoStateService.class);
accountAgeWitnessService = injector.getInstance(AccountAgeWitnessService.class);
bondedReputationRepository = injector.getInstance(BondedReputationRepository.class);
bondedRolesRepository = injector.getInstance(BondedRolesRepository.class);
signVerifyService = injector.getInstance(SignVerifyService.class);
injector.getInstance(P2PService.class).addP2PServiceListener(new P2PServiceListener() {
@Override
public void onDataReceived() {
// Do nothing
}
@Override
public void onNoSeedNodeAvailable() {
// Do nothing
}
@Override
public void onNoPeersAvailable() {
// Do nothing
}
@Override
public void onUpdatedDataReceived() {
// Do nothing
}
@Override
public void onTorNodeReady() {
// Do nothing
}
@Override
public void onHiddenServicePublished() {
boolean preventPeriodicShutdownAtSeedNode = injector.getInstance(Key.get(boolean.class,
Names.named(Config.PREVENT_PERIODIC_SHUTDOWN_AT_SEED_NODE)));
if (!preventPeriodicShutdownAtSeedNode) {
startShutDownInterval(RestApi.this);
}
UserThread.runAfter(() -> setupConnectionLossCheck(), 60);
accountAgeWitnessService.onAllServicesInitialized();
}
@Override
public void onSetupFailed(Throwable throwable) {
// Do nothing
}
@Override
public void onRequestCustomBridges() {
// Do nothing
}
});
}
private void setupConnectionLossCheck() {
// For dev testing (usually on BTC_REGTEST) we don't want to get the seed shut
// down as it is normal that the seed is the only actively running node.
if (Config.baseCurrencyNetwork() == BaseCurrencyNetwork.BTC_REGTEST) {
return;
}
if (checkConnectionLossTime != null) {
return;
}
checkConnectionLossTime = UserThread.runPeriodically(() -> {
if (injector.getInstance(PeerManager.class).getNumAllConnectionsLostEvents() > 1) {
// We set a flag to clear tor cache files at re-start. We cannot clear it now as Tor is used and
// that can cause problems.
injector.getInstance(User.class).getCookie().putAsBoolean(CookieKey.CLEAN_TOR_DIR_AT_RESTART, true);
shutDown(this);
}
}, CHECK_CONNECTION_LOSS_SEC);
}
public void gracefulShutDown() {
gracefulShutDown(() -> {
});
}
@Override
public void gracefulShutDown(ResultHandler resultHandler) {
super.gracefulShutDown(resultHandler);
}
}

View File

@ -0,0 +1,129 @@
/*
* This file is part of Bisq.
*
* Bisq is free software: you can redistribute it and/or modify it
* under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or (at
* your option) any later version.
*
* Bisq is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
* License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with Bisq. If not, see <http://www.gnu.org/licenses/>.
*/
package bisq.daonode;
import bisq.common.config.Config;
import java.net.URI;
import java.util.function.Consumer;
import lombok.Getter;
import lombok.extern.slf4j.Slf4j;
import bisq.daonode.endpoints.AccountAgeApi;
import bisq.daonode.endpoints.BondedReputationApi;
import bisq.daonode.endpoints.BondedRoleVerificationApi;
import bisq.daonode.endpoints.ProofOfBurnApi;
import bisq.daonode.endpoints.SignedWitnessApi;
import bisq.daonode.error.CustomExceptionMapper;
import bisq.daonode.error.StatusException;
import bisq.daonode.swagger.StaticFileHandler;
import bisq.daonode.swagger.SwaggerResolution;
import com.sun.net.httpserver.HttpServer;
import org.glassfish.jersey.jdkhttp.JdkHttpServerFactory;
import org.glassfish.jersey.server.ResourceConfig;
/**
* Application to start and config the rest service.
* This creates a rest service for clients to connect and for users to browse the documentation.
* <p>
* Swagger doc are available at <a href="http://localhost:8082/doc/v1/index.html">REST API documentation</a>
*/
@Slf4j
public class RestApiMain extends ResourceConfig {
@Getter
private static String baseUrl;
public static void main(String[] args) throws Exception {
RestApiMain daoNodeApplication = new RestApiMain();
daoNodeApplication.start(args, config -> {
daoNodeApplication
.register(CustomExceptionMapper.class)
.register(StatusException.StatusExceptionMapper.class)
.register(ProofOfBurnApi.class)
.register(BondedReputationApi.class)
.register(BondedRoleVerificationApi.class)
.register(AccountAgeApi.class)
.register(SignedWitnessApi.class)
.register(SwaggerResolution.class);
daoNodeApplication.startServer(config.daoNodeApiUrl, config.daoNodeApiPort);
});
}
@Getter
private final RestApi restApi;
private HttpServer httpServer;
public RestApiMain() {
restApi = new RestApi();
}
private void start(String[] args, Consumer<Config> configConsumer) {
new Thread(() -> {
restApi.execute(args);
configConsumer.accept(restApi.getConfig());
try {
// Keep running
Thread.currentThread().setName("daoNodeThread");
Thread.currentThread().join();
} catch (InterruptedException e) {
log.error("daoNodeThread interrupted", e);
shutDown();
}
}).start();
}
private void startServer(String url, int port) {
baseUrl = url + ":" + port + "/api/v1";
try {
httpServer = JdkHttpServerFactory.createHttpServer(URI.create(baseUrl), this);
httpServer.createContext("/doc", new StaticFileHandler("/doc/v1/"));
Runtime.getRuntime().addShutdownHook(new Thread(this::shutDown));
log.info("Server started at {}.", baseUrl);
} catch (Exception e1) {
log.error("Exception at startServer:", e1);
}
// block and wait shut down signal, like CTRL+C
try {
Thread.currentThread().setName("serverThread");
Thread.currentThread().join();
} catch (InterruptedException e) {
log.error("serverThread interrupted", e);
System.exit(1);
}
shutDown();
}
private void shutDown() {
stopServer();
restApi.gracefulShutDown();
}
private void stopServer() {
if (httpServer != null) {
httpServer.stop(1);
}
}
}

View File

@ -0,0 +1,48 @@
/*
* This file is part of Bisq.
*
* Bisq is free software: you can redistribute it and/or modify it
* under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or (at
* your option) any later version.
*
* Bisq is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
* License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with Bisq. If not, see <http://www.gnu.org/licenses/>.
*/
package bisq.daonode.dto;
import lombok.Getter;
import lombok.extern.slf4j.Slf4j;
import io.swagger.v3.oas.annotations.media.Schema;
/**
* Minimal data required for Bisq 2 bonded reputation use case.
* Need to be in sync with the Bisq 2 BondedReputationDto class.
*/
@Getter
@Slf4j
@Schema(title = "BondedReputation")
public class BondedReputationDto {
private final long amount;
private final long time;
private final String hash;
private final int blockHeight;
private final int lockTime;
public BondedReputationDto(long amount, long time, String hash, int blockHeight, int lockTime) {
this.amount = amount;
this.time = time;
this.hash = hash;
this.blockHeight = blockHeight;
this.lockTime = lockTime;
}
}

View File

@ -0,0 +1,45 @@
/*
* This file is part of Bisq.
*
* Bisq is free software: you can redistribute it and/or modify it
* under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or (at
* your option) any later version.
*
* Bisq is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
* License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with Bisq. If not, see <http://www.gnu.org/licenses/>.
*/
package bisq.daonode.dto;
import lombok.Getter;
import javax.annotation.Nullable;
import io.swagger.v3.oas.annotations.media.Schema;
/**
* Minimal data required for Bisq 2 bonded roles use case.
* Need to be in sync with the Bisq 2 BondedRoleDto class.
*/
@Getter
@Schema(title = "BondedRoleVerification")
public class BondedRoleVerificationDto {
@Nullable
private final String errorMessage;
public BondedRoleVerificationDto() {
errorMessage = null;
}
public BondedRoleVerificationDto(String errorMessage) {
this.errorMessage = errorMessage;
}
}

View File

@ -0,0 +1,44 @@
/*
* This file is part of Bisq.
*
* Bisq is free software: you can redistribute it and/or modify it
* under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or (at
* your option) any later version.
*
* Bisq is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
* License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with Bisq. If not, see <http://www.gnu.org/licenses/>.
*/
package bisq.daonode.dto;
import lombok.Getter;
import io.swagger.v3.oas.annotations.media.Schema;
/**
* Minimal data required for Bisq 2 proof of burn use case.
* Need to be in sync with the Bisq 2 ProofOfBurnDto class.
*/
@Getter
@Schema(title = "ProofOfBurn")
public class ProofOfBurnDto {
private final long amount;
private final long time;
private final String hash;
private final int blockHeight;
public ProofOfBurnDto(long amount, long time, String hash, int blockHeight) {
this.amount = amount;
this.time = time;
this.hash = hash;
this.blockHeight = blockHeight;
}
}

View File

@ -0,0 +1,76 @@
/*
* This file is part of Bisq.
*
* Bisq is free software: you can redistribute it and/or modify it
* under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or (at
* your option) any later version.
*
* Bisq is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
* License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with Bisq. If not, see <http://www.gnu.org/licenses/>.
*/
package bisq.daonode.endpoints;
import bisq.core.account.witness.AccountAgeWitness;
import lombok.extern.slf4j.Slf4j;
import static com.google.common.base.Preconditions.checkNotNull;
import bisq.daonode.RestApi;
import bisq.daonode.RestApiMain;
import bisq.daonode.dto.ProofOfBurnDto;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.media.Content;
import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.ws.rs.GET;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.PathParam;
import jakarta.ws.rs.Produces;
import jakarta.ws.rs.core.Application;
import jakarta.ws.rs.core.Context;
import jakarta.ws.rs.core.MediaType;
/**
* Endpoint for getting the account age date from a given hash as hex string.
* Used for reputation system in Bisq 2.
* <a href="http://localhost:8082/api/v1/account-age/get-date/dd75a7175c7c83fe9a4729e36b85f5fbc44e29ae">Request with hash</a>
*/
@Slf4j
@Path("/account-age")
@Produces(MediaType.TEXT_PLAIN)
@Tag(name = "Account age API")
public class AccountAgeApi {
private static final String DESC_HASH = "The hash of the account age witness as hex string";
private final RestApi restApi;
public AccountAgeApi(@Context Application application) {
restApi = ((RestApiMain) application).getRestApi();
}
@Operation(description = "Request the account age date")
@ApiResponse(responseCode = "200", description = "The account age date",
content = {@Content(mediaType = MediaType.TEXT_PLAIN,
schema = @Schema(allOf = ProofOfBurnDto.class))}
)
@GET
@Path("get-date/{hash}")
public Long getDate(@Parameter(description = DESC_HASH)
@PathParam("hash")
String hash) {
return checkNotNull(restApi.getAccountAgeWitnessService()).getWitnessByHashAsHex(hash)
.map(AccountAgeWitness::getDate)
.orElse(-1L);
}
}

View File

@ -0,0 +1,106 @@
/*
* This file is part of Bisq.
*
* Bisq is free software: you can redistribute it and/or modify it
* under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or (at
* your option) any later version.
*
* Bisq is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
* License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with Bisq. If not, see <http://www.gnu.org/licenses/>.
*/
package bisq.daonode.endpoints;
import bisq.core.dao.governance.bond.reputation.BondedReputationRepository;
import bisq.core.dao.state.DaoStateService;
import bisq.core.dao.state.model.blockchain.Tx;
import bisq.common.util.Hex;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.stream.Collectors;
import lombok.extern.slf4j.Slf4j;
import bisq.daonode.RestApi;
import bisq.daonode.RestApiMain;
import bisq.daonode.dto.BondedReputationDto;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.media.Content;
import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.ws.rs.GET;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.PathParam;
import jakarta.ws.rs.Produces;
import jakarta.ws.rs.core.Application;
import jakarta.ws.rs.core.Context;
import jakarta.ws.rs.core.MediaType;
/**
* Endpoint for getting the bonded reputation data from a given block height.
* Used for reputation system in Bisq 2.
* <a href="http://localhost:8082/api/v1/bonded-reputation/get-bonded-reputation/0">Request with block height 0</a>
*/
@Slf4j
@Path("/bonded-reputation")
@Produces(MediaType.APPLICATION_JSON)
@Tag(name = "Bonded reputation API")
public class BondedReputationApi {
private static final String DESC_BLOCK_HEIGHT = "The block height from which we request the bonded reputation data";
private final BondedReputationRepository bondedReputationRepository;
private final DaoStateService daoStateService;
public BondedReputationApi(@Context Application application) {
RestApi restApi = ((RestApiMain) application).getRestApi();
daoStateService = restApi.getDaoStateService();
bondedReputationRepository = restApi.getBondedReputationRepository();
}
@Operation(description = "Request the bonded reputation data")
@ApiResponse(responseCode = "200", description = "The bonded reputation data",
content = {@Content(mediaType = MediaType.APPLICATION_JSON,
schema = @Schema(allOf = BondedReputationDto.class))}
)
@GET
@Path("get-bonded-reputation/{block-height}")
public List<BondedReputationDto> getBondedReputation(@Parameter(description = DESC_BLOCK_HEIGHT)
@PathParam("block-height")
int fromBlockHeight) {
// We only consider lock time with at least 50 000 blocks as valid
return bondedReputationRepository.getActiveBonds().stream()
.filter(bondedReputation -> bondedReputation.getLockTime() >= 50_000)
.map(bondedReputation -> {
Optional<Tx> optionalTx = daoStateService.getTx(bondedReputation.getLockupTxId());
if (optionalTx.isEmpty()) {
return null;
}
Tx tx = optionalTx.get();
int blockHeight = tx.getBlockHeight();
if (blockHeight >= fromBlockHeight) {
return new BondedReputationDto(bondedReputation.getAmount(),
tx.getTime(),
Hex.encode(bondedReputation.getBondedAsset().getHash()),
blockHeight,
bondedReputation.getLockTime()
);
} else {
return null;
}
})
.filter(Objects::nonNull)
.collect(Collectors.toList());
}
}

View File

@ -0,0 +1,107 @@
/*
* This file is part of Bisq.
*
* Bisq is free software: you can redistribute it and/or modify it
* under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or (at
* your option) any later version.
*
* Bisq is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
* License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with Bisq. If not, see <http://www.gnu.org/licenses/>.
*/
package bisq.daonode.endpoints;
import bisq.core.dao.SignVerifyService;
import bisq.core.dao.governance.bond.BondState;
import bisq.core.dao.governance.bond.role.BondedRolesRepository;
import bisq.core.dao.state.DaoStateService;
import bisq.common.util.Base64;
import bisq.common.util.Hex;
import java.security.SignatureException;
import lombok.extern.slf4j.Slf4j;
import bisq.daonode.RestApi;
import bisq.daonode.RestApiMain;
import bisq.daonode.dto.BondedRoleVerificationDto;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.media.Content;
import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.ws.rs.GET;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.PathParam;
import jakarta.ws.rs.Produces;
import jakarta.ws.rs.core.Application;
import jakarta.ws.rs.core.Context;
import jakarta.ws.rs.core.MediaType;
/**
* Endpoint for getting the bonded role verification for the given parameters.
* Used for bonded roles in Bisq 2.
* <a href="http://localhost:8082/api/v1/bonded-roles/get-bonded-role-verification">Request the verification of a bonded role with the provided parameters</a>
*/
@Slf4j
@Path("/bonded-role-verification")
@Produces(MediaType.APPLICATION_JSON)
@Tag(name = "Bonded role API")
public class BondedRoleVerificationApi {
private final DaoStateService daoStateService;
private final BondedRolesRepository bondedRolesRepository;
private final SignVerifyService signVerifyService;
public BondedRoleVerificationApi(@Context Application application) {
RestApi restApi = ((RestApiMain) application).getRestApi();
daoStateService = restApi.getDaoStateService();
bondedRolesRepository = restApi.getBondedRolesRepository();
signVerifyService = restApi.getSignVerifyService();
}
@Operation(description = "Request the verification of a bonded role with the provided parameters")
@ApiResponse(responseCode = "200", description = "A BondedRoleVerification result object",
content = {@Content(mediaType = MediaType.APPLICATION_JSON,
schema = @Schema(allOf = BondedRoleVerificationDto.class))}
)
@GET
@Path("get-bonded-role-verification/{bond-user-name}/{role-type}/{profile-id}/{signature}")
public BondedRoleVerificationDto getBondedRoleVerification(@PathParam("bond-user-name") String bondUserName,
@PathParam("role-type") String roleType,
@PathParam("profile-id") String profileId,
@PathParam("signature") String signature) {
log.info("Received request for verifying a bonded role. bondUserName={}, roleType={}, profileId={}, signature={}",
bondUserName, roleType, profileId, signature);
String signatureBase64 = Base64.encode(Hex.decode(signature));
return bondedRolesRepository.getAcceptedBonds().stream()
.filter(bondedRole -> bondedRole.getBondedAsset().getBondedRoleType().name().equals(roleType))
.filter(bondedRole -> bondedRole.getBondedAsset().getName().equals(bondUserName))
.filter(bondedRole -> bondedRole.getBondState() == BondState.LOCKUP_TX_CONFIRMED)
.flatMap(bondedRole -> daoStateService.getTx(bondedRole.getLockupTxId()).stream())
.map(tx -> tx.getTxInputs().get(0))
.map(txInput -> {
try {
signVerifyService.verify(profileId, txInput.getPubKey(), signatureBase64);
log.info("Successfully verified bonded role");
return new BondedRoleVerificationDto();
} catch (SignatureException e) {
return new BondedRoleVerificationDto("Signature verification failed.");
}
})
.findAny()
.orElseGet(() -> {
String errorMessage = "Did not find a bonded role matching the parameters";
log.warn(errorMessage);
return new BondedRoleVerificationDto(errorMessage);
});
}
}

View File

@ -0,0 +1,85 @@
/*
* This file is part of Bisq.
*
* Bisq is free software: you can redistribute it and/or modify it
* under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or (at
* your option) any later version.
*
* Bisq is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
* License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with Bisq. If not, see <http://www.gnu.org/licenses/>.
*/
package bisq.daonode.endpoints;
import bisq.core.dao.governance.proofofburn.ProofOfBurnService;
import bisq.common.util.Hex;
import java.util.List;
import java.util.stream.Collectors;
import lombok.extern.slf4j.Slf4j;
import static com.google.common.base.Preconditions.checkNotNull;
import bisq.daonode.RestApi;
import bisq.daonode.RestApiMain;
import bisq.daonode.dto.ProofOfBurnDto;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.media.Content;
import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.ws.rs.GET;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.PathParam;
import jakarta.ws.rs.Produces;
import jakarta.ws.rs.core.Application;
import jakarta.ws.rs.core.Context;
import jakarta.ws.rs.core.MediaType;
/**
* Endpoint for getting the proof of burn data from a given block height.
* Used for reputation system in Bisq 2.
* <a href="http://localhost:8082/api/v1/proof-of-burn/get-proof-of-burn/0">Request with block height 0</a>
*/
@Slf4j
@Path("/proof-of-burn")
@Produces(MediaType.APPLICATION_JSON)
@Tag(name = "Proof of burn API")
public class ProofOfBurnApi {
private static final String DESC_BLOCK_HEIGHT = "The block height from which we request the proof of burn data";
private final RestApi restApi;
public ProofOfBurnApi(@Context Application application) {
restApi = ((RestApiMain) application).getRestApi();
}
@Operation(description = "Request the proof of burn data")
@ApiResponse(responseCode = "200", description = "The proof of burn data",
content = {@Content(mediaType = MediaType.APPLICATION_JSON,
schema = @Schema(allOf = ProofOfBurnDto.class))}
)
@GET
@Path("get-proof-of-burn/{block-height}")
public List<ProofOfBurnDto> getProofOfBurn(@Parameter(description = DESC_BLOCK_HEIGHT)
@PathParam("block-height")
int fromBlockHeight) {
return checkNotNull(restApi.getDaoStateService()).getProofOfBurnTxs().stream()
.filter(tx -> tx.getBlockHeight() >= fromBlockHeight)
.map(tx -> new ProofOfBurnDto(tx.getBurntBsq(),
tx.getTime(),
Hex.encode(ProofOfBurnService.getHashFromOpReturnData(tx)),
tx.getBlockHeight()))
.collect(Collectors.toList());
}
}

View File

@ -0,0 +1,77 @@
/*
* This file is part of Bisq.
*
* Bisq is free software: you can redistribute it and/or modify it
* under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or (at
* your option) any later version.
*
* Bisq is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
* License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with Bisq. If not, see <http://www.gnu.org/licenses/>.
*/
package bisq.daonode.endpoints;
import bisq.core.account.witness.AccountAgeWitnessService;
import lombok.extern.slf4j.Slf4j;
import static com.google.common.base.Preconditions.checkNotNull;
import bisq.daonode.RestApi;
import bisq.daonode.RestApiMain;
import bisq.daonode.dto.ProofOfBurnDto;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.media.Content;
import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.ws.rs.GET;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.PathParam;
import jakarta.ws.rs.Produces;
import jakarta.ws.rs.core.Application;
import jakarta.ws.rs.core.Context;
import jakarta.ws.rs.core.MediaType;
/**
* Endpoint for getting the signed witness date from a given hash as hex string.
* Used for reputation system in Bisq 2.
* <a href="http://localhost:8082/api/v1/signed-witness/get-date/dd75a7175c7c83fe9a4729e36b85f5fbc44e29ae">Request with hash</a>
*/
@Slf4j
@Path("/signed-witness")
@Produces(MediaType.TEXT_PLAIN)
@Tag(name = "Signed witness API")
public class SignedWitnessApi {
private static final String DESC_HASH = "The hash of the signed account age witness as hex string";
private final RestApi restApi;
public SignedWitnessApi(@Context Application application) {
restApi = ((RestApiMain) application).getRestApi();
}
@Operation(description = "Request the signed witness date")
@ApiResponse(responseCode = "200", description = "The signed witness date",
content = {@Content(mediaType = MediaType.TEXT_PLAIN,
schema = @Schema(allOf = ProofOfBurnDto.class))}
)
@GET
@Path("get-date/{hash}")
public Long getDate(@Parameter(description = DESC_HASH)
@PathParam("hash")
String hash) {
AccountAgeWitnessService accountAgeWitnessService = checkNotNull(restApi.getAccountAgeWitnessService());
return accountAgeWitnessService.getWitnessByHashAsHex(hash)
.map(accountAgeWitnessService::getWitnessSignDate)
.orElse(-1L);
}
}

View File

@ -0,0 +1,38 @@
/*
* This file is part of Bisq.
*
* Bisq is free software: you can redistribute it and/or modify it
* under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or (at
* your option) any later version.
*
* Bisq is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
* License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with Bisq. If not, see <http://www.gnu.org/licenses/>.
*/
package bisq.daonode.error;
import lombok.extern.slf4j.Slf4j;
import jakarta.ws.rs.core.Response;
import jakarta.ws.rs.ext.ExceptionMapper;
import jakarta.ws.rs.ext.Provider;
@Slf4j
@Provider
public class CustomExceptionMapper implements ExceptionMapper<Exception> {
@Override
public Response toResponse(Exception exception) {
log.error("Exception: ", exception);
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
.entity(new ErrorMessage(exception.getMessage()))
.build();
}
}

View File

@ -0,0 +1,30 @@
/*
* This file is part of Bisq.
*
* Bisq is free software: you can redistribute it and/or modify it
* under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or (at
* your option) any later version.
*
* Bisq is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
* License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with Bisq. If not, see <http://www.gnu.org/licenses/>.
*/
package bisq.daonode.error;
import lombok.Getter;
@Getter
public class ErrorMessage {
private final String error;
public ErrorMessage(String error) {
this.error = error;
}
}

View File

@ -0,0 +1,55 @@
/*
* This file is part of Bisq.
*
* Bisq is free software: you can redistribute it and/or modify it
* under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or (at
* your option) any later version.
*
* Bisq is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
* License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with Bisq. If not, see <http://www.gnu.org/licenses/>.
*/
package bisq.daonode.error;
import lombok.Getter;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;
import jakarta.ws.rs.core.Response;
import jakarta.ws.rs.ext.ExceptionMapper;
import jakarta.ws.rs.ext.Provider;
@Slf4j
@Provider
public class StatusException extends RuntimeException {
@Getter
@Setter
protected Response.Status httpStatus;
public StatusException() {
}
public StatusException(Response.Status httpStatus, String message) {
super(message);
this.httpStatus = httpStatus;
}
public static class StatusExceptionMapper implements ExceptionMapper<StatusException> {
@Override
public Response toResponse(StatusException exception) {
log.error("Exception: ", exception);
return Response.status(exception.getHttpStatus())
.entity(new ErrorMessage(exception.getMessage()))
.build();
}
}
}

View File

@ -0,0 +1,108 @@
/*
* This file is part of Bisq.
*
* Bisq is free software: you can redistribute it and/or modify it
* under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or (at
* your option) any later version.
*
* Bisq is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
* License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with Bisq. If not, see <http://www.gnu.org/licenses/>.
*/
package bisq.daonode.swagger;
import java.net.URI;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Arrays;
import lombok.Getter;
import lombok.extern.slf4j.Slf4j;
import com.sun.net.httpserver.Headers;
import com.sun.net.httpserver.HttpExchange;
import com.sun.net.httpserver.HttpHandler;
/**
* JDK Server needs handler for serving files, will change in JDK 18
* Currently this is only to serve the swagger-ui content to the client.
* So any call to this handler must begin with api/v1. We keep v1 in case
* we will have incompatible changes in the future.
* This handler is limited to html, css, json and javascript files.
*/
@Slf4j
public class StaticFileHandler implements HttpHandler {
private static final String NOT_FOUND = "404 (Not Found)\n";
public static final String[] VALID_SUFFIX = {".html", ".json", ".css", ".js"};
@Getter
protected final String rootContext;
public StaticFileHandler(String rootContext) {
this.rootContext = rootContext;
}
public void handle(HttpExchange exchange) throws IOException {
URI uri = exchange.getRequestURI();
log.debug("requesting: " + uri.getPath());
String filename = uri.getPath();
if (filename == null || !filename.startsWith(rootContext) ||
Arrays.stream(VALID_SUFFIX).noneMatch(filename::endsWith)) {
respond404(exchange);
return;
}
// resource loading without leading slash
String resourceName = filename.replace("..", "");
if (filename.charAt(0) == '/') {
resourceName = filename.substring(1);
}
// we are using getResourceAsStream to ultimately prevent load from parent directories
try (InputStream resource = getClass().getClassLoader().getResourceAsStream(resourceName)) {
if (resource == null) {
respond404(exchange);
return;
}
log.debug("sending: " + resourceName);
// Object exists and is a file: accept with response code 200.
String mime = "text/html";
if (resourceName.endsWith(".js")) mime = "application/javascript";
if (resourceName.endsWith(".json")) mime = "application/json";
if (resourceName.endsWith(".css")) mime = "text/css";
if (resourceName.endsWith(".png")) mime = "image/png";
Headers headers = exchange.getResponseHeaders();
headers.set("Content-Type", mime);
headers.add("Cache-Control", "max-age=3600"); // cache static content on browser for 3600 seconds
exchange.sendResponseHeaders(200, 0);
try (OutputStream outputStream = exchange.getResponseBody()) {
byte[] buffer = new byte[0x10000];
int count;
while ((count = resource.read(buffer)) >= 0) {
outputStream.write(buffer, 0, count);
}
}
}
}
private void respond404(HttpExchange exchange) throws IOException {
// Object does not exist or is not a file: reject with 404 error.
exchange.sendResponseHeaders(404, NOT_FOUND.length());
try (OutputStream outputStream = exchange.getResponseBody()) {
outputStream.write(NOT_FOUND.getBytes());
}
}
}

View File

@ -0,0 +1,72 @@
/*
* This file is part of Bisq.
*
* Bisq is free software: you can redistribute it and/or modify it
* under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or (at
* your option) any later version.
*
* Bisq is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
* License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with Bisq. If not, see <http://www.gnu.org/licenses/>.
*/
package bisq.daonode.swagger;
import lombok.extern.slf4j.Slf4j;
import bisq.daonode.RestApiMain;
import io.swagger.v3.core.util.Json;
import io.swagger.v3.jaxrs2.Reader;
import io.swagger.v3.oas.annotations.Hidden;
import io.swagger.v3.oas.integration.SwaggerConfiguration;
import io.swagger.v3.oas.models.OpenAPI;
import io.swagger.v3.oas.models.info.Info;
import io.swagger.v3.oas.models.info.License;
import io.swagger.v3.oas.models.servers.Server;
import jakarta.ws.rs.GET;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.Produces;
import jakarta.ws.rs.core.Application;
import jakarta.ws.rs.core.Context;
import jakarta.ws.rs.core.MediaType;
@Slf4j
@Path("openapi.json")
@Produces(MediaType.APPLICATION_JSON)
@Hidden
public class SwaggerResolution {
private static String swaggerJson;
@GET
public String swagIt(@Context Application application) {
if (swaggerJson == null) {
try {
OpenAPI api = new OpenAPI();
Info info = new Info()
.title("Bisq DAO node REST API")
.description("This is the rest API description for the Bisq DAO node, For more Information about Bisq, see https://bisq.network")
.license(new License()
.name("GNU Affero General Public License")
.url("https://github.com/bisq-network/bisq2/blob/main/LICENSE"));
api.info(info).addServersItem(new Server().url(RestApiMain.getBaseUrl()));
SwaggerConfiguration configuration = new SwaggerConfiguration().openAPI(api);
Reader reader = new Reader(configuration);
OpenAPI openAPI = reader.read(application.getClasses());
swaggerJson = Json.pretty(openAPI);
} catch (Exception exception) {
log.error("", exception);
throw new RuntimeException(exception);
}
}
return swaggerJson;
}
}

View File

@ -0,0 +1,15 @@
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<appender name="CONSOLE_APPENDER" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%highlight(%d{MMM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{40}: %msg %xEx%n)</pattern>
</encoder>
</appender>
<root level="TRACE">
<appender-ref ref="CONSOLE_APPENDER"/>
</root>
<!-- <logger name="org.bitcoinj" level="WARN"/>-->
<logger name="org.berndpruenster.netlayer.tor.Tor" level="WARN"/>
</configuration>

Binary file not shown.

After

Width:  |  Height:  |  Size: 665 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 628 B

View File

@ -0,0 +1,16 @@
html {
box-sizing: border-box;
overflow: -moz-scrollbars-vertical;
overflow-y: scroll;
}
*,
*:before,
*:after {
box-sizing: inherit;
}
body {
margin: 0;
background: #fafafa;
}

View File

@ -0,0 +1,19 @@
<!-- HTML for static distribution bundle build -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Swagger UI</title>
<link rel="stylesheet" type="text/css" href="./swagger-ui.css"/>
<link rel="stylesheet" type="text/css" href="index.css"/>
<link rel="icon" type="image/png" href="./favicon-32x32.png" sizes="32x32"/>
<link rel="icon" type="image/png" href="./favicon-16x16.png" sizes="16x16"/>
</head>
<body>
<div id="swagger-ui"></div>
<script src="./swagger-ui-bundle.js" charset="UTF-8"></script>
<script src="./swagger-ui-standalone-preset.js" charset="UTF-8"></script>
<script src="./swagger-initializer.js" charset="UTF-8"></script>
</body>
</html>

View File

@ -0,0 +1,80 @@
<!doctype html>
<html lang="en-US">
<head>
<title>Swagger UI: OAuth2 Redirect</title>
</head>
<body>
<script>
'use strict';
function run () {
var oauth2 = window.opener.swaggerUIRedirectOauth2;
var sentState = oauth2.state;
var redirectUrl = oauth2.redirectUrl;
var isValid, qp, arr;
if (/code|token|error/.test(window.location.hash)) {
qp = window.location.hash.substring(1);
} else {
qp = location.search.substring(1);
}
arr = qp.split("&");
arr.forEach(function (v,i,_arr) { _arr[i] = '"' + v.replace('=', '":"') + '"';});
qp = qp ? JSON.parse('{' + arr.join() + '}',
function (key, value) {
return key === "" ? value : decodeURIComponent(value);
}
) : {};
isValid = qp.state === sentState;
if ((
oauth2.auth.schema.get("flow") === "accessCode" ||
oauth2.auth.schema.get("flow") === "authorizationCode" ||
oauth2.auth.schema.get("flow") === "authorization_code"
) && !oauth2.auth.code) {
if (!isValid) {
oauth2.errCb({
authId: oauth2.auth.name,
source: "auth",
level: "warning",
message: "Authorization may be unsafe, passed state was changed in server Passed state wasn't returned from auth server"
});
}
if (qp.code) {
delete oauth2.state;
oauth2.auth.code = qp.code;
oauth2.callback({auth: oauth2.auth, redirectUrl: redirectUrl});
} else {
let oauthErrorMsg;
if (qp.error) {
oauthErrorMsg = "["+qp.error+"]: " +
(qp.error_description ? qp.error_description+ ". " : "no accessCode received from the server. ") +
(qp.error_uri ? "More info: "+qp.error_uri : "");
}
oauth2.errCb({
authId: oauth2.auth.name,
source: "auth",
level: "error",
message: oauthErrorMsg || "[Authorization failed]: no accessCode received from the server"
});
}
} else {
oauth2.callback({auth: oauth2.auth, token: qp, isValid: isValid, redirectUrl: redirectUrl});
}
window.close();
}
if (document.readyState !== 'loading') {
run();
} else {
document.addEventListener('DOMContentLoaded', function () {
run();
});
}
</script>
</body>
</html>

View File

@ -0,0 +1,20 @@
window.onload = function() {
//<editor-fold desc="Changeable Configuration Block">
// the following lines will be replaced by docker/configurator, when it runs in a docker-container
window.ui = SwaggerUIBundle({
url: "/api/v1/openapi.json",
dom_id: '#swagger-ui',
deepLinking: true,
presets: [
SwaggerUIBundle.presets.apis,
SwaggerUIStandalonePreset
],
plugins: [
SwaggerUIBundle.plugins.DownloadUrl
],
layout: "StandaloneLayout"
});
//</editor-fold>
};

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

View File

@ -29,6 +29,7 @@ include 'daemon'
include 'desktop'
include 'inventory'
include 'persistence'
include 'restapi'
include 'seednode'
include 'statsnode'
include 'apitest'