diff --git a/.gitignore b/.gitignore index 19bd1ac29b..822cf9bdd2 100644 --- a/.gitignore +++ b/.gitignore @@ -86,4 +86,9 @@ android/app/src/main/assets .metro-health-check* # testing -/coverage \ No newline at end of file +/coverage + +.env.local +*.tmp.ci +artifacts +.direnv diff --git a/Makefile b/Makefile index c0636342db..a4a3d85d61 100644 --- a/Makefile +++ b/Makefile @@ -18,3 +18,9 @@ reset-ios: start: yarn start + +tilt-up: + cd dev && GALOY_QUICKSTART_PATH="dev/vendor/galoy-quickstart" tilt up + +tilt-down: + cd dev && GALOY_QUICKSTART_PATH="dev/vendor/galoy-quickstart" tilt down diff --git a/dev/Tiltfile b/dev/Tiltfile new file mode 100644 index 0000000000..4926e49750 --- /dev/null +++ b/dev/Tiltfile @@ -0,0 +1,33 @@ +local_resource( + name='init-onchain', + labels = ['dev-setup'], + cmd='vendor/galoy-quickstart/bin/init-onchain.sh', + resource_deps = [ + "bitcoind", + "bria", + ] +) +local_resource( + name='init-lightning', + labels = ['dev-setup'], + cmd='vendor/galoy-quickstart/bin/init-lightning.sh', + resource_deps = [ + "lnd1", + "lnd-outside-1", + ] +) + +docker_compose('vendor/galoy-quickstart/docker-compose.yml') +galoy_services = ["apollo-router", "galoy", "trigger", "redis", "mongodb", "mongodb-migrate", "price", "price-history", "price-history-migrate", "price-history-pg", "svix", "svix-pg", "stablesats"] +auth_services = ["oathkeeper", "kratos", "kratos-pg", "hydra", "hydra-pg", "hydra-migrate"] +bitcoin_services = ["bitcoind", "bitcoind-signer", "lnd1", "lnd-outside-1", "bria", "bria-pg", "fulcrum"] + +for service in galoy_services: + dc_resource(service, labels = ["galoy"]) +for service in auth_services: + dc_resource(service, labels = ["auth"]) +for service in bitcoin_services: + dc_resource(service, labels = ["bitcoin"]) + +dc_resource('otel-agent', labels = ["otel"]) +dc_resource('quickstart-test', labels = ['quickstart'], auto_init=False) diff --git a/dev/vendir.lock.yml b/dev/vendir.lock.yml new file mode 100644 index 0000000000..e90fe9121e --- /dev/null +++ b/dev/vendir.lock.yml @@ -0,0 +1,11 @@ +apiVersion: vendir.k14s.io/v1alpha1 +directories: +- contents: + - git: + commitTitle: 'feat: adding suggest and approve endpoint for the map (#3937)' + sha: d2f6f35ab4fb67397094684d4b7fc0cf79d47111 + tags: + - 0.20.42 + path: galoy-quickstart + path: vendor +kind: LockConfig diff --git a/dev/vendir.yml b/dev/vendir.yml new file mode 100644 index 0000000000..71b1187bb4 --- /dev/null +++ b/dev/vendir.yml @@ -0,0 +1,19 @@ +apiVersion: vendir.k14s.io/v1alpha1 +kind: Config + +directories: + - path: vendor + contents: + - path: galoy-quickstart + git: + url: https://github.com/GaloyMoney/galoy.git + ref: '0.20.42' + includePaths: + - quickstart/bin/* + - quickstart/dev/**/* + - quickstart/graphql/**/* + - quickstart/galoy/test/**/* + - quickstart/docker-compose.yml + - quickstart/.env.galoy + - quickstart/.gitignore + newRootPath: quickstart diff --git a/dev/vendor/galoy-quickstart/.env.galoy b/dev/vendor/galoy-quickstart/.env.galoy new file mode 100644 index 0000000000..55317b0ffe --- /dev/null +++ b/dev/vendor/galoy-quickstart/.env.galoy @@ -0,0 +1,67 @@ +# .env.ci is interpolated into tmp.env.ci during CI testing after integration-deps have been spun up. +# tmp.env.ci is then passed into integration and bats test containers by setting the environment variable "TMP_ENV_CI=tmp.env.ci". +JEST_TIMEOUT=90000 +NETWORK=regtest +LND1_TLS=LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUNZVENDQWdlZ0F3SUJBZ0lSQU9zZzdYWFR4cnVZYlhkeTY2d3RuN1F3Q2dZSUtvWkl6ajBFQXdJd09ERWYKTUIwR0ExVUVDaE1XYkc1a0lHRjFkRzluWlc1bGNtRjBaV1FnWTJWeWRERVZNQk1HQTFVRUF4TU1PRFl4T1RneApNak5tT0Roak1CNFhEVEl6TURFeE9USXdOREUxTTFvWERUTTBNRGN5TVRJd05ERTFNMW93T0RFZk1CMEdBMVVFCkNoTVdiRzVrSUdGMWRHOW5aVzVsY21GMFpXUWdZMlZ5ZERFVk1CTUdBMVVFQXhNTU9EWXhPVGd4TWpObU9EaGoKTUZrd0V3WUhLb1pJemowQ0FRWUlLb1pJemowREFRY0RRZ0FFM1lieUlKWU1Vcm8zZkl0UFFucysxZ2lpTXI5NQpJUXRmclFDQ2JhOWVtcjI4TENmbk1vYy9VQVFwUlg3QVlvVFRneUdiMFBuZGNUODF5ZVgvYTlPa0RLT0I4VENCCjdqQU9CZ05WSFE4QkFmOEVCQU1DQXFRd0V3WURWUjBsQkF3d0NnWUlLd1lCQlFVSEF3RXdEd1lEVlIwVEFRSC8KQkFVd0F3RUIvekFkQmdOVkhRNEVGZ1FVL1AxRHpJUkRzTEhHMU10d3NrZE5nZ0lub1Mwd2daWUdBMVVkRVFTQgpqakNCaTRJTU9EWXhPVGd4TWpObU9EaGpnZ2xzYjJOaGJHaHZjM1NDRFd4dVpDMXZkWFJ6YVdSbExUR0NEV3h1ClpDMXZkWFJ6YVdSbExUS0NEV3h1WkMxdmRYUnphV1JsTFRPQ0JHeHVaREdDQkd4dVpES0NCSFZ1YVhpQ0NuVnUKYVhod1lXTnJaWFNDQjJKMVptTnZibTZIQkg4QUFBR0hFQUFBQUFBQUFBQUFBQUFBQUFBQUFBR0hCS3dUQUJBdwpDZ1lJS29aSXpqMEVBd0lEU0FBd1JRSWhBSU5DNlJWQ3d6SzFYRnFxeVNLY0Y4QzQ5ZFlSOThjemdLNVdkcmNOCkxYYWlBaUJHYmtWeGhaeHdDaDVLQ1o1Z2M1Q2FsQ0RvaGNxVkdiaHNya0hHTFhpdHN3PT0KLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQo= +TLSOUTSIDE1=LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUNZVENDQWdlZ0F3SUJBZ0lSQU9zZzdYWFR4cnVZYlhkeTY2d3RuN1F3Q2dZSUtvWkl6ajBFQXdJd09ERWYKTUIwR0ExVUVDaE1XYkc1a0lHRjFkRzluWlc1bGNtRjBaV1FnWTJWeWRERVZNQk1HQTFVRUF4TU1PRFl4T1RneApNak5tT0Roak1CNFhEVEl6TURFeE9USXdOREUxTTFvWERUTTBNRGN5TVRJd05ERTFNMW93T0RFZk1CMEdBMVVFCkNoTVdiRzVrSUdGMWRHOW5aVzVsY21GMFpXUWdZMlZ5ZERFVk1CTUdBMVVFQXhNTU9EWXhPVGd4TWpObU9EaGoKTUZrd0V3WUhLb1pJemowQ0FRWUlLb1pJemowREFRY0RRZ0FFM1lieUlKWU1Vcm8zZkl0UFFucysxZ2lpTXI5NQpJUXRmclFDQ2JhOWVtcjI4TENmbk1vYy9VQVFwUlg3QVlvVFRneUdiMFBuZGNUODF5ZVgvYTlPa0RLT0I4VENCCjdqQU9CZ05WSFE4QkFmOEVCQU1DQXFRd0V3WURWUjBsQkF3d0NnWUlLd1lCQlFVSEF3RXdEd1lEVlIwVEFRSC8KQkFVd0F3RUIvekFkQmdOVkhRNEVGZ1FVL1AxRHpJUkRzTEhHMU10d3NrZE5nZ0lub1Mwd2daWUdBMVVkRVFTQgpqakNCaTRJTU9EWXhPVGd4TWpObU9EaGpnZ2xzYjJOaGJHaHZjM1NDRFd4dVpDMXZkWFJ6YVdSbExUR0NEV3h1ClpDMXZkWFJ6YVdSbExUS0NEV3h1WkMxdmRYUnphV1JsTFRPQ0JHeHVaREdDQkd4dVpES0NCSFZ1YVhpQ0NuVnUKYVhod1lXTnJaWFNDQjJKMVptTnZibTZIQkg4QUFBR0hFQUFBQUFBQUFBQUFBQUFBQUFBQUFBR0hCS3dUQUJBdwpDZ1lJS29aSXpqMEVBd0lEU0FBd1JRSWhBSU5DNlJWQ3d6SzFYRnFxeVNLY0Y4QzQ5ZFlSOThjemdLNVdkcmNOCkxYYWlBaUJHYmtWeGhaeHdDaDVLQ1o1Z2M1Q2FsQ0RvaGNxVkdiaHNya0hHTFhpdHN3PT0KLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQo= +TLSOUTSIDE2=LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUNZVENDQWdlZ0F3SUJBZ0lSQU9zZzdYWFR4cnVZYlhkeTY2d3RuN1F3Q2dZSUtvWkl6ajBFQXdJd09ERWYKTUIwR0ExVUVDaE1XYkc1a0lHRjFkRzluWlc1bGNtRjBaV1FnWTJWeWRERVZNQk1HQTFVRUF4TU1PRFl4T1RneApNak5tT0Roak1CNFhEVEl6TURFeE9USXdOREUxTTFvWERUTTBNRGN5TVRJd05ERTFNMW93T0RFZk1CMEdBMVVFCkNoTVdiRzVrSUdGMWRHOW5aVzVsY21GMFpXUWdZMlZ5ZERFVk1CTUdBMVVFQXhNTU9EWXhPVGd4TWpObU9EaGoKTUZrd0V3WUhLb1pJemowQ0FRWUlLb1pJemowREFRY0RRZ0FFM1lieUlKWU1Vcm8zZkl0UFFucysxZ2lpTXI5NQpJUXRmclFDQ2JhOWVtcjI4TENmbk1vYy9VQVFwUlg3QVlvVFRneUdiMFBuZGNUODF5ZVgvYTlPa0RLT0I4VENCCjdqQU9CZ05WSFE4QkFmOEVCQU1DQXFRd0V3WURWUjBsQkF3d0NnWUlLd1lCQlFVSEF3RXdEd1lEVlIwVEFRSC8KQkFVd0F3RUIvekFkQmdOVkhRNEVGZ1FVL1AxRHpJUkRzTEhHMU10d3NrZE5nZ0lub1Mwd2daWUdBMVVkRVFTQgpqakNCaTRJTU9EWXhPVGd4TWpObU9EaGpnZ2xzYjJOaGJHaHZjM1NDRFd4dVpDMXZkWFJ6YVdSbExUR0NEV3h1ClpDMXZkWFJ6YVdSbExUS0NEV3h1WkMxdmRYUnphV1JsTFRPQ0JHeHVaREdDQkd4dVpES0NCSFZ1YVhpQ0NuVnUKYVhod1lXTnJaWFNDQjJKMVptTnZibTZIQkg4QUFBR0hFQUFBQUFBQUFBQUFBQUFBQUFBQUFBR0hCS3dUQUJBdwpDZ1lJS29aSXpqMEVBd0lEU0FBd1JRSWhBSU5DNlJWQ3d6SzFYRnFxeVNLY0Y4QzQ5ZFlSOThjemdLNVdkcmNOCkxYYWlBaUJHYmtWeGhaeHdDaDVLQ1o1Z2M1Q2FsQ0RvaGNxVkdiaHNya0hHTFhpdHN3PT0KLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQo= +LND1_MACAROON=AgEDbG5kAvgBAwoQB1FdhGa9xoewc1LEXmnURRIBMBoWCgdhZGRyZXNzEgRyZWFkEgV3cml0ZRoTCgRpbmZvEgRyZWFkEgV3cml0ZRoXCghpbnZvaWNlcxIEcmVhZBIFd3JpdGUaIQoIbWFjYXJvb24SCGdlbmVyYXRlEgRyZWFkEgV3cml0ZRoWCgdtZXNzYWdlEgRyZWFkEgV3cml0ZRoXCghvZmZjaGFpbhIEcmVhZBIFd3JpdGUaFgoHb25jaGFpbhIEcmVhZBIFd3JpdGUaFAoFcGVlcnMSBHJlYWQSBXdyaXRlGhgKBnNpZ25lchIIZ2VuZXJhdGUSBHJlYWQAAAYgqHDdwGCqx0aQL1/Z3uUfzCpeBhfapGf9s/AZPOVwf6s= +MACAROONOUTSIDE1=AgEDbG5kAvgBAwoQeE+5exgz7/0ExCn7H6AJlBIBMBoWCgdhZGRyZXNzEgRyZWFkEgV3cml0ZRoTCgRpbmZvEgRyZWFkEgV3cml0ZRoXCghpbnZvaWNlcxIEcmVhZBIFd3JpdGUaIQoIbWFjYXJvb24SCGdlbmVyYXRlEgRyZWFkEgV3cml0ZRoWCgdtZXNzYWdlEgRyZWFkEgV3cml0ZRoXCghvZmZjaGFpbhIEcmVhZBIFd3JpdGUaFgoHb25jaGFpbhIEcmVhZBIFd3JpdGUaFAoFcGVlcnMSBHJlYWQSBXdyaXRlGhgKBnNpZ25lchIIZ2VuZXJhdGUSBHJlYWQAAAYgL7pU+cKOt6zGyWTdWWmAJLP1L3cnbOPb4Rd3QtniyyM= +MACAROONOUTSIDE2=AgEDbG5kAvgBAwoQfKO82/iPT2zIwWYPrOXvABIBMBoWCgdhZGRyZXNzEgRyZWFkEgV3cml0ZRoTCgRpbmZvEgRyZWFkEgV3cml0ZRoXCghpbnZvaWNlcxIEcmVhZBIFd3JpdGUaIQoIbWFjYXJvb24SCGdlbmVyYXRlEgRyZWFkEgV3cml0ZRoWCgdtZXNzYWdlEgRyZWFkEgV3cml0ZRoXCghvZmZjaGFpbhIEcmVhZBIFd3JpdGUaFgoHb25jaGFpbhIEcmVhZBIFd3JpdGUaFAoFcGVlcnMSBHJlYWQSBXdyaXRlGhgKBnNpZ25lchIIZ2VuZXJhdGUSBHJlYWQAAAYg2XkV+4Z4inbfXGZivRoY+r7KHNZhgxkCEdKByxbeb/Q= +LND1_PUBKEY=03ca1907342d5d37744cb7038375e1867c24a87564c293157c95b2a9d38dcfb4c2 +BITCOINDPORT=18443 +BITCOINDADDR=bitcoind +BITCOIND_SIGNER_PORT=18443 +BITCOIND_SIGNER_ADDR=bitcoind-signer +BITCOINDRPCPASS=rpcpassword +LND1_DNS=lnd1 +LND1_RPCPORT=10009 +LND1_TYPE=offchain,onchain +LND1_NAME=lnd1 +LNDOUTSIDE1ADDR=lnd-outside-1 +LNDOUTSIDE2ADDR=lnd-outside-2 +MONGODB_CON="mongodb://mongodb:27017/galoy" +REDIS_0_DNS=redis +REDIS_0_PORT=6379 +REDIS_TYPE=standalone +REDIS_MASTER_NAME=mymaster +REDIS_PASSWORD= +BRIA_HOST=bria +BRIA_PORT=2742 +PRICE_HOST=price +PRICE_PORT=50051 +PRICE_HISTORY_HOST=price-history +PRICE_HISTORY_PORT=50052 +OATHKEEPER_DECISION_ENDPOINT=http://oathkeeper:4456 +WEBSOCKET_PORT=4000 +GEETEST_ID=geetest_id +GEETEST_KEY=geetest_key +TWILIO_ACCOUNT_SID=AC_twilio_id +TWILIO_AUTH_TOKEN=AC_twilio_auth_token +TWILIO_VERIFY_SERVICE_ID=VA_twilio_service +COMMITHASH=hash +HELMREVISION=1 +PRICE_SERVER_HOST=stablesats +LND1_LOOP_MACAROON=AgEEbG9vcAJ3AwoQRGymK6/vfF3wwuVmaTj3RhIBMBoMCgRhdXRoEgRyZWFkGg8KBGxvb3ASAmluEgNvdXQaGgoLc3VnZ2VzdGlvbnMSBHJlYWQSBXdyaXRlGhUKBHN3YXASB2V4ZWN1dGUSBHJlYWQaDQoFdGVybXMSBHJlYWQAAAYgAFS/qTZItZ3ZKksQkfXAKFnsb0JS5Ok3Oi5fAgCaE/k= +LND1_LOOP_TLS=LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUNKakNDQWMyZ0F3SUJBZ0lSQU1memVXM0J0UWJaaTdxSjZoQk5vMHN3Q2dZSUtvWkl6ajBFQXdJd09URWcKTUI0R0ExVUVDaE1YYkc5dmNDQmhkWFJ2WjJWdVpYSmhkR1ZrSUdObGNuUXhGVEFUQmdOVkJBTVREREpqWkdRMQpOMlptWlRZeFpEQWVGdzB5TWpBNU1EY3lNVE15TWpSYUZ3MHlNekV4TURJeU1UTXlNalJhTURreElEQWVCZ05WCkJBb1RGMnh2YjNBZ1lYVjBiMmRsYm1WeVlYUmxaQ0JqWlhKME1SVXdFd1lEVlFRREV3d3lZMlJrTlRkbVptVTIKTVdRd1dUQVRCZ2NxaGtqT1BRSUJCZ2dxaGtqT1BRTUJCd05DQUFUcU5qcVFMUGNHSURaSmtHenNlL3d2ZWt0TwpRVlhpaFJ6WmVLay9ZMFlTNDFkejB2TjlQdktaM0ZxTmN2eEN5a1cvZ1dKNWhBdEpCZTdDaTZhWitnR0tvNEcxCk1JR3lNQTRHQTFVZER3RUIvd1FFQXdJQ3BEQVRCZ05WSFNVRUREQUtCZ2dyQmdFRkJRY0RBVEFQQmdOVkhSTUIKQWY4RUJUQURBUUgvTUIwR0ExVWREZ1FXQkJRZHJscHQzM2lLdlZUZWQyVnV4Y25uQVJMeTlEQmJCZ05WSFJFRQpWREJTZ2d3eVkyUmtOVGRtWm1VMk1XU0NDV3h2WTJGc2FHOXpkSUlFZFc1cGVJSUtkVzVwZUhCaFkydGxkSUlIClluVm1ZMjl1Ym9jRWZ3QUFBWWNRQUFBQUFBQUFBQUFBQUFBQUFBQUFBWWNFckJzQUR6QUtCZ2dxaGtqT1BRUUQKQWdOSEFEQkVBaUJYaFI2VmRzSFYrREhhWGRrV2VRZ0pzMlRxT0pXajBwUXI1ZHFLcFViNjlBSWdTeGtYYTZFRQpWVk9CZ0VhNXR5Z3NBcGM2bDBSak5nVGF2SkF6T2dWT2tIWT0KLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQo= +KRATOS_MASTER_USER_PASSWORD=passwordHardtoFindWithNumber123 +KRATOS_CALLBACK_API_KEY=The-Value-of-My-Key +KRATOS_PUBLIC_API=http://kratos:4433 +KRATOS_ADMIN_API=http://kratos:4434 +KRATOS_PG_CON="postgres://dbuser:secret@kratos-pg:5432/default?sslmode=disable" + +OTEL_EXPORTER_OTLP_ENDPOINT=http://otel-agent:4318 +MATTERMOST_WEBHOOK_URL=https://chat.galoy.io/hooks/sometoken +UNSECURE_DEFAULT_LOGIN_CODE=000000 +SVIX_SECRET=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE2OTE2NzIwMTQsImV4cCI6MjAwNzAzMjAxNCwibmJmIjoxNjkxNjcyMDE0LCJpc3MiOiJzdml4LXNlcnZlciIsInN1YiI6Im9yZ18yM3JiOFlkR3FNVDBxSXpwZ0d3ZFhmSGlyTXUifQ.b9s0aWSisNdUNki4edabBEToLNSwjC9-AiJQr4J3y4E +SVIX_ENDPOINT=http://svix:8071 + +BRIA_API_KEY=bria_dev_000000000000000000000 + +UNSECURE_DEFAULT_LOGIN_CODE=000000 +UNSECURE_IP_FROM_REQUEST_OBJECT=true + +HYDRA_PUBLIC_API="http://hydra:4444" +HYDRA_ADMIN_API="http://hydra:4445" + +NOTIFICATIONS_HOST="dummy" diff --git a/dev/vendor/galoy-quickstart/.gitignore b/dev/vendor/galoy-quickstart/.gitignore new file mode 100644 index 0000000000..7a5af7a34b --- /dev/null +++ b/dev/vendor/galoy-quickstart/.gitignore @@ -0,0 +1 @@ +tmp* diff --git a/dev/vendor/galoy-quickstart/bin/bump-galoy-git-ref.sh b/dev/vendor/galoy-quickstart/bin/bump-galoy-git-ref.sh new file mode 100755 index 0000000000..d1bc9e8a19 --- /dev/null +++ b/dev/vendor/galoy-quickstart/bin/bump-galoy-git-ref.sh @@ -0,0 +1,11 @@ +#!/bin/bash + +DIR="$(dirname "$(readlink -f "$BASH_SOURCE")")" + +TMPDIR="" +TMPDIR=$(mktemp -d -t repipe.XXXXXX) +trap "rm -rf ${TMPDIR}" INT TERM QUIT EXIT + +sed "s/^galoy_git_ref:.*/galoy_git_ref: ${1}/" ${DIR}/../vendir/values.yml > ${TMPDIR}/new_values.yml + +mv ${TMPDIR}/new_values.yml ${DIR}/../vendir/values.yml diff --git a/dev/vendor/galoy-quickstart/bin/bump-galoy-image-digest.sh b/dev/vendor/galoy-quickstart/bin/bump-galoy-image-digest.sh new file mode 100755 index 0000000000..36f326b287 --- /dev/null +++ b/dev/vendor/galoy-quickstart/bin/bump-galoy-image-digest.sh @@ -0,0 +1,11 @@ +#!/bin/bash + +DIR="$(dirname "$(readlink -f "$BASH_SOURCE")")" + +TMPDIR="" +TMPDIR=$(mktemp -d -t repipe.XXXXXX) +trap "rm -rf ${TMPDIR}" INT TERM QUIT EXIT + +sed "s/^#@ galoy_${1}_image_digest = \".*\"/#@ galoy_${1}_image_digest = \"${2}\"/" ${DIR}/../docker-compose.tmpl.yml > ${TMPDIR}/docker-compose.tmpl.yml + +mv ${TMPDIR}/docker-compose.tmpl.yml ${DIR}/../docker-compose.tmpl.yml diff --git a/dev/vendor/galoy-quickstart/bin/bump-mongodb-migrate-image-digest.sh b/dev/vendor/galoy-quickstart/bin/bump-mongodb-migrate-image-digest.sh new file mode 100755 index 0000000000..d28aae0eec --- /dev/null +++ b/dev/vendor/galoy-quickstart/bin/bump-mongodb-migrate-image-digest.sh @@ -0,0 +1,11 @@ +#!/bin/bash + +DIR="$(dirname "$(readlink -f "$BASH_SOURCE")")" + +TMPDIR="" +TMPDIR=$(mktemp -d -t repipe.XXXXXX) +trap "rm -rf ${TMPDIR}" INT TERM QUIT EXIT + +sed "s/^#@ mongodb_migrate_image_digest = \".*\"/#@ mongodb_migrate_image_digest = \"${1}\"/" ${DIR}/../docker-compose.tmpl.yml > ${TMPDIR}/docker-compose.tmpl.yml + +mv ${TMPDIR}/docker-compose.tmpl.yml ${DIR}/../docker-compose.tmpl.yml diff --git a/dev/vendor/galoy-quickstart/bin/helpers.sh b/dev/vendor/galoy-quickstart/bin/helpers.sh new file mode 100644 index 0000000000..61dc2a90f6 --- /dev/null +++ b/dev/vendor/galoy-quickstart/bin/helpers.sh @@ -0,0 +1,239 @@ +#!/bin/bash + +set -e + +COMPOSE_PROJECT_NAME="${COMPOSE_PROJECT_NAME:-quickstart}" +# default is oathkeeper endpoint +GALOY_ENDPOINT=${GALOY_ENDPOINT:-localhost:4455} + +if [ -n "$HOST_PROJECT_PATH" ]; then + GALOY_DIR="./vendor/galoy-quickstart" +else + GALOY_DIR="." +fi +export GALOY_DIR + +CACHE_DIR=$GALOY_DIR/tmp/quickstart-cache +mkdir -p $CACHE_DIR + +cache_value() { + echo $2 >${CACHE_DIR}/$1 +} + +read_value() { + cat ${CACHE_DIR}/$1 +} + +bitcoin_cli() { + docker exec "${COMPOSE_PROJECT_NAME}-bitcoind-1" bitcoin-cli $@ +} + +lnd_cli() { + docker exec "${COMPOSE_PROJECT_NAME}-lnd1-1" \ + lncli \ + --macaroonpath /root/.lnd/data/chain/bitcoin/regtest/admin.macaroon \ + --tlscertpath /root/.lnd/tls.cert \ + $@ +} + +lnd_outside_cli() { + docker exec "${COMPOSE_PROJECT_NAME}-lnd-outside-1-1" \ + lncli \ + --macaroonpath /root/.lnd/data/chain/bitcoin/regtest/admin.macaroon \ + --tlscertpath /root/.lnd/tls.cert \ + $@ +} + +init_lnd_channel() { + lnd_cli closeallchannels || true + + local amount="1" + local address="$(lnd_outside_cli newaddress p2wkh | jq -r '.address')" + local local_amount="10000000" + bitcoin_cli sendtoaddress "$address" "$amount" + bitcoin_cli -generate 3 + + # Open balanced channel from lnd1 to lndoutside1 + lnd_local_pubkey="$(lnd_cli getinfo | jq -r '.identity_pubkey')" + lnd_outside_cli connect "${lnd_local_pubkey}@${COMPOSE_PROJECT_NAME}-lnd1-1:9735" || true + for i in {1..10}; do + lnd_outside_cli openchannel \ + --node_key "$lnd_local_pubkey" \ + --local_amt "$local_amount" && break + done + + for i in {1..10}; do + local txid="$(bitcoin_cli getrawmempool | jq -r '.[0]')" + [[ "$txid" != "null" ]] && break + sleep 1 + done + + bitcoin_cli -generate 3 + +} + +bria_cli() { + docker exec "${COMPOSE_PROJECT_NAME}-bria-1" bria $@ +} + +bitcoin_signer_cli() { + docker exec "${COMPOSE_PROJECT_NAME}-bitcoind-signer-1" bitcoin-cli $@ +} + +gql_file() { + echo "$GALOY_DIR/graphql/gql/$1.gql" +} + +gql_query() { + cat "$(gql_file $1)" | tr '\n' ' ' | sed 's/"/\\"/g' +} + +graphql_output() { + echo $output | jq -r "$@" +} + +exec_graphql() { + local token_name=$1 + local query_name=$2 + local variables=${3:-"{}"} + + if [[ ${token_name} == "anon" ]]; then + AUTH_HEADER="" + else + AUTH_HEADER="Authorization: Bearer $(read_value ${token_name})" + fi + + gql_route="graphql" + + output=$(curl -s \ + -X POST \ + ${AUTH_HEADER:+ -H "$AUTH_HEADER"} \ + -H "Content-Type: application/json" \ + -d "{\"query\": \"$(gql_query $query_name)\", \"variables\": $variables}" \ + "${GALOY_ENDPOINT}/${gql_route}") +} + +login_user() { + local token_name=$1 + local phone=$2 + local code=$3 + + local variables=$( + jq -n \ + --arg phone "$phone" \ + --arg code "$code" \ + '{input: {phone: $phone, code: $code}}' + ) + exec_graphql 'anon' 'user-login' "$variables" + auth_token="$(graphql_output '.data.userLogin.authToken')" + [[ -n "${auth_token}" && "${auth_token}" != "null" ]] + cache_value "$token_name" "$auth_token" + + exec_graphql "$token_name" 'wallets-for-account' + + account_id="$(graphql_output '.data.me.defaultAccount.id')" + [[ "${account_id}" != "null" ]] + cache_value "$token_name.account_id" "$account_id" + + btc_wallet_id="$(graphql_output '.data.me.defaultAccount.wallets[] | select(.walletCurrency == "BTC") .id')" + [[ "${btc_wallet_id}" != "null" ]] + cache_value "$token_name.btc_wallet_id" "$btc_wallet_id" + + usd_wallet_id="$(graphql_output '.data.me.defaultAccount.wallets[] | select(.walletCurrency == "USD") .id')" + [[ "${usd_wallet_id}" != "null" ]] + cache_value "$token_name.usd_wallet_id" "$usd_wallet_id" +} + +receive_onchain() { + token_name="alice" + btc_wallet_name="$token_name.btc_wallet_id" + amount="0.01" + + variables=$( + jq -n \ + --arg wallet_id "$(read_value $btc_wallet_name)" \ + '{input: {walletId: $wallet_id}}' + ) + + exec_graphql "$token_name" 'on-chain-address-create' "$variables" + address="$(graphql_output '.data.onChainAddressCreate.address')" + + bitcoin_cli sendtoaddress "$address" "$amount" + bitcoin_cli -generate 4 + + variables=$( + jq -n \ + --argjson first "1" \ + '{"first": $first}' + ) + for i in {1..60}; do + exec_graphql "$token_name" 'transactions' "$variables" + + jq_query='.data.me.defaultAccount.transactions.edges[] | select(.node.initiationVia.address == $address) .node' + settled_status=$(echo $output \ + | jq -r --arg address "$address" "$jq_query" \ + | jq -r ".status") + [[ "${settled_status}" = "SUCCESS" ]] && break + sleep 1 + done +} + +receive_lightning() { + token_name="alice" + btc_wallet_name="$token_name.btc_wallet_id" + btc_amount=1000 + + variables=$( + jq -n \ + --arg wallet_id "$(read_value $btc_wallet_name)" \ + --arg amount "$btc_amount" \ + '{input: {walletId: $wallet_id, amount: $amount}}' + ) + exec_graphql "$token_name" 'ln-invoice-create' "$variables" + payment_request="$(echo $invoice | jq -r '.paymentRequest')" + lnd_outside_cli payinvoice -f \ + --pay_req "$payment_request" + + for i in {1..20}; do + jq_query='.data.me.defaultAccount.transactions.edges[] | select(.node.initiationVia.paymentHash == $payment_hash) .node' + echo $output \ + | jq -r --arg payment_hash "$1" "$jq_query" \ + | jq -r ".status" + [[ "${settled_status}" = "SUCCESS" ]] && break + sleep 1 + done +} + +fund_wallet_from_onchain() { + local token_name=$1 + local wallet_id_name="$2" + local amount=$3 + + variables=$( + jq -n \ + --arg wallet_id "$(read_value $wallet_id_name)" \ + '{input: {walletId: $wallet_id}}' + ) + exec_graphql "$token_name" 'on-chain-address-create' "$variables" + address="$(graphql_output '.data.onChainAddressCreate.address')" + [[ "${address}" != "null" ]] + + bitcoin_cli sendtoaddress "$address" "$amount" + bitcoin_cli -generate 5 +} + +initialize_user_from_onchain() { + local token_name="$1" + local phone="$2" + local code="$3" + + local btc_amount_in_btc="1" + + login_user "$token_name" "$phone" "$code" + + fund_wallet_from_onchain \ + "$token_name" \ + "$token_name.btc_wallet_id" \ + "$btc_amount_in_btc" +} + diff --git a/dev/vendor/galoy-quickstart/bin/init-lightning.sh b/dev/vendor/galoy-quickstart/bin/init-lightning.sh new file mode 100755 index 0000000000..fd554620f3 --- /dev/null +++ b/dev/vendor/galoy-quickstart/bin/init-lightning.sh @@ -0,0 +1,15 @@ +#!/bin/bash + +set -e + +COMPOSE_PROJECT_NAME="${COMPOSE_PROJECT_NAME:-quickstart}" + +DIR="$(dirname "$(readlink -f "$BASH_SOURCE")")" +source ${DIR}/helpers.sh + +echo "Running getinfo on lnd..." +lnd_cli getinfo +echo "DONE" +echo "Opening lnd-outside -> lnd channel" +init_lnd_channel +echo "DONE" diff --git a/dev/vendor/galoy-quickstart/bin/init-onchain.sh b/dev/vendor/galoy-quickstart/bin/init-onchain.sh new file mode 100755 index 0000000000..acce29e6f6 --- /dev/null +++ b/dev/vendor/galoy-quickstart/bin/init-onchain.sh @@ -0,0 +1,26 @@ +#!/bin/bash + +set -e + +COMPOSE_PROJECT_NAME="${COMPOSE_PROJECT_NAME:-quickstart}" + +DIR="$(dirname "$(readlink -f "$BASH_SOURCE")")" +source ${DIR}/helpers.sh + +echo "Seeding some regtest blocks..." + +bitcoin_cli createwallet "outside" || true +bitcoin_cli -generate 200 > /dev/null 2>&1 + +bitcoin_signer_cli createwallet "dev" || true +bitcoin_signer_cli -rpcwallet=dev importdescriptors "$(cat $GALOY_DIR/dev/config/bitcoind/bitcoind_signer_descriptors.json)" + +echo "Checking that bria is running..." + +for i in {1..20}; do + bria_cli wallet-balance -w dev-wallet && break + sleep 1 +done +bria_cli wallet-balance -w dev-wallet || exit 1 + +echo "DONE" diff --git a/dev/vendor/galoy-quickstart/bin/quickstart.sh b/dev/vendor/galoy-quickstart/bin/quickstart.sh new file mode 100755 index 0000000000..274b9586cc --- /dev/null +++ b/dev/vendor/galoy-quickstart/bin/quickstart.sh @@ -0,0 +1,61 @@ +#!/bin/bash + +set -e + +COMPOSE_PROJECT_NAME="${COMPOSE_PROJECT_NAME:-quickstart}" + +DIR="$(dirname "$(readlink -f "$BASH_SOURCE")")" +source ${DIR}/helpers.sh + +show_galoy() { +cat << "EOF" + ('-. + ( OO ).-. + ,----. / . --. / ,--. .-'),-----. ,--. ,--. + ' .-./-') | \-. \ | |.-') ( OO' .-. ' \ `.' / + | |_( O- ).-'-' | | | | OO )/ | | | | .-') / + | | .--, \ \| |_.' | | |`-' |\_) | |\| |(OO \ / + (| | '. (_/ | .-. |(| '---.' \ | | | | | / /\_ + | '--' | | | | | | | `' '-' ' `-./ /.__) + `------' `--' `--' `------' `-----' `--' +EOF +} + +main() { + show_galoy + echo "------------------------------------------------------------" + echo "------------------------------------------------------------" + echo + echo "Checking that all services are up and running" + echo + ${DIR}/init-onchain.sh + ${DIR}/init-lightning.sh + echo + echo "------------------------------------------------------------" + echo "------------------------------------------------------------" + echo + echo "Hitting graphql endpoints" + + echo "Running on network:" + for i in {1..20}; do + exec_graphql "anon" "globals" + [[ "$(echo $output | jq -r '.data.globals.network')" = 'regtest' ]] && break + sleep 1 + done + echo $output | jq -r '.data.globals.network' + [[ "$(echo $output | jq -r '.data.globals.network')" = 'regtest' ]] || exit 1 + echo + for i in {1..10}; do + echo "Logging in Alice" + login_user "alice" "+16505554328" "000000" && break + sleep 1 + done + + initialize_user_from_onchain "alice" "+16505554328" "000000" + echo "Alice account set up, token: $(read_value "alice")" + + echo "TOKEN_ALICE=$(read_value "alice")" + export TOKEN_ALICE=$(read_value "alice") +} + +main diff --git a/dev/vendor/galoy-quickstart/bin/re-render.sh b/dev/vendor/galoy-quickstart/bin/re-render.sh new file mode 100755 index 0000000000..3477379ef4 --- /dev/null +++ b/dev/vendor/galoy-quickstart/bin/re-render.sh @@ -0,0 +1,13 @@ +#!/bin/bash + +set -e + +REPO_ROOT=$(git rev-parse --show-toplevel) +DEV_ROOT_DIR=${REPO_ROOT}/quickstart/dev + +pushd ${REPO_ROOT}/quickstart + +ytt -f vendir > vendir.yml +vendir sync + +ytt -f ./docker-compose.tmpl.yml -f ${DEV_ROOT_DIR}/docker-compose.deps.yml > docker-compose.yml diff --git a/dev/vendor/galoy-quickstart/dev/BUCK b/dev/vendor/galoy-quickstart/dev/BUCK new file mode 100644 index 0000000000..00fca6d337 --- /dev/null +++ b/dev/vendor/galoy-quickstart/dev/BUCK @@ -0,0 +1,99 @@ +load("@toolchains//rover:macros.bzl", "supergraph", "diff_check", "dev_update_file") +load( ":tilt.bzl", "tilt",) + +# Bring up the full set of services for development +tilt( + name = "up", + subcmd = "up", +) + +# Bring down any remaining/running services +tilt( + name = "down", + subcmd = "down", +) + +python_bootstrap_binary( + name = "healthcheck", + main = "healthcheck.py", + visibility = ["PUBLIC"], +) + +supergraph( + name = "supergraph", + config = "config/apollo-federation/supergraph-config.yaml", + subgraphs = { + "API_KEYS_SCHEMA": "//core/api-keys:sdl", + "NOTIFICATIONS_SCHEMA": "//core/notifications:sdl", + "PUBLIC_SCHEMA": "//core/api:public-sdl", + }, +) + +diff_check( + name = "supergraph-diff", + original = "config/apollo-federation/supergraph.graphql", + new = ":supergraph" +) + +test_suite( + name = "check-sdls", + tests = [ + ":supergraph-diff", + "//core/api:public-schema-diff", + "//core/api:admin-schema-diff", + "//core/api-keys:schema-diff", + "//core/notifications:schema-diff", + ], +) + +dev_update_file( + name = "update-supergraph", + generated = ":supergraph", + out = "config/apollo-federation/supergraph.graphql" +) + +dev_update_file( + name = "update-core-supergraph", + generated = ":supergraph", + out = "../core/api/dev/apollo-federation/supergraph.graphql" +) + +sh_binary( + name = "update-schemas", + main = "bin/update-schemas.sh", +) + +sh_binary( + name = "init-onchain", + main = "bin/init-onchain.sh", +) + +sh_binary( + name = "init-lightning", + main = "bin/init-lightning.sh", +) + +sh_binary( + name = "init-user", + main = "bin/init-user.sh", +) + +sh_binary( + name = "setup-hydra-client", + main = "bin/setup-hydra-client.sh", +) + +sh_binary( + name = "stoppable-trigger", + main = "bin/run-stoppable-trigger.sh", +) + +sh_binary( + name = "add-test-users-with-usernames", + main = "bin/add-test-users-with-usernames.sh", +) + +sh_binary( + name = "fund-user", + main = "bin/fund-user.sh", +) diff --git a/dev/vendor/galoy-quickstart/dev/Tiltfile b/dev/vendor/galoy-quickstart/dev/Tiltfile new file mode 100644 index 0000000000..0e781310ea --- /dev/null +++ b/dev/vendor/galoy-quickstart/dev/Tiltfile @@ -0,0 +1,600 @@ +config.define_string_list("test") +config.define_bool("bats") +cfg = config.parse() + +CORE_TEST_LABEL = "core" +CONSENT_TEST_LABEL = "consent" +DASHBOARD_TEST_LABEL = "dashboard" +PAY_TEST_LABEL = "pay" +ADMIN_PANEL_TEST_LABEL = "admin-panel" + +TEST_RESOURCES = { + CORE_TEST_LABEL: "api-test", + CONSENT_TEST_LABEL: "consent-test", + DASHBOARD_TEST_LABEL: "dashboard-test", + PAY_TEST_LABEL: "pay-test", + ADMIN_PANEL_TEST_LABEL: "admin-panel-test" +} + +is_ci=("ci" in sys.argv) or cfg.get("bats", False) +run_apps=not cfg.get("bats", False) + +# From the Tilt docs: +# +# > By default, Tilt will not let you develop against a remote cluster. +# +# The implication appears to be that if Tilt finds a configured Kubernetes setup on your system +# **and** it's a remote cluster, despite the fact that we are not using any Kubernetes features or +# capabilities, it will still try to connect and fail. Instead, we're going to disable this check +# and continue. +# +# - https://docs.tilt.dev/choosing_clusters.html#remote +# - https://docs.tilt.dev/api.html#api.allow_k8s_contexts +allow_k8s_contexts(k8s_context()) + +def _buck2_dep_inputs(target): + cmd = [ + "buck2", + "uquery", + "\"inputs(deps('{}'))\"".format(target), + ] + file_paths = str(local(" ".join(cmd))).splitlines() + + return file_paths + +dashboard_target = "//apps/dashboard:dev" +if is_ci: + dashboard_target = '//apps/dashboard:dashboard' +local_resource( + "dashboard", + labels = ["apps"], + cmd = "buck2 build {}".format(dashboard_target), + serve_cmd = ". .envs/dashboard.env && buck2 run {}".format(dashboard_target), + serve_env = { + "NEXTAUTH_URL": "http://localhost:3001", + "NEXTAUTH_SECRET": "secret", + "PORT": "3001", + }, + deps = _buck2_dep_inputs(dashboard_target), + allow_parallel = True, + auto_init = run_apps, + resource_deps = [ + "hydra-dashboard", + "api-keys", + "svix", + "svix-pg", + "add-test-users-with-usernames", + "fund-user", + "notifications", + ], + links = [ + link("http://localhost:3001", "dashboard"), + ], +) + +pay_target = "//apps/pay:dev" +if is_ci: + pay_target = '//apps/pay:pay-ci' +pay_env = { + "PORT": "3002", + "CORE_GQL_URL_INTRANET": "http://localhost:4455/graphql", + "NEXT_PUBLIC_CORE_GQL_URL": "http://localhost:4455/graphql", + "NEXT_PUBLIC_CORE_GQL_WEB_SOCKET_URL": "ws://localhost:4455/graphqlws", + "NEXT_PUBLIC_PAY_DOMAIN": "localhost:3002", +} +local_resource( + "pay", + labels = ["apps"], + cmd = "buck2 build {}".format(pay_target), + serve_cmd = "buck2 run {}".format(pay_target), + env = pay_env, + serve_env = pay_env, + deps = _buck2_dep_inputs(pay_target), + allow_parallel = True, + resource_deps = [ + "api", + ], + links = [ + link("http://localhost:3002", "pay"), + ], +) + +admin_panel_target = "//apps/admin-panel:dev" +if is_ci: + admin_panel_target = '//apps/admin-panel:admin-panel' +admin_panel_env = { + "PORT": "3004", + "ADMIN_CORE_API" : "http://localhost:4455/admin/graphql", + "NEXTAUTH_URL" : "http://localhost:3004", + "NEXTAUTH_SECRET" : "nextAuthSecret", +} +local_resource( + "admin-panel", + labels = ["apps"], + cmd = "buck2 build {}".format(admin_panel_target), + serve_cmd = "buck2 run {}".format(admin_panel_target), + env = admin_panel_env, + serve_env = admin_panel_env, + deps = _buck2_dep_inputs(admin_panel_target), + allow_parallel = True, + resource_deps = [ + "api", + "apollo-router", + ], + links = [ + link("http://localhost:3004", "admin-panel"), + ], +) + +local_resource( + name='hydra-dashboard', + labels = ['apps'], + cmd=[ + 'buck2', + 'run', + '//dev:setup-hydra-client', + '--', + 'dashboard', + 'authorization_code,refresh_token', + 'http://localhost:3001/api/auth/callback/blink', + ], + allow_parallel = True, + auto_init = run_apps, + resource_deps = [ + "hydra", + "api", + ] +) + +consent_test_target = "//apps/consent:test-integration" +local_resource( + "consent-test", + labels = ["test"], + auto_init = is_ci and CONSENT_TEST_LABEL in cfg.get("test", []), + cmd = "buck2 test {}".format(consent_test_target), + allow_parallel = True, + resource_deps = [ + "consent", + "init-test-user", + ], +) + +dashboard_test_target = "//apps/dashboard:test-integration" +local_resource( + "dashboard-test", + labels = ["test"], + auto_init = is_ci and DASHBOARD_TEST_LABEL in cfg.get("test", []), + cmd = "buck2 test {}".format(dashboard_test_target), + resource_deps = [ + "consent", + "dashboard", + "init-test-user", + ], +) + +pay_test_target = "//apps/pay:test-integration" +local_resource( + "pay-test", + labels = ["test"], + auto_init = is_ci and PAY_TEST_LABEL in cfg.get("test", []), + cmd = "buck2 test {}".format(pay_test_target), + resource_deps = [ + "api", + "pay", + "add-test-users-with-usernames", + ], +) + +admin_panel_test_target = "//apps/admin-panel:test-integration" +local_resource( + "admin-panel-test", + labels = ["test"], + auto_init = is_ci and ADMIN_PANEL_TEST_LABEL in cfg.get("test", []), + cmd = "buck2 test {}".format(admin_panel_test_target), + resource_deps = [ + "admin-panel", + ], +) + +local_resource( + name='init-test-user', + labels = ['test'], + cmd='buck2 run //dev:init-user', + allow_parallel = True, + resource_deps = [ + "oathkeeper", + "kratos", + "api", + ] +) + +local_resource( + name='add-test-users-with-usernames', + labels = ['test'], + cmd='buck2 run //dev:add-test-users-with-usernames', + allow_parallel = True, + resource_deps = [ + "oathkeeper", + "kratos", + "api", + ] +) + +local_resource( + name='fund-user', + labels = ['test'], + cmd='buck2 run //dev:fund-user', + allow_parallel = True, + resource_deps = [ + "oathkeeper", + "kratos", + "api", + "init-onchain", + "init-test-user", + "api-trigger", + "stablesats", + "price", + ] +) + + +consent_target = "//apps/consent:dev" +if is_ci: + consent_target = '//apps/consent:consent' +local_resource( + "consent", + labels = ["auth"], + cmd = "buck2 build {}".format(consent_target), + serve_cmd = "buck2 run {}".format(consent_target), + deps = _buck2_dep_inputs(consent_target), + allow_parallel = True, + auto_init = run_apps, + resource_deps = [ + "hydra-consent", + "apollo-router", + "hydra", + "api", + ], + links = [ + link("http://localhost:3000", "consent"), + ], +) + +local_resource( + name='hydra-consent', + labels = ['auth'], + cmd=[ + 'buck2', + 'run', + '//dev:setup-hydra-client', + '--', + 'consent', + 'authorization_code,refresh_token', + 'http://localhost:3000', + ], + allow_parallel = True, + auto_init = run_apps, + resource_deps = [ + "hydra", + "api", + ] +) + +core_serve_env = { + "HELMREVISION": "dev", + "NETWORK": "regtest", + "OATHKEEPER_DECISION_ENDPOINT": "http://localhost:4456", + "TWILIO_ACCOUNT_SID": "AC_twilio_id", + "TWILIO_AUTH_TOKEN": "AC_twilio_auth_token", + "TWILIO_VERIFY_SERVICE_ID": "VA_twilio_service", + "KRATOS_PG_CON": "postgres://dbuser:secret@localhost:5432/default?sslmode=disable", + "KRATOS_PUBLIC_API": "http://localhost:4433", + "KRATOS_ADMIN_API": "http://localhost:4434", + "KRATOS_MASTER_USER_PASSWORD": "passwordHardtoFindWithNumber123", + "PRICE_HOST": "localhost", + "PRICE_HISTORY_HOST": "localhost", + "BRIA_HOST": "localhost", + "BRIA_API_KEY": "bria_dev_000000000000000000000", + "NOTIFICATIONS_HOST": "localhost", + "MONGODB_CON": "mongodb://localhost:27017/galoy", + "REDIS_MASTER_NAME": "mymaster", + "REDIS_PASSWORD": "", + "REDIS_0_DNS": "localhost", + "REDIS_0_PORT": "6379", + "REDIS_TYPE": "standalone", + "UNSECURE_IP_FROM_REQUEST_OBJECT": "true", + "UNSECURE_DEFAULT_LOGIN_CODE": "000000", + "GEETEST_ID": "geetest_id", + "GEETEST_KEY": "geetest_key", + + "LND1_TLS": "LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUNZVENDQWdlZ0F3SUJBZ0lSQU9zZzdYWFR4cnVZYlhkeTY2d3RuN1F3Q2dZSUtvWkl6ajBFQXdJd09ERWYKTUIwR0ExVUVDaE1XYkc1a0lHRjFkRzluWlc1bGNtRjBaV1FnWTJWeWRERVZNQk1HQTFVRUF4TU1PRFl4T1RneApNak5tT0Roak1CNFhEVEl6TURFeE9USXdOREUxTTFvWERUTTBNRGN5TVRJd05ERTFNMW93T0RFZk1CMEdBMVVFCkNoTVdiRzVrSUdGMWRHOW5aVzVsY21GMFpXUWdZMlZ5ZERFVk1CTUdBMVVFQXhNTU9EWXhPVGd4TWpObU9EaGoKTUZrd0V3WUhLb1pJemowQ0FRWUlLb1pJemowREFRY0RRZ0FFM1lieUlKWU1Vcm8zZkl0UFFucysxZ2lpTXI5NQpJUXRmclFDQ2JhOWVtcjI4TENmbk1vYy9VQVFwUlg3QVlvVFRneUdiMFBuZGNUODF5ZVgvYTlPa0RLT0I4VENCCjdqQU9CZ05WSFE4QkFmOEVCQU1DQXFRd0V3WURWUjBsQkF3d0NnWUlLd1lCQlFVSEF3RXdEd1lEVlIwVEFRSC8KQkFVd0F3RUIvekFkQmdOVkhRNEVGZ1FVL1AxRHpJUkRzTEhHMU10d3NrZE5nZ0lub1Mwd2daWUdBMVVkRVFTQgpqakNCaTRJTU9EWXhPVGd4TWpObU9EaGpnZ2xzYjJOaGJHaHZjM1NDRFd4dVpDMXZkWFJ6YVdSbExUR0NEV3h1ClpDMXZkWFJ6YVdSbExUS0NEV3h1WkMxdmRYUnphV1JsTFRPQ0JHeHVaREdDQkd4dVpES0NCSFZ1YVhpQ0NuVnUKYVhod1lXTnJaWFNDQjJKMVptTnZibTZIQkg4QUFBR0hFQUFBQUFBQUFBQUFBQUFBQUFBQUFBR0hCS3dUQUJBdwpDZ1lJS29aSXpqMEVBd0lEU0FBd1JRSWhBSU5DNlJWQ3d6SzFYRnFxeVNLY0Y4QzQ5ZFlSOThjemdLNVdkcmNOCkxYYWlBaUJHYmtWeGhaeHdDaDVLQ1o1Z2M1Q2FsQ0RvaGNxVkdiaHNya0hHTFhpdHN3PT0KLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQo=", + "LND1_MACAROON": "AgEDbG5kAvgBAwoQB1FdhGa9xoewc1LEXmnURRIBMBoWCgdhZGRyZXNzEgRyZWFkEgV3cml0ZRoTCgRpbmZvEgRyZWFkEgV3cml0ZRoXCghpbnZvaWNlcxIEcmVhZBIFd3JpdGUaIQoIbWFjYXJvb24SCGdlbmVyYXRlEgRyZWFkEgV3cml0ZRoWCgdtZXNzYWdlEgRyZWFkEgV3cml0ZRoXCghvZmZjaGFpbhIEcmVhZBIFd3JpdGUaFgoHb25jaGFpbhIEcmVhZBIFd3JpdGUaFAoFcGVlcnMSBHJlYWQSBXdyaXRlGhgKBnNpZ25lchIIZ2VuZXJhdGUSBHJlYWQAAAYgqHDdwGCqx0aQL1/Z3uUfzCpeBhfapGf9s/AZPOVwf6s=", + "LND1_PUBKEY":"03ca1907342d5d37744cb7038375e1867c24a87564c293157c95b2a9d38dcfb4c2", + "LND1_DNS": "localhost", + "LND1_RPCPORT": "10009", + "LND1_NAME": "lnd1", + "LND1_TYPE": "offchain,onchain", + + "LND2_TLS": "LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUNZVENDQWdlZ0F3SUJBZ0lSQU9zZzdYWFR4cnVZYlhkeTY2d3RuN1F3Q2dZSUtvWkl6ajBFQXdJd09ERWYKTUIwR0ExVUVDaE1XYkc1a0lHRjFkRzluWlc1bGNtRjBaV1FnWTJWeWRERVZNQk1HQTFVRUF4TU1PRFl4T1RneApNak5tT0Roak1CNFhEVEl6TURFeE9USXdOREUxTTFvWERUTTBNRGN5TVRJd05ERTFNMW93T0RFZk1CMEdBMVVFCkNoTVdiRzVrSUdGMWRHOW5aVzVsY21GMFpXUWdZMlZ5ZERFVk1CTUdBMVVFQXhNTU9EWXhPVGd4TWpObU9EaGoKTUZrd0V3WUhLb1pJemowQ0FRWUlLb1pJemowREFRY0RRZ0FFM1lieUlKWU1Vcm8zZkl0UFFucysxZ2lpTXI5NQpJUXRmclFDQ2JhOWVtcjI4TENmbk1vYy9VQVFwUlg3QVlvVFRneUdiMFBuZGNUODF5ZVgvYTlPa0RLT0I4VENCCjdqQU9CZ05WSFE4QkFmOEVCQU1DQXFRd0V3WURWUjBsQkF3d0NnWUlLd1lCQlFVSEF3RXdEd1lEVlIwVEFRSC8KQkFVd0F3RUIvekFkQmdOVkhRNEVGZ1FVL1AxRHpJUkRzTEhHMU10d3NrZE5nZ0lub1Mwd2daWUdBMVVkRVFTQgpqakNCaTRJTU9EWXhPVGd4TWpObU9EaGpnZ2xzYjJOaGJHaHZjM1NDRFd4dVpDMXZkWFJ6YVdSbExUR0NEV3h1ClpDMXZkWFJ6YVdSbExUS0NEV3h1WkMxdmRYUnphV1JsTFRPQ0JHeHVaREdDQkd4dVpES0NCSFZ1YVhpQ0NuVnUKYVhod1lXTnJaWFNDQjJKMVptTnZibTZIQkg4QUFBR0hFQUFBQUFBQUFBQUFBQUFBQUFBQUFBR0hCS3dUQUJBdwpDZ1lJS29aSXpqMEVBd0lEU0FBd1JRSWhBSU5DNlJWQ3d6SzFYRnFxeVNLY0Y4QzQ5ZFlSOThjemdLNVdkcmNOCkxYYWlBaUJHYmtWeGhaeHdDaDVLQ1o1Z2M1Q2FsQ0RvaGNxVkdiaHNya0hHTFhpdHN3PT0KLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQo=", + "LND2_MACAROON": "AgEDbG5kAvgBAwoQX0BxfhQTxLTiqaceBnGnfBIBMBoWCgdhZGRyZXNzEgRyZWFkEgV3cml0ZRoTCgRpbmZvEgRyZWFkEgV3cml0ZRoXCghpbnZvaWNlcxIEcmVhZBIFd3JpdGUaIQoIbWFjYXJvb24SCGdlbmVyYXRlEgRyZWFkEgV3cml0ZRoWCgdtZXNzYWdlEgRyZWFkEgV3cml0ZRoXCghvZmZjaGFpbhIEcmVhZBIFd3JpdGUaFgoHb25jaGFpbhIEcmVhZBIFd3JpdGUaFAoFcGVlcnMSBHJlYWQSBXdyaXRlGhgKBnNpZ25lchIIZ2VuZXJhdGUSBHJlYWQAAAYgMAKlr1HehfBpn2R5RPE2IuY9r/18QBeLZxYgRidpos4=", + "LND2_PUBKEY": "039341ef13e776dc1611502cf510110d9ac5cdc252141f5997adcfd72cef34c3a7", + "LND2_DNS": "localhost", + "LND2_RPCPORT": "10010", + "LND2_NAME": "lnd2", + "LND2_TYPE": "offchain", + + "SVIX_SECRET": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE2OTE2NzIwMTQsImV4cCI6MjAwNzAzMjAxNCwibmJmIjoxNjkxNjcyMDE0LCJpc3MiOiJzdml4LXNlcnZlciIsInN1YiI6Im9yZ18yM3JiOFlkR3FNVDBxSXpwZ0d3ZFhmSGlyTXUifQ.b9s0aWSisNdUNki4edabBEToLNSwjC9-AiJQr4J3y4E", + "SVIX_ENDPOINT": "http://localhost:8071", + "EXPORTER_PORT": "3003" +} + +callback_target = "//bats/helpers/callback:run" +local_resource( + "callback", + labels = ["test"], + serve_cmd = "buck2 run {}".format(callback_target), + allow_parallel = True, + deps = _buck2_dep_inputs(callback_target), +) + +api_target = "//core/api:dev" +if is_ci: + api_target = "//core/api:api" +local_resource( + "api", + labels = ["core"], + cmd = "buck2 build {}".format(api_target), + serve_cmd = "buck2 run {}".format(api_target), + serve_env = core_serve_env, + allow_parallel = True, + readiness_probe = probe( + period_secs = 5, + http_get = http_get_action( + path = "healthz", + port = 4012, + ), + ), + deps = _buck2_dep_inputs(api_target), + resource_deps = [ + "price", + "init-onchain", + "init-lightning", + "lnd1", + "lnd2", + "redis", + "mongodb", + "oathkeeper", + "svix", + ] +) + +api_trigger_target = "//core/api-trigger:dev" +if is_ci: + api_trigger_target = "//core/api-trigger:api-trigger" +local_resource( + "api-trigger", + labels = ["core"], + cmd = "buck2 build {}".format(api_trigger_target), + serve_cmd = "buck2 run //dev:stoppable-trigger {}".format(api_trigger_target), + serve_env = core_serve_env, + allow_parallel = True, + readiness_probe = probe( + period_secs = 5, + http_get = http_get_action( + path = "healthz", + port = 4012, + ), + ), + deps = _buck2_dep_inputs(api_trigger_target), + resource_deps = [ + "price", + "init-onchain", + "lnd1", + "lnd2", + "redis", + "mongodb", + "oathkeeper", + ] +) + +api_exporter_target = "//core/api-exporter:dev" +if is_ci: + api_exporter_target = "//core/api-exporter:api-exporter" +local_resource( + "api-exporter", + labels = ["core"], + cmd = "buck2 build {}".format(api_exporter_target), + serve_cmd = "buck2 run {}".format(api_exporter_target), + serve_env = core_serve_env, + allow_parallel = True, + readiness_probe = probe( + period_secs = 5, + http_get = http_get_action( + path = "healthz", + port = 4012, + ), + ), + deps = _buck2_dep_inputs(api_exporter_target), + resource_deps = [ + "price", + "init-onchain", + "lnd1", + "lnd2", + "redis", + "mongodb", + "oathkeeper", + ] +) + +api_ws_server_target = "//core/api-ws-server:dev" +if is_ci: + api_ws_server_target = "//core/api-ws-server:api-ws-server" +local_resource( + "api-ws-server", + labels = ["core"], + cmd = "buck2 build {}".format(api_ws_server_target), + serve_cmd = "buck2 run {}".format(api_ws_server_target), + serve_env = core_serve_env, + allow_parallel = True, + readiness_probe = probe( + period_secs = 5, + http_get = http_get_action( + path = "healthz", + port = 4012, + ), + ), + deps = _buck2_dep_inputs(api_ws_server_target), + resource_deps = [ + "price", + "init-onchain", + "lnd1", + "lnd2", + "redis", + "mongodb", + "oathkeeper", + ] +) + +notifications_target = "//core/notifications:notifications" +local_resource( + "notifications", + labels = ["core"], + cmd = "buck2 build {}".format(notifications_target), + serve_cmd = "buck2 run {}".format(notifications_target), + serve_env = { + "PG_CON": "postgres://user:password@localhost:5433/pg", + "NOTIFICATIONS_CONFIG": "../core/notifications/notifications.yml", + "OTEL_EXPORTER_OTLP_ENDPOINT": "http://localhost:4317", + }, + deps = _buck2_dep_inputs(notifications_target), + allow_parallel = True, + resource_deps = [ + "api", + "notifications-pg" + ] +) + +local_resource( + name='init-onchain', + labels = ['bitcoin'], + cmd='buck2 run //dev:init-onchain', + allow_parallel = True, + resource_deps = [ + "bitcoind", + "bria", + ] +) + +local_resource( + name='init-lightning', + labels = ['bitcoin'], + cmd='buck2 run //dev:init-lightning', + allow_parallel = True, + resource_deps = [ + "init-onchain", + "lnd1", + "lnd-outside-1", + "lnd-outside-2", + ] +) + +api_keys_target = "//core/api-keys:api-keys" +local_resource( + "api-keys", + labels = ["auth"], + cmd = "buck2 build {}".format(api_keys_target), + serve_cmd = "buck2 run {}".format(api_keys_target), + serve_env = { + "PG_CON": "postgres://user:password@localhost:5431/pg", + "API_KEYS_CONFIG": "../core/api-keys/api-keys.yml", + "OTEL_EXPORTER_OTLP_ENDPOINT": "http://localhost:4317", + }, + deps = _buck2_dep_inputs(api_keys_target), + allow_parallel = True, + resource_deps = [ + "api", + "api-keys-pg" + ] +) + +docker_groups = { + "auth": [ + "api-keys-pg", + "oathkeeper", + "hydra", + "hydra-migrate", + "hydra-pg", + "kratos", + "kratos-pg", + ], + "core": [ + "apollo-router", + "mongodb", + "notifications-pg", + "oathkeeper", + "redis", + "stablesats", + "svix-pg", + "svix", + ], + "bitcoin": [ + "lnd1", + "lnd2", + "bria", + "bria-pg", + "bitcoind", + ], + "integration": [ + "lnd-outside-1", + "lnd-outside-2", + ], + "price": [ + "price", + "price-history", + "price-history-migrate", + "price-history-pg" + ], + "tracing": [ + "otel-agent", + ], +} + +to_run = cfg.get("to-run", []) +if to_run != []: + enabled_resources = [] + for svc in to_run: + enabled_resources.append(svc) + config.set_enabled_resources(enabled_resources) + +to_test = cfg.get("test", []) +if to_test != []: + enabled_resources = [] + for label in to_test: + svc = TEST_RESOURCES.get(label) + if svc: + enabled_resources.append(svc) + config.set_enabled_resources(enabled_resources) + +docker_compose("./docker-compose.deps.yml", project_name = "galoy-dev") + +for service in docker_groups["bitcoin"]: + dc_resource(service, labels = ["bitcoin"]) +for service in docker_groups["tracing"]: + dc_resource(service, labels = ["tracing"]) +for service in docker_groups["core"]: + dc_resource(service, labels = ["core"]) +for service in docker_groups["auth"]: + dc_resource(service, labels = ["auth"]) +for service in docker_groups["price"]: + dc_resource(service, labels = ["price"]) +for service in docker_groups["integration"]: + dc_resource(service, labels = ["integration"]) + +api_test_target = "//core/api:test-integration" +local_resource( + "api-test", + labels = ["test"], + auto_init = is_ci and CORE_TEST_LABEL in cfg.get("test", []), + cmd = "buck2 test {}".format(api_test_target), + resource_deps = [res for sublist in docker_groups.values() for res in sublist] + ["notifications"] +) diff --git a/dev/vendor/galoy-quickstart/dev/config/apollo-federation/README.md b/dev/vendor/galoy-quickstart/dev/config/apollo-federation/README.md new file mode 100644 index 0000000000..13d043b1fd --- /dev/null +++ b/dev/vendor/galoy-quickstart/dev/config/apollo-federation/README.md @@ -0,0 +1,14 @@ +# Apollo Federation + +To generate the supergraph you need to run: +``` +$ pnpm run write-sdl +``` + +which executes: +``` +$ rover supergraph compose \ + --config dev/apollo-federation/supergraph-config.yaml \ + --elv2-license accept \ + > dev/apollo-federation/supergraph.graphql +``` diff --git a/dev/vendor/galoy-quickstart/dev/config/apollo-federation/router.yaml b/dev/vendor/galoy-quickstart/dev/config/apollo-federation/router.yaml new file mode 100644 index 0000000000..e48c193792 --- /dev/null +++ b/dev/vendor/galoy-quickstart/dev/config/apollo-federation/router.yaml @@ -0,0 +1,22 @@ +headers: + all: + request: + - propagate: + matching: .* +include_subgraph_errors: + all: true +sandbox: + enabled: true +homepage: + enabled: false +supergraph: + listen: 0.0.0.0:4004 + introspection: true + path: /graphql +cors: + allow_any_origin: true +telemetry: + tracing: + otlp: + endpoint: http://otel-agent:4318 + protocol: http diff --git a/dev/vendor/galoy-quickstart/dev/config/apollo-federation/supergraph-config.yaml b/dev/vendor/galoy-quickstart/dev/config/apollo-federation/supergraph-config.yaml new file mode 100644 index 0000000000..2bbc4e4f9d --- /dev/null +++ b/dev/vendor/galoy-quickstart/dev/config/apollo-federation/supergraph-config.yaml @@ -0,0 +1,14 @@ +federation_version: =2.3.2 +subgraphs: + public: + routing_url: http://bats-tests:4012/graphql + schema: + file: ${env.PUBLIC_SCHEMA:-../../../core/api/src/graphql/public/schema.graphql} + api_keys: + routing_url: http://bats-tests:5397/graphql + schema: + file: ${env.API_KEYS_SCHEMA:-../../../core/api-keys/subgraph/schema.graphql} + notifications: + routing_url: http://bats-tests:6684/graphql + schema: + file: ${env.NOTIFICATIONS_SCHEMA:-../../../core/notifications/subgraph/schema.graphql} diff --git a/dev/vendor/galoy-quickstart/dev/config/apollo-federation/supergraph.graphql b/dev/vendor/galoy-quickstart/dev/config/apollo-federation/supergraph.graphql new file mode 100644 index 0000000000..a865d53942 --- /dev/null +++ b/dev/vendor/galoy-quickstart/dev/config/apollo-federation/supergraph.graphql @@ -0,0 +1,2256 @@ +schema + @link(url: "https://specs.apollo.dev/link/v1.0") + @link(url: "https://specs.apollo.dev/join/v0.3", for: EXECUTION) +{ + query: Query + mutation: Mutation + subscription: Subscription +} + +directive @join__enumValue(graph: join__Graph!) repeatable on ENUM_VALUE + +directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION + +directive @join__graph(name: String!, url: String!) on ENUM_VALUE + +directive @join__implements(graph: join__Graph!, interface: String!) repeatable on OBJECT | INTERFACE + +directive @join__type(graph: join__Graph!, key: join__FieldSet, extension: Boolean! = false, resolvable: Boolean! = true, isInterfaceObject: Boolean! = false) repeatable on OBJECT | INTERFACE | UNION | ENUM | INPUT_OBJECT | SCALAR + +directive @join__unionMember(graph: join__Graph!, member: String!) repeatable on UNION + +directive @link(url: String, as: String, for: link__Purpose, import: [link__Import]) repeatable on SCHEMA + +interface Account + @join__type(graph: PUBLIC) +{ + callbackEndpoints: [CallbackEndpoint!]! + csvTransactions(walletIds: [WalletId!]!): String! + defaultWallet: PublicWallet! + defaultWalletId: WalletId! @deprecated(reason: "Shifting property to 'defaultWallet.id'") + displayCurrency: DisplayCurrency! + id: ID! + invoices( + """Returns the items in the list that come after the specified cursor.""" + after: String + + """Returns the items in the list that come before the specified cursor.""" + before: String + + """Returns the first n items from the list.""" + first: Int + + """Returns the last n items from the list.""" + last: Int + walletIds: [WalletId] + ): InvoiceConnection + level: AccountLevel! + limits: AccountLimits! + notificationSettings: NotificationSettings! + pendingIncomingTransactions(walletIds: [WalletId]): [Transaction!]! + realtimePrice: RealtimePrice! + transactions( + """Returns the items in the list that come after the specified cursor.""" + after: String + + """Returns the items in the list that come before the specified cursor.""" + before: String + + """Returns the first n items from the list.""" + first: Int + + """Returns the last n items from the list.""" + last: Int + walletIds: [WalletId] + ): TransactionConnection + walletById(walletId: WalletId!): Wallet! + wallets: [Wallet!]! +} + +type AccountDeletePayload + @join__type(graph: PUBLIC) +{ + errors: [Error!]! + success: Boolean! +} + +input AccountDisableNotificationCategoryInput + @join__type(graph: PUBLIC) +{ + category: NotificationCategory! + channel: NotificationChannel +} + +input AccountDisableNotificationChannelInput + @join__type(graph: PUBLIC) +{ + channel: NotificationChannel! +} + +input AccountEnableNotificationCategoryInput + @join__type(graph: PUBLIC) +{ + category: NotificationCategory! + channel: NotificationChannel +} + +input AccountEnableNotificationChannelInput + @join__type(graph: PUBLIC) +{ + channel: NotificationChannel! +} + +enum AccountLevel + @join__type(graph: PUBLIC) +{ + ONE @join__enumValue(graph: PUBLIC) + TWO @join__enumValue(graph: PUBLIC) + ZERO @join__enumValue(graph: PUBLIC) +} + +interface AccountLimit + @join__type(graph: PUBLIC) +{ + """The rolling time interval in seconds that the limits would apply for.""" + interval: Seconds + + """ + The amount of cents remaining below the limit for the current 24 hour period. + """ + remainingLimit: CentAmount + + """The current maximum limit for a given 24 hour period.""" + totalLimit: CentAmount! +} + +type AccountLimits + @join__type(graph: PUBLIC) +{ + """ + Limits for converting between currencies among a account's own wallets. + """ + convert: [AccountLimit!]! + + """Limits for sending to other internal accounts.""" + internalSend: [AccountLimit!]! + + """Limits for withdrawing to external onchain or lightning destinations.""" + withdrawal: [AccountLimit!]! +} + +input AccountUpdateDefaultWalletIdInput + @join__type(graph: PUBLIC) +{ + walletId: WalletId! +} + +type AccountUpdateDefaultWalletIdPayload + @join__type(graph: PUBLIC) +{ + account: ConsumerAccount + errors: [Error!]! +} + +input AccountUpdateDisplayCurrencyInput + @join__type(graph: PUBLIC) +{ + currency: DisplayCurrency! +} + +type AccountUpdateDisplayCurrencyPayload + @join__type(graph: PUBLIC) +{ + account: ConsumerAccount + errors: [Error!]! +} + +type AccountUpdateNotificationSettingsPayload + @join__type(graph: PUBLIC) +{ + account: ConsumerAccount + errors: [Error!]! +} + +type ApiKey + @join__type(graph: API_KEYS) +{ + id: ID! + name: String! + createdAt: Timestamp! + revoked: Boolean! + expired: Boolean! + lastUsedAt: Timestamp + expiresAt: Timestamp + readOnly: Boolean! +} + +input ApiKeyCreateInput + @join__type(graph: API_KEYS) +{ + name: String! + expireInDays: Int + readOnly: Boolean! = false +} + +type ApiKeyCreatePayload + @join__type(graph: API_KEYS) +{ + apiKey: ApiKey! + apiKeySecret: String! +} + +input ApiKeyRevokeInput + @join__type(graph: API_KEYS) +{ + id: ID! +} + +type ApiKeyRevokePayload + @join__type(graph: API_KEYS) +{ + apiKey: ApiKey! +} + +"""An Opaque Bearer token""" +scalar AuthToken + @join__type(graph: PUBLIC) + +type AuthTokenPayload + @join__type(graph: PUBLIC) +{ + authToken: AuthToken + errors: [Error!]! + totpRequired: Boolean +} + +""" +A wallet belonging to an account which contains a BTC balance and a list of transactions. +""" +type BTCWallet implements Wallet + @join__implements(graph: PUBLIC, interface: "Wallet") + @join__type(graph: PUBLIC) +{ + accountId: ID! + + """A balance stored in BTC.""" + balance: SignedAmount! + id: ID! + invoiceByPaymentHash(paymentHash: PaymentHash!): Invoice! + + """A list of all invoices associated with walletIds optionally passed.""" + invoices( + """Returns the items in the list that come after the specified cursor.""" + after: String + + """Returns the items in the list that come before the specified cursor.""" + before: String + + """Returns the first n items from the list.""" + first: Int + + """Returns the last n items from the list.""" + last: Int + ): InvoiceConnection + + """An unconfirmed incoming onchain balance.""" + pendingIncomingBalance: SignedAmount! + pendingIncomingTransactions: [Transaction!]! + pendingIncomingTransactionsByAddress( + """Returns the items that include this address.""" + address: OnChainAddress! + ): [Transaction!]! + transactionById(transactionId: ID!): Transaction! + + """A list of BTC transactions associated with this wallet.""" + transactions( + """Returns the items in the list that come after the specified cursor.""" + after: String + + """Returns the items in the list that come before the specified cursor.""" + before: String + + """Returns the first n items from the list.""" + first: Int + + """Returns the last n items from the list.""" + last: Int + ): TransactionConnection + transactionsByAddress( + """Returns the items that include this address.""" + address: OnChainAddress! + + """Returns the items in the list that come after the specified cursor.""" + after: String + + """Returns the items in the list that come before the specified cursor.""" + before: String + + """Returns the first n items from the list.""" + first: Int + + """Returns the last n items from the list.""" + last: Int + ): TransactionConnection + transactionsByPaymentHash(paymentHash: PaymentHash!): [Transaction!]! + walletCurrency: WalletCurrency! +} + +type BuildInformation + @join__type(graph: PUBLIC) +{ + commitHash: String + helmRevision: Int +} + +type CallbackEndpoint + @join__type(graph: PUBLIC) +{ + id: EndpointId! + url: EndpointUrl! +} + +input CallbackEndpointAddInput + @join__type(graph: PUBLIC) +{ + """callback endpoint to be called""" + url: EndpointUrl! +} + +type CallbackEndpointAddPayload + @join__type(graph: PUBLIC) +{ + errors: [Error!]! + id: EndpointId +} + +input CallbackEndpointDeleteInput + @join__type(graph: PUBLIC) +{ + id: EndpointId! +} + +type CaptchaCreateChallengePayload + @join__type(graph: PUBLIC) +{ + errors: [Error!]! + result: CaptchaCreateChallengeResult +} + +type CaptchaCreateChallengeResult + @join__type(graph: PUBLIC) +{ + challengeCode: String! + failbackMode: Boolean! + id: String! + newCaptcha: Boolean! +} + +input CaptchaRequestAuthCodeInput + @join__type(graph: PUBLIC) +{ + challengeCode: String! + channel: PhoneCodeChannelType + phone: Phone! + secCode: String! + validationCode: String! +} + +"""(Positive) Cent amount (1/100 of a dollar)""" +scalar CentAmount + @join__type(graph: PUBLIC) + +type CentAmountPayload + @join__type(graph: PUBLIC) +{ + amount: CentAmount + errors: [Error!]! +} + +type ConsumerAccount implements Account + @join__implements(graph: PUBLIC, interface: "Account") + @join__type(graph: PUBLIC) +{ + callbackEndpoints: [CallbackEndpoint!]! + + """ + return CSV stream, base64 encoded, of the list of transactions in the wallet + """ + csvTransactions(walletIds: [WalletId!]!): String! + defaultWallet: PublicWallet! + defaultWalletId: WalletId! + displayCurrency: DisplayCurrency! + id: ID! + + """A list of all invoices associated with walletIds optionally passed.""" + invoices( + """Returns the items in the list that come after the specified cursor.""" + after: String + + """Returns the items in the list that come before the specified cursor.""" + before: String + + """Returns the first n items from the list.""" + first: Int + + """Returns the last n items from the list.""" + last: Int + walletIds: [WalletId] + ): InvoiceConnection + level: AccountLevel! + limits: AccountLimits! + notificationSettings: NotificationSettings! + pendingIncomingTransactions(walletIds: [WalletId]): [Transaction!]! + + """List the quiz questions of the consumer account""" + quiz: [Quiz!]! + realtimePrice: RealtimePrice! + + """ + A list of all transactions associated with walletIds optionally passed. + """ + transactions( + """Returns the items in the list that come after the specified cursor.""" + after: String + + """Returns the items in the list that come before the specified cursor.""" + before: String + + """Returns the first n items from the list.""" + first: Int + + """Returns the last n items from the list.""" + last: Int + walletIds: [WalletId] + ): TransactionConnection + walletById(walletId: WalletId!): Wallet! + wallets: [Wallet!]! +} + +""" +An alias name that a user can set for a wallet (with which they have transactions) +""" +scalar ContactAlias + @join__type(graph: PUBLIC) + +type Coordinates + @join__type(graph: PUBLIC) +{ + latitude: Float! + longitude: Float! +} + +type Country + @join__type(graph: PUBLIC) +{ + id: CountryCode! + supportedAuthChannels: [PhoneCodeChannelType!]! +} + +"""A CCA2 country code (ex US, FR, etc)""" +scalar CountryCode + @join__type(graph: PUBLIC) + +type Currency + @join__type(graph: PUBLIC) +{ + flag: String! + fractionDigits: Int! + id: ID! + name: String! + symbol: String! +} + +type DepositFeesInformation + @join__type(graph: PUBLIC) +{ + minBankFee: String! + + """below this amount minBankFee will be charged""" + minBankFeeThreshold: String! + + """ratio to charge as basis points above minBankFeeThreshold amount""" + ratio: String! +} + +input DeviceNotificationTokenCreateInput + @join__type(graph: PUBLIC) +{ + deviceToken: String! +} + +"""Display currency of an account""" +scalar DisplayCurrency + @join__type(graph: PUBLIC) + +type Email + @join__type(graph: PUBLIC) +{ + address: EmailAddress + verified: Boolean +} + +"""Email address""" +scalar EmailAddress + @join__type(graph: PUBLIC) + +""" +An id to be passed between registrationInitiate and registrationValidate for confirming email +""" +scalar EmailRegistrationId + @join__type(graph: PUBLIC) + +scalar EndpointId + @join__type(graph: PUBLIC) + +"""Url that will be fetched on events for the account""" +scalar EndpointUrl + @join__type(graph: PUBLIC) + +interface Error + @join__type(graph: PUBLIC) +{ + code: String + message: String! + path: [String] +} + +enum ExchangeCurrencyUnit + @join__type(graph: PUBLIC) +{ + BTCSAT @join__enumValue(graph: PUBLIC) + USDCENT @join__enumValue(graph: PUBLIC) +} + +"""Feedback shared with our user""" +scalar Feedback + @join__type(graph: PUBLIC) + +input FeedbackSubmitInput + @join__type(graph: PUBLIC) +{ + feedback: Feedback! +} + +type FeesInformation + @join__type(graph: PUBLIC) +{ + deposit: DepositFeesInformation! +} + +""" +Provides global settings for the application which might have an impact for the user. +""" +type Globals + @join__type(graph: PUBLIC) +{ + buildInformation: BuildInformation! + feesInformation: FeesInformation! + + """ + The domain name for lightning addresses accepted by this Galoy instance + """ + lightningAddressDomain: String! + lightningAddressDomainAliases: [String!]! + + """ + Which network (mainnet, testnet, regtest, signet) this instance is running on. + """ + network: Network! + + """ + A list of public keys for the running lightning nodes. + This can be used to know if an invoice belongs to one of our nodes. + """ + nodesIds: [String!]! + + """A list of countries and their supported auth channels""" + supportedCountries: [Country!]! +} + +type GraphQLApplicationError implements Error + @join__implements(graph: PUBLIC, interface: "Error") + @join__type(graph: PUBLIC) +{ + code: String + message: String! + path: [String] +} + +"""Hex-encoded string of 32 bytes""" +scalar Hex32Bytes + @join__type(graph: PUBLIC) + +union InitiationVia + @join__type(graph: PUBLIC) + @join__unionMember(graph: PUBLIC, member: "InitiationViaIntraLedger") + @join__unionMember(graph: PUBLIC, member: "InitiationViaLn") + @join__unionMember(graph: PUBLIC, member: "InitiationViaOnChain") + = InitiationViaIntraLedger | InitiationViaLn | InitiationViaOnChain + +type InitiationViaIntraLedger + @join__type(graph: PUBLIC) +{ + counterPartyUsername: Username + counterPartyWalletId: WalletId +} + +type InitiationViaLn + @join__type(graph: PUBLIC) +{ + paymentHash: PaymentHash! + + """Bolt11 invoice""" + paymentRequest: LnPaymentRequest! +} + +type InitiationViaOnChain + @join__type(graph: PUBLIC) +{ + address: OnChainAddress! +} + +input IntraLedgerPaymentSendInput + @join__type(graph: PUBLIC) +{ + """Amount in satoshis.""" + amount: SatAmount! + + """Optional memo to be attached to the payment.""" + memo: Memo + recipientWalletId: WalletId! + + """The wallet ID of the sender.""" + walletId: WalletId! +} + +type IntraLedgerUpdate + @join__type(graph: PUBLIC) +{ + amount: SatAmount! @deprecated(reason: "Deprecated in favor of transaction") + displayCurrencyPerSat: Float! @deprecated(reason: "Deprecated in favor of transaction") + transaction: Transaction! + txNotificationType: TxNotificationType! + usdPerSat: Float! @deprecated(reason: "updated over displayCurrencyPerSat") + walletId: WalletId! @deprecated(reason: "Deprecated in favor of transaction") +} + +input IntraLedgerUsdPaymentSendInput + @join__type(graph: PUBLIC) +{ + """Amount in cents.""" + amount: CentAmount! + + """Optional memo to be attached to the payment.""" + memo: Memo + recipientWalletId: WalletId! + + """The wallet ID of the sender.""" + walletId: WalletId! +} + +"""A lightning invoice.""" +interface Invoice + @join__type(graph: PUBLIC) +{ + createdAt: Timestamp! + + """The payment hash of the lightning invoice.""" + paymentHash: PaymentHash! + + """The bolt11 invoice to be paid.""" + paymentRequest: LnPaymentRequest! + + """ + The payment secret of the lightning invoice. This is not the preimage of the payment hash. + """ + paymentSecret: LnPaymentSecret! + + """The payment status of the invoice.""" + paymentStatus: InvoicePaymentStatus! +} + +"""A connection to a list of items.""" +type InvoiceConnection + @join__type(graph: PUBLIC) +{ + """A list of edges.""" + edges: [InvoiceEdge!] + + """Information to aid in pagination.""" + pageInfo: PageInfo! +} + +"""An edge in a connection.""" +type InvoiceEdge + @join__type(graph: PUBLIC) +{ + """A cursor for use in pagination""" + cursor: String! + + """The item at the end of the edge""" + node: Invoice! +} + +enum InvoicePaymentStatus + @join__type(graph: PUBLIC) +{ + EXPIRED @join__enumValue(graph: PUBLIC) + PAID @join__enumValue(graph: PUBLIC) + PENDING @join__enumValue(graph: PUBLIC) +} + +scalar join__FieldSet + +enum join__Graph { + API_KEYS @join__graph(name: "api_keys", url: "http://bats-tests:5397/graphql") + NOTIFICATIONS @join__graph(name: "notifications", url: "http://bats-tests:6684/graphql") + PUBLIC @join__graph(name: "public", url: "http://bats-tests:4012/graphql") +} + +scalar Language + @join__type(graph: PUBLIC) + +scalar link__Import + +enum link__Purpose { + """ + `SECURITY` features provide metadata necessary to securely resolve fields. + """ + SECURITY + + """ + `EXECUTION` features provide metadata necessary for operation execution. + """ + EXECUTION +} + +input LnAddressPaymentSendInput + @join__type(graph: PUBLIC) +{ + """Amount in satoshis.""" + amount: SatAmount! + + """Lightning address to send to.""" + lnAddress: String! + + """Wallet ID to send bitcoin from.""" + walletId: WalletId! +} + +type LnInvoice implements Invoice + @join__implements(graph: PUBLIC, interface: "Invoice") + @join__type(graph: PUBLIC) +{ + createdAt: Timestamp! + paymentHash: PaymentHash! + paymentRequest: LnPaymentRequest! + paymentSecret: LnPaymentSecret! + paymentStatus: InvoicePaymentStatus! + satoshis: SatAmount! +} + +input LnInvoiceCreateInput + @join__type(graph: PUBLIC) +{ + """Amount in satoshis.""" + amount: SatAmount! + + """Optional invoice expiration time in minutes.""" + expiresIn: Minutes + + """Optional memo for the lightning invoice.""" + memo: Memo + + """Wallet ID for a BTC wallet belonging to the current account.""" + walletId: WalletId! +} + +input LnInvoiceCreateOnBehalfOfRecipientInput + @join__type(graph: PUBLIC) +{ + """Amount in satoshis.""" + amount: SatAmount! + descriptionHash: Hex32Bytes + + """Optional invoice expiration time in minutes.""" + expiresIn: Minutes + + """Optional memo for the lightning invoice.""" + memo: Memo + + """Wallet ID for a BTC wallet which belongs to any account.""" + recipientWalletId: WalletId! +} + +input LnInvoiceFeeProbeInput + @join__type(graph: PUBLIC) +{ + paymentRequest: LnPaymentRequest! + walletId: WalletId! +} + +type LnInvoicePayload + @join__type(graph: PUBLIC) +{ + errors: [Error!]! + invoice: LnInvoice +} + +input LnInvoicePaymentInput + @join__type(graph: PUBLIC) +{ + """Optional memo to associate with the lightning invoice.""" + memo: Memo + + """Payment request representing the invoice which is being paid.""" + paymentRequest: LnPaymentRequest! + + """ + Wallet ID with sufficient balance to cover amount of invoice. Must belong to the account of the current user. + """ + walletId: WalletId! +} + +input LnInvoicePaymentStatusInput + @join__type(graph: PUBLIC) +{ + paymentRequest: LnPaymentRequest! +} + +type LnInvoicePaymentStatusPayload + @join__type(graph: PUBLIC) +{ + errors: [Error!]! + status: InvoicePaymentStatus +} + +type LnNoAmountInvoice implements Invoice + @join__implements(graph: PUBLIC, interface: "Invoice") + @join__type(graph: PUBLIC) +{ + createdAt: Timestamp! + paymentHash: PaymentHash! + paymentRequest: LnPaymentRequest! + paymentSecret: LnPaymentSecret! + paymentStatus: InvoicePaymentStatus! +} + +input LnNoAmountInvoiceCreateInput + @join__type(graph: PUBLIC) +{ + """Optional invoice expiration time in minutes.""" + expiresIn: Minutes + + """Optional memo for the lightning invoice.""" + memo: Memo + + """ + ID for either a USD or BTC wallet belonging to the account of the current user. + """ + walletId: WalletId! +} + +input LnNoAmountInvoiceCreateOnBehalfOfRecipientInput + @join__type(graph: PUBLIC) +{ + """Optional invoice expiration time in minutes.""" + expiresIn: Minutes + + """Optional memo for the lightning invoice.""" + memo: Memo + + """ + ID for either a USD or BTC wallet which belongs to the account of any user. + """ + recipientWalletId: WalletId! +} + +input LnNoAmountInvoiceFeeProbeInput + @join__type(graph: PUBLIC) +{ + amount: SatAmount! + paymentRequest: LnPaymentRequest! + walletId: WalletId! +} + +type LnNoAmountInvoicePayload + @join__type(graph: PUBLIC) +{ + errors: [Error!]! + invoice: LnNoAmountInvoice +} + +input LnNoAmountInvoicePaymentInput + @join__type(graph: PUBLIC) +{ + """Amount to pay in satoshis.""" + amount: SatAmount! + + """Optional memo to associate with the lightning invoice.""" + memo: Memo + + """Payment request representing the invoice which is being paid.""" + paymentRequest: LnPaymentRequest! + + """ + Wallet ID with sufficient balance to cover amount defined in mutation request. Must belong to the account of the current user. + """ + walletId: WalletId! +} + +input LnNoAmountUsdInvoiceFeeProbeInput + @join__type(graph: PUBLIC) +{ + amount: CentAmount! + paymentRequest: LnPaymentRequest! + walletId: WalletId! +} + +input LnNoAmountUsdInvoicePaymentInput + @join__type(graph: PUBLIC) +{ + """Amount to pay in USD cents.""" + amount: CentAmount! + + """Optional memo to associate with the lightning invoice.""" + memo: Memo + + """Payment request representing the invoice which is being paid.""" + paymentRequest: LnPaymentRequest! + + """ + Wallet ID with sufficient balance to cover amount defined in mutation request. Must belong to the account of the current user. + """ + walletId: WalletId! +} + +scalar LnPaymentPreImage + @join__type(graph: PUBLIC) + +"""BOLT11 lightning invoice payment request with the amount included""" +scalar LnPaymentRequest + @join__type(graph: PUBLIC) + +scalar LnPaymentSecret + @join__type(graph: PUBLIC) + +type LnUpdate + @join__type(graph: PUBLIC) +{ + paymentHash: PaymentHash! @deprecated(reason: "Deprecated in favor of transaction") + status: InvoicePaymentStatus! + transaction: Transaction! + walletId: WalletId! @deprecated(reason: "Deprecated in favor of transaction") +} + +input LnurlPaymentSendInput + @join__type(graph: PUBLIC) +{ + """Amount in satoshis.""" + amount: SatAmount! + + """Lnurl string to send to.""" + lnurl: String! + + """Wallet ID to send bitcoin from.""" + walletId: WalletId! +} + +input LnUsdInvoiceBtcDenominatedCreateOnBehalfOfRecipientInput + @join__type(graph: PUBLIC) +{ + """Amount in satoshis.""" + amount: SatAmount! + descriptionHash: Hex32Bytes + + """Optional invoice expiration time in minutes.""" + expiresIn: Minutes + + """ + Optional memo for the lightning invoice. Acts as a note to the recipient. + """ + memo: Memo + + """Wallet ID for a USD wallet which belongs to the account of any user.""" + recipientWalletId: WalletId! +} + +input LnUsdInvoiceCreateInput + @join__type(graph: PUBLIC) +{ + """Amount in USD cents.""" + amount: CentAmount! + + """Optional invoice expiration time in minutes.""" + expiresIn: Minutes + + """Optional memo for the lightning invoice.""" + memo: Memo + + """Wallet ID for a USD wallet belonging to the current user.""" + walletId: WalletId! +} + +input LnUsdInvoiceCreateOnBehalfOfRecipientInput + @join__type(graph: PUBLIC) +{ + """Amount in USD cents.""" + amount: CentAmount! + descriptionHash: Hex32Bytes + + """Optional invoice expiration time in minutes.""" + expiresIn: Minutes + + """ + Optional memo for the lightning invoice. Acts as a note to the recipient. + """ + memo: Memo + + """Wallet ID for a USD wallet which belongs to the account of any user.""" + recipientWalletId: WalletId! +} + +input LnUsdInvoiceFeeProbeInput + @join__type(graph: PUBLIC) +{ + paymentRequest: LnPaymentRequest! + walletId: WalletId! +} + +type MapInfo + @join__type(graph: PUBLIC) +{ + coordinates: Coordinates! + title: String! +} + +type MapMarker + @join__type(graph: PUBLIC) +{ + mapInfo: MapInfo! + username: Username! +} + +"""Text field in a lightning payment transaction""" +scalar Memo + @join__type(graph: PUBLIC) + +"""(Positive) amount of minutes""" +scalar Minutes + @join__type(graph: PUBLIC) + +type MobileVersions + @join__type(graph: PUBLIC) +{ + currentSupported: Int! + minSupported: Int! + platform: String! +} + +type Mutation + @join__type(graph: API_KEYS) + @join__type(graph: NOTIFICATIONS) + @join__type(graph: PUBLIC) +{ + apiKeyCreate(input: ApiKeyCreateInput!): ApiKeyCreatePayload! @join__field(graph: API_KEYS) + apiKeyRevoke(input: ApiKeyRevokeInput!): ApiKeyRevokePayload! @join__field(graph: API_KEYS) + userDisableNotificationChannel(input: UserDisableNotificationChannelInput!): UserUpdateNotificationSettingsPayload! @join__field(graph: NOTIFICATIONS) + userEnableNotificationChannel(input: UserEnableNotificationChannelInput!): UserUpdateNotificationSettingsPayload! @join__field(graph: NOTIFICATIONS) + userDisableNotificationCategory(input: UserDisableNotificationCategoryInput!): UserUpdateNotificationSettingsPayload! @join__field(graph: NOTIFICATIONS) + userEnableNotificationCategory(input: UserEnableNotificationCategoryInput!): UserUpdateNotificationSettingsPayload! @join__field(graph: NOTIFICATIONS) + accountDelete: AccountDeletePayload! @join__field(graph: PUBLIC) + accountDisableNotificationCategory(input: AccountDisableNotificationCategoryInput!): AccountUpdateNotificationSettingsPayload! @join__field(graph: PUBLIC) + accountDisableNotificationChannel(input: AccountDisableNotificationChannelInput!): AccountUpdateNotificationSettingsPayload! @join__field(graph: PUBLIC) + accountEnableNotificationCategory(input: AccountEnableNotificationCategoryInput!): AccountUpdateNotificationSettingsPayload! @join__field(graph: PUBLIC) + accountEnableNotificationChannel(input: AccountEnableNotificationChannelInput!): AccountUpdateNotificationSettingsPayload! @join__field(graph: PUBLIC) + accountUpdateDefaultWalletId(input: AccountUpdateDefaultWalletIdInput!): AccountUpdateDefaultWalletIdPayload! @join__field(graph: PUBLIC) + accountUpdateDisplayCurrency(input: AccountUpdateDisplayCurrencyInput!): AccountUpdateDisplayCurrencyPayload! @join__field(graph: PUBLIC) + callbackEndpointAdd(input: CallbackEndpointAddInput!): CallbackEndpointAddPayload! @join__field(graph: PUBLIC) + callbackEndpointDelete(input: CallbackEndpointDeleteInput!): SuccessPayload! @join__field(graph: PUBLIC) + captchaCreateChallenge: CaptchaCreateChallengePayload! @join__field(graph: PUBLIC) + captchaRequestAuthCode(input: CaptchaRequestAuthCodeInput!): SuccessPayload! @join__field(graph: PUBLIC) + deviceNotificationTokenCreate(input: DeviceNotificationTokenCreateInput!): SuccessPayload! @join__field(graph: PUBLIC) + feedbackSubmit(input: FeedbackSubmitInput!): SuccessPayload! @join__field(graph: PUBLIC) + + """ + Actions a payment which is internal to the ledger e.g. it does + not use onchain/lightning. Returns payment status (success, + failed, pending, already_paid). + """ + intraLedgerPaymentSend(input: IntraLedgerPaymentSendInput!): PaymentSendPayload! @join__field(graph: PUBLIC) + + """ + Actions a payment which is internal to the ledger e.g. it does + not use onchain/lightning. Returns payment status (success, + failed, pending, already_paid). + """ + intraLedgerUsdPaymentSend(input: IntraLedgerUsdPaymentSendInput!): PaymentSendPayload! @join__field(graph: PUBLIC) + + """Sends a payment to a lightning address.""" + lnAddressPaymentSend(input: LnAddressPaymentSendInput!): PaymentSendPayload! @join__field(graph: PUBLIC) + + """ + Returns a lightning invoice for an associated wallet. + When invoice is paid the value will be credited to a BTC wallet. + Expires after 'expiresIn' or 24 hours. + """ + lnInvoiceCreate(input: LnInvoiceCreateInput!): LnInvoicePayload! @join__field(graph: PUBLIC) + + """ + Returns a lightning invoice for an associated wallet. + When invoice is paid the value will be credited to a BTC wallet. + Expires after 'expiresIn' or 24 hours. + """ + lnInvoiceCreateOnBehalfOfRecipient(input: LnInvoiceCreateOnBehalfOfRecipientInput!): LnInvoicePayload! @join__field(graph: PUBLIC) + lnInvoiceFeeProbe(input: LnInvoiceFeeProbeInput!): SatAmountPayload! @join__field(graph: PUBLIC) + + """ + Pay a lightning invoice using a balance from a wallet which is owned by the account of the current user. + Provided wallet can be USD or BTC and must have sufficient balance to cover amount in lightning invoice. + Returns payment status (success, failed, pending, already_paid). + """ + lnInvoicePaymentSend(input: LnInvoicePaymentInput!): PaymentSendPayload! @join__field(graph: PUBLIC) + + """ + Returns a lightning invoice for an associated wallet. + Can be used to receive any supported currency value (currently USD or BTC). + Expires after 'expiresIn' or 24 hours for BTC invoices or 5 minutes for USD invoices. + """ + lnNoAmountInvoiceCreate(input: LnNoAmountInvoiceCreateInput!): LnNoAmountInvoicePayload! @join__field(graph: PUBLIC) + + """ + Returns a lightning invoice for an associated wallet. + Can be used to receive any supported currency value (currently USD or BTC). + Expires after 'expiresIn' or 24 hours for BTC invoices or 5 minutes for USD invoices. + """ + lnNoAmountInvoiceCreateOnBehalfOfRecipient(input: LnNoAmountInvoiceCreateOnBehalfOfRecipientInput!): LnNoAmountInvoicePayload! @join__field(graph: PUBLIC) + lnNoAmountInvoiceFeeProbe(input: LnNoAmountInvoiceFeeProbeInput!): SatAmountPayload! @join__field(graph: PUBLIC) + + """ + Pay a lightning invoice using a balance from a wallet which is owned by the account of the current user. + Provided wallet must be BTC and must have sufficient balance to cover amount specified in mutation request. + Returns payment status (success, failed, pending, already_paid). + """ + lnNoAmountInvoicePaymentSend(input: LnNoAmountInvoicePaymentInput!): PaymentSendPayload! @join__field(graph: PUBLIC) + lnNoAmountUsdInvoiceFeeProbe(input: LnNoAmountUsdInvoiceFeeProbeInput!): CentAmountPayload! @join__field(graph: PUBLIC) + + """ + Pay a lightning invoice using a balance from a wallet which is owned by the account of the current user. + Provided wallet must be USD and have sufficient balance to cover amount specified in mutation request. + Returns payment status (success, failed, pending, already_paid). + """ + lnNoAmountUsdInvoicePaymentSend(input: LnNoAmountUsdInvoicePaymentInput!): PaymentSendPayload! @join__field(graph: PUBLIC) + + """ + Returns a lightning invoice denominated in satoshis for an associated wallet. + When invoice is paid the equivalent value at invoice creation will be credited to a USD wallet. + Expires after 'expiresIn' or 5 minutes (short expiry time because there is a USD/BTC exchange rate + associated with the amount). + """ + lnUsdInvoiceBtcDenominatedCreateOnBehalfOfRecipient(input: LnUsdInvoiceBtcDenominatedCreateOnBehalfOfRecipientInput!): LnInvoicePayload! @join__field(graph: PUBLIC) + + """ + Returns a lightning invoice denominated in satoshis for an associated wallet. + When invoice is paid the equivalent value at invoice creation will be credited to a USD wallet. + Expires after 'expiresIn' or 5 minutes (short expiry time because there is a USD/BTC exchange rate + associated with the amount). + """ + lnUsdInvoiceCreate(input: LnUsdInvoiceCreateInput!): LnInvoicePayload! @join__field(graph: PUBLIC) + + """ + Returns a lightning invoice denominated in satoshis for an associated wallet. + When invoice is paid the equivalent value at invoice creation will be credited to a USD wallet. + Expires after 'expiresIn' or 5 minutes (short expiry time because there is a USD/BTC exchange rate + associated with the amount). + """ + lnUsdInvoiceCreateOnBehalfOfRecipient(input: LnUsdInvoiceCreateOnBehalfOfRecipientInput!): LnInvoicePayload! @join__field(graph: PUBLIC) + lnUsdInvoiceFeeProbe(input: LnUsdInvoiceFeeProbeInput!): SatAmountPayload! @join__field(graph: PUBLIC) + + """Sends a payment to a lightning address.""" + lnurlPaymentSend(input: LnurlPaymentSendInput!): PaymentSendPayload! @join__field(graph: PUBLIC) + onChainAddressCreate(input: OnChainAddressCreateInput!): OnChainAddressPayload! @join__field(graph: PUBLIC) + onChainAddressCurrent(input: OnChainAddressCurrentInput!): OnChainAddressPayload! @join__field(graph: PUBLIC) + onChainPaymentSend(input: OnChainPaymentSendInput!): PaymentSendPayload! @join__field(graph: PUBLIC) + onChainPaymentSendAll(input: OnChainPaymentSendAllInput!): PaymentSendPayload! @join__field(graph: PUBLIC) + onChainUsdPaymentSend(input: OnChainUsdPaymentSendInput!): PaymentSendPayload! @join__field(graph: PUBLIC) + onChainUsdPaymentSendAsBtcDenominated(input: OnChainUsdPaymentSendAsBtcDenominatedInput!): PaymentSendPayload! @join__field(graph: PUBLIC) + quizClaim(input: QuizClaimInput!): QuizClaimPayload! @join__field(graph: PUBLIC) + quizCompleted(input: QuizCompletedInput!): QuizCompletedPayload! @join__field(graph: PUBLIC) @deprecated(reason: "Use quizClaim instead") + userContactUpdateAlias(input: UserContactUpdateAliasInput!): UserContactUpdateAliasPayload! @join__field(graph: PUBLIC) @deprecated(reason: "will be moved to AccountContact") + userEmailDelete: UserEmailDeletePayload! @join__field(graph: PUBLIC) + userEmailRegistrationInitiate(input: UserEmailRegistrationInitiateInput!): UserEmailRegistrationInitiatePayload! @join__field(graph: PUBLIC) + userEmailRegistrationValidate(input: UserEmailRegistrationValidateInput!): UserEmailRegistrationValidatePayload! @join__field(graph: PUBLIC) + userLogin(input: UserLoginInput!): AuthTokenPayload! @join__field(graph: PUBLIC) + userLoginUpgrade(input: UserLoginUpgradeInput!): UpgradePayload! @join__field(graph: PUBLIC) + userLogout(input: UserLogoutInput): SuccessPayload! @join__field(graph: PUBLIC) + userPhoneDelete: UserPhoneDeletePayload! @join__field(graph: PUBLIC) + userPhoneRegistrationInitiate(input: UserPhoneRegistrationInitiateInput!): SuccessPayload! @join__field(graph: PUBLIC) + userPhoneRegistrationValidate(input: UserPhoneRegistrationValidateInput!): UserPhoneRegistrationValidatePayload! @join__field(graph: PUBLIC) + userTotpDelete: UserTotpDeletePayload! @join__field(graph: PUBLIC) + userTotpRegistrationInitiate: UserTotpRegistrationInitiatePayload! @join__field(graph: PUBLIC) + userTotpRegistrationValidate(input: UserTotpRegistrationValidateInput!): UserTotpRegistrationValidatePayload! @join__field(graph: PUBLIC) + userUpdateLanguage(input: UserUpdateLanguageInput!): UserUpdateLanguagePayload! @join__field(graph: PUBLIC) + userUpdateUsername(input: UserUpdateUsernameInput!): UserUpdateUsernamePayload! @join__field(graph: PUBLIC) @deprecated(reason: "Username will be moved to @Handle in Accounts. Also SetUsername naming should be used instead of UpdateUsername to reflect the idempotency of Handles") +} + +type MyUpdatesPayload + @join__type(graph: PUBLIC) +{ + errors: [Error!]! + me: User + update: UserUpdate +} + +enum Network + @join__type(graph: PUBLIC) +{ + mainnet @join__enumValue(graph: PUBLIC) + regtest @join__enumValue(graph: PUBLIC) + signet @join__enumValue(graph: PUBLIC) + testnet @join__enumValue(graph: PUBLIC) +} + +scalar NotificationCategory + @join__type(graph: PUBLIC) + +enum NotificationChannel + @join__type(graph: PUBLIC) +{ + PUSH @join__enumValue(graph: PUBLIC) +} + +type NotificationChannelSettings + @join__type(graph: PUBLIC) +{ + disabledCategories: [NotificationCategory!]! + enabled: Boolean! +} + +type NotificationSettings + @join__type(graph: PUBLIC) +{ + push: NotificationChannelSettings! +} + +"""An address for an on-chain bitcoin destination""" +scalar OnChainAddress + @join__type(graph: PUBLIC) + +input OnChainAddressCreateInput + @join__type(graph: PUBLIC) +{ + walletId: WalletId! +} + +input OnChainAddressCurrentInput + @join__type(graph: PUBLIC) +{ + walletId: WalletId! +} + +type OnChainAddressPayload + @join__type(graph: PUBLIC) +{ + address: OnChainAddress + errors: [Error!]! +} + +input OnChainPaymentSendAllInput + @join__type(graph: PUBLIC) +{ + address: OnChainAddress! + memo: Memo + speed: PayoutSpeed! = FAST + walletId: WalletId! +} + +input OnChainPaymentSendInput + @join__type(graph: PUBLIC) +{ + address: OnChainAddress! + amount: SatAmount! + memo: Memo + speed: PayoutSpeed! = FAST + walletId: WalletId! +} + +type OnChainTxFee + @join__type(graph: PUBLIC) +{ + amount: SatAmount! +} + +scalar OnChainTxHash + @join__type(graph: PUBLIC) + +type OnChainUpdate + @join__type(graph: PUBLIC) +{ + amount: SatAmount! @deprecated(reason: "Deprecated in favor of transaction") + displayCurrencyPerSat: Float! @deprecated(reason: "Deprecated in favor of transaction") + transaction: Transaction! + txHash: OnChainTxHash! @deprecated(reason: "Deprecated in favor of transaction") + txNotificationType: TxNotificationType! + usdPerSat: Float! @deprecated(reason: "updated over displayCurrencyPerSat") + walletId: WalletId! @deprecated(reason: "Deprecated in favor of transaction") +} + +input OnChainUsdPaymentSendAsBtcDenominatedInput + @join__type(graph: PUBLIC) +{ + address: OnChainAddress! + amount: SatAmount! + memo: Memo + speed: PayoutSpeed! = FAST + walletId: WalletId! +} + +input OnChainUsdPaymentSendInput + @join__type(graph: PUBLIC) +{ + address: OnChainAddress! + amount: CentAmount! + memo: Memo + speed: PayoutSpeed! = FAST + walletId: WalletId! +} + +type OnChainUsdTxFee + @join__type(graph: PUBLIC) +{ + amount: CentAmount! +} + +type OneDayAccountLimit implements AccountLimit + @join__implements(graph: PUBLIC, interface: "AccountLimit") + @join__type(graph: PUBLIC) +{ + """ + The rolling time interval value in seconds for the current 24 hour period. + """ + interval: Seconds + + """ + The amount of cents remaining below the limit for the current 24 hour period. + """ + remainingLimit: CentAmount + + """The current maximum limit for a given 24 hour period.""" + totalLimit: CentAmount! +} + +"""An authentication code valid for a single use""" +scalar OneTimeAuthCode + @join__type(graph: PUBLIC) + +"""Information about pagination in a connection.""" +type PageInfo + @join__type(graph: PUBLIC) +{ + """When paginating forwards, the cursor to continue.""" + endCursor: String + + """When paginating forwards, are there more items?""" + hasNextPage: Boolean! + + """When paginating backwards, are there more items?""" + hasPreviousPage: Boolean! + + """When paginating backwards, the cursor to continue.""" + startCursor: String +} + +scalar PaymentHash + @join__type(graph: PUBLIC) + +type PaymentSendPayload + @join__type(graph: PUBLIC) +{ + errors: [Error!]! + status: PaymentSendResult + transaction: Transaction +} + +enum PaymentSendResult + @join__type(graph: PUBLIC) +{ + ALREADY_PAID @join__enumValue(graph: PUBLIC) + FAILURE @join__enumValue(graph: PUBLIC) + PENDING @join__enumValue(graph: PUBLIC) + SUCCESS @join__enumValue(graph: PUBLIC) +} + +enum PayoutSpeed + @join__type(graph: PUBLIC) +{ + FAST @join__enumValue(graph: PUBLIC) +} + +"""Phone number which includes country code""" +scalar Phone + @join__type(graph: PUBLIC) + +enum PhoneCodeChannelType + @join__type(graph: PUBLIC) +{ + SMS @join__enumValue(graph: PUBLIC) + WHATSAPP @join__enumValue(graph: PUBLIC) +} + +""" +Price amount expressed in base/offset. To calculate, use: `base / 10^offset` +""" +type Price + @join__type(graph: PUBLIC) +{ + base: SafeInt! + currencyUnit: String! + formattedAmount: String! + offset: Int! +} + +"""The range for the X axis in the BTC price graph""" +enum PriceGraphRange + @join__type(graph: PUBLIC) +{ + FIVE_YEARS @join__enumValue(graph: PUBLIC) + ONE_DAY @join__enumValue(graph: PUBLIC) + ONE_MONTH @join__enumValue(graph: PUBLIC) + ONE_WEEK @join__enumValue(graph: PUBLIC) + ONE_YEAR @join__enumValue(graph: PUBLIC) +} + +input PriceInput + @join__type(graph: PUBLIC) +{ + amount: SatAmount! + amountCurrencyUnit: ExchangeCurrencyUnit! + priceCurrencyUnit: ExchangeCurrencyUnit! +} + +interface PriceInterface + @join__type(graph: PUBLIC) +{ + base: SafeInt! + currencyUnit: String! @deprecated(reason: "Deprecated due to type renaming") + offset: Int! +} + +"""Price of 1 sat in base/offset. To calculate, use: `base / 10^offset`""" +type PriceOfOneSatInMinorUnit implements PriceInterface + @join__implements(graph: PUBLIC, interface: "PriceInterface") + @join__type(graph: PUBLIC) +{ + base: SafeInt! + currencyUnit: String! @deprecated(reason: "Deprecated due to type renaming") + offset: Int! +} + +""" +Price of 1 sat or 1 usd cent in base/offset. To calculate, use: `base / 10^offset` +""" +type PriceOfOneSettlementMinorUnitInDisplayMinorUnit implements PriceInterface + @join__implements(graph: PUBLIC, interface: "PriceInterface") + @join__type(graph: PUBLIC) +{ + base: SafeInt! + currencyUnit: String! @deprecated(reason: "Deprecated due to type renaming") + formattedAmount: String! @deprecated(reason: "Deprecated please use `base / 10^offset`") + offset: Int! +} + +""" +Price of 1 usd cent in base/offset. To calculate, use: `base / 10^offset` +""" +type PriceOfOneUsdCentInMinorUnit implements PriceInterface + @join__implements(graph: PUBLIC, interface: "PriceInterface") + @join__type(graph: PUBLIC) +{ + base: SafeInt! + currencyUnit: String! @deprecated(reason: "Deprecated due to type renaming") + offset: Int! +} + +type PricePayload + @join__type(graph: PUBLIC) +{ + errors: [Error!]! + price: Price +} + +type PricePoint + @join__type(graph: PUBLIC) +{ + price: Price! + + """ + Unix timestamp (number of seconds elapsed since January 1, 1970 00:00:00 UTC) + """ + timestamp: Timestamp! +} + +""" +A public view of a generic wallet which stores value in one of our supported currencies. +""" +type PublicWallet + @join__type(graph: PUBLIC) +{ + currency: WalletCurrency! + id: ID! + walletCurrency: WalletCurrency! @deprecated(reason: "Shifting property to 'currency'") +} + +type Query + @join__type(graph: API_KEYS) + @join__type(graph: NOTIFICATIONS) + @join__type(graph: PUBLIC) +{ + accountDefaultWallet(username: Username!, walletCurrency: WalletCurrency): PublicWallet! @join__field(graph: PUBLIC) + btcPriceList(range: PriceGraphRange!): [PricePoint] @join__field(graph: PUBLIC) + businessMapMarkers: [MapMarker!]! @join__field(graph: PUBLIC) + currencyList: [Currency!]! @join__field(graph: PUBLIC) + globals: Globals @join__field(graph: PUBLIC) + lnInvoicePaymentStatus(input: LnInvoicePaymentStatusInput!): LnInvoicePaymentStatusPayload! @join__field(graph: PUBLIC) + me: User @join__field(graph: PUBLIC) + mobileVersions: [MobileVersions] @join__field(graph: PUBLIC) + onChainTxFee(address: OnChainAddress!, amount: SatAmount!, speed: PayoutSpeed! = FAST, walletId: WalletId!): OnChainTxFee! @join__field(graph: PUBLIC) + onChainUsdTxFee(address: OnChainAddress!, amount: CentAmount!, speed: PayoutSpeed! = FAST, walletId: WalletId!): OnChainUsdTxFee! @join__field(graph: PUBLIC) + onChainUsdTxFeeAsBtcDenominated(address: OnChainAddress!, amount: SatAmount!, speed: PayoutSpeed! = FAST, walletId: WalletId!): OnChainUsdTxFee! @join__field(graph: PUBLIC) + + """Returns 1 Sat and 1 Usd Cent price for the given currency""" + realtimePrice(currency: DisplayCurrency = "USD"): RealtimePrice! @join__field(graph: PUBLIC) + userDefaultWalletId(username: Username!): WalletId! @join__field(graph: PUBLIC) @deprecated(reason: "will be migrated to AccountDefaultWalletId") + usernameAvailable(username: Username!): Boolean @join__field(graph: PUBLIC) +} + +type Quiz + @join__type(graph: PUBLIC) +{ + """The reward in Satoshis for the quiz question""" + amount: SatAmount! + completed: Boolean! + id: ID! + notBefore: Timestamp +} + +input QuizClaimInput + @join__type(graph: PUBLIC) +{ + id: ID! +} + +type QuizClaimPayload + @join__type(graph: PUBLIC) +{ + errors: [Error!]! + quizzes: [Quiz!]! +} + +input QuizCompletedInput + @join__type(graph: PUBLIC) +{ + id: ID! +} + +type QuizCompletedPayload + @join__type(graph: PUBLIC) +{ + errors: [Error!]! + quiz: Quiz +} + +type RealtimePrice + @join__type(graph: PUBLIC) +{ + btcSatPrice: PriceOfOneSatInMinorUnit! + denominatorCurrency: DisplayCurrency! + id: ID! + + """ + Unix timestamp (number of seconds elapsed since January 1, 1970 00:00:00 UTC) + """ + timestamp: Timestamp! + usdCentPrice: PriceOfOneUsdCentInMinorUnit! +} + +input RealtimePriceInput + @join__type(graph: PUBLIC) +{ + currency: DisplayCurrency = "USD" +} + +type RealtimePricePayload + @join__type(graph: PUBLIC) +{ + errors: [Error!]! + realtimePrice: RealtimePrice +} + +""" +Non-fractional signed whole numeric value between -(2^53) + 1 and 2^53 - 1 +""" +scalar SafeInt + @join__type(graph: PUBLIC) + +"""(Positive) Satoshi amount""" +scalar SatAmount + @join__type(graph: PUBLIC) + +type SatAmountPayload + @join__type(graph: PUBLIC) +{ + amount: SatAmount + errors: [Error!]! +} + +"""(Positive) amount of seconds""" +scalar Seconds + @join__type(graph: PUBLIC) + +union SettlementVia + @join__type(graph: PUBLIC) + @join__unionMember(graph: PUBLIC, member: "SettlementViaIntraLedger") + @join__unionMember(graph: PUBLIC, member: "SettlementViaLn") + @join__unionMember(graph: PUBLIC, member: "SettlementViaOnChain") + = SettlementViaIntraLedger | SettlementViaLn | SettlementViaOnChain + +type SettlementViaIntraLedger + @join__type(graph: PUBLIC) +{ + """ + Settlement destination: Could be null if the payee does not have a username + """ + counterPartyUsername: Username + counterPartyWalletId: WalletId + preImage: LnPaymentPreImage +} + +type SettlementViaLn + @join__type(graph: PUBLIC) +{ + paymentSecret: LnPaymentSecret @deprecated(reason: "Shifting property to 'preImage' to improve granularity of the LnPaymentSecret type") + preImage: LnPaymentPreImage +} + +type SettlementViaOnChain + @join__type(graph: PUBLIC) +{ + arrivalInMempoolEstimatedAt: Timestamp + transactionHash: OnChainTxHash + vout: Int +} + +"""An amount (of a currency) that can be negative (e.g. in a transaction)""" +scalar SignedAmount + @join__type(graph: PUBLIC) + +""" +A string amount (of a currency) that can be negative (e.g. in a transaction) +""" +scalar SignedDisplayMajorAmount + @join__type(graph: PUBLIC) + +type Subscription + @join__type(graph: PUBLIC) +{ + lnInvoicePaymentStatus(input: LnInvoicePaymentStatusInput!): LnInvoicePaymentStatusPayload! + myUpdates: MyUpdatesPayload! + price(input: PriceInput!): PricePayload! + + """Returns the price of 1 satoshi""" + realtimePrice(input: RealtimePriceInput!): RealtimePricePayload! +} + +type SuccessPayload + @join__type(graph: PUBLIC) +{ + errors: [Error!]! + success: Boolean +} + +""" +Timestamp field, serialized as Unix time (the number of seconds since the Unix epoch) +""" +scalar Timestamp + @join__type(graph: API_KEYS) + @join__type(graph: PUBLIC) + +"""A time-based one-time password""" +scalar TotpCode + @join__type(graph: PUBLIC) + +"""An id to be passed between set and verify for confirming totp""" +scalar TotpRegistrationId + @join__type(graph: PUBLIC) + +"""A secret to generate time-based one-time password""" +scalar TotpSecret + @join__type(graph: PUBLIC) + +""" +Give details about an individual transaction. +Galoy have a smart routing system which is automatically +settling intraledger when both the payer and payee use the same wallet +therefore it's possible the transactions is being initiated onchain +or with lightning but settled intraledger. +""" +type Transaction + @join__type(graph: PUBLIC) +{ + createdAt: Timestamp! + direction: TxDirection! + id: ID! + + """From which protocol the payment has been initiated.""" + initiationVia: InitiationVia! + memo: Memo + + """Amount of the settlement currency sent or received.""" + settlementAmount: SignedAmount! + + """Wallet currency for transaction.""" + settlementCurrency: WalletCurrency! + settlementDisplayAmount: SignedDisplayMajorAmount! + settlementDisplayCurrency: DisplayCurrency! + settlementDisplayFee: SignedDisplayMajorAmount! + settlementFee: SignedAmount! + + """Price in WALLETCURRENCY/SETTLEMENTUNIT at time of settlement.""" + settlementPrice: PriceOfOneSettlementMinorUnitInDisplayMinorUnit! + + """To which protocol the payment has settled on.""" + settlementVia: SettlementVia! + status: TxStatus! +} + +"""A connection to a list of items.""" +type TransactionConnection + @join__type(graph: PUBLIC) +{ + """A list of edges.""" + edges: [TransactionEdge!] + + """Information to aid in pagination.""" + pageInfo: PageInfo! +} + +"""An edge in a connection.""" +type TransactionEdge + @join__type(graph: PUBLIC) +{ + """A cursor for use in pagination""" + cursor: String! + + """The item at the end of the edge""" + node: Transaction! +} + +enum TxDirection + @join__type(graph: PUBLIC) +{ + RECEIVE @join__enumValue(graph: PUBLIC) + SEND @join__enumValue(graph: PUBLIC) +} + +enum TxNotificationType + @join__type(graph: PUBLIC) +{ + IntraLedgerPayment @join__enumValue(graph: PUBLIC) + IntraLedgerReceipt @join__enumValue(graph: PUBLIC) + LigtningReceipt @join__enumValue(graph: PUBLIC) + OnchainPayment @join__enumValue(graph: PUBLIC) + OnchainReceipt @join__enumValue(graph: PUBLIC) + OnchainReceiptPending @join__enumValue(graph: PUBLIC) +} + +enum TxStatus + @join__type(graph: PUBLIC) +{ + FAILURE @join__enumValue(graph: PUBLIC) + PENDING @join__enumValue(graph: PUBLIC) + SUCCESS @join__enumValue(graph: PUBLIC) +} + +type UpgradePayload + @join__type(graph: PUBLIC) +{ + authToken: AuthToken + errors: [Error!]! + success: Boolean! +} + +""" +A wallet belonging to an account which contains a USD balance and a list of transactions. +""" +type UsdWallet implements Wallet + @join__implements(graph: PUBLIC, interface: "Wallet") + @join__type(graph: PUBLIC) +{ + accountId: ID! + balance: SignedAmount! + id: ID! + invoiceByPaymentHash(paymentHash: PaymentHash!): Invoice! + + """A list of all invoices associated with walletIds optionally passed.""" + invoices( + """Returns the items in the list that come after the specified cursor.""" + after: String + + """Returns the items in the list that come before the specified cursor.""" + before: String + + """Returns the first n items from the list.""" + first: Int + + """Returns the last n items from the list.""" + last: Int + ): InvoiceConnection + + """An unconfirmed incoming onchain balance.""" + pendingIncomingBalance: SignedAmount! + pendingIncomingTransactions: [Transaction!]! + pendingIncomingTransactionsByAddress( + """Returns the items that include this address.""" + address: OnChainAddress! + ): [Transaction!]! + transactionById(transactionId: ID!): Transaction! + transactions( + """Returns the items in the list that come after the specified cursor.""" + after: String + + """Returns the items in the list that come before the specified cursor.""" + before: String + + """Returns the first n items from the list.""" + first: Int + + """Returns the last n items from the list.""" + last: Int + ): TransactionConnection + transactionsByAddress( + """Returns the items that include this address.""" + address: OnChainAddress! + + """Returns the items in the list that come after the specified cursor.""" + after: String + + """Returns the items in the list that come before the specified cursor.""" + before: String + + """Returns the first n items from the list.""" + first: Int + + """Returns the last n items from the list.""" + last: Int + ): TransactionConnection + transactionsByPaymentHash(paymentHash: PaymentHash!): [Transaction!]! + walletCurrency: WalletCurrency! +} + +type User + @join__type(graph: API_KEYS, key: "id", extension: true) + @join__type(graph: NOTIFICATIONS, key: "id", extension: true) + @join__type(graph: PUBLIC) +{ + id: ID! + apiKeys: [ApiKey!]! @join__field(graph: API_KEYS) + notificationSettings: UserNotificationSettings! @join__field(graph: NOTIFICATIONS) + + """ + Get single contact details. + Can include the transactions associated with the contact. + """ + contactByUsername(username: Username!): UserContact! @join__field(graph: PUBLIC) @deprecated(reason: "will be moved to Accounts") + + """ + Get full list of contacts. + Can include the transactions associated with each contact. + """ + contacts: [UserContact!]! @join__field(graph: PUBLIC) @deprecated(reason: "will be moved to account") + createdAt: Timestamp! @join__field(graph: PUBLIC) + defaultAccount: Account! @join__field(graph: PUBLIC) + + """Email address""" + email: Email @join__field(graph: PUBLIC) + + """ + Preferred language for user. + When value is 'default' the intent is to use preferred language from OS settings. + """ + language: Language! @join__field(graph: PUBLIC) + + """Phone number with international calling code.""" + phone: Phone @join__field(graph: PUBLIC) + + """Whether TOTP is enabled for this user.""" + totpEnabled: Boolean! @join__field(graph: PUBLIC) + + """Optional immutable user friendly identifier.""" + username: Username @join__field(graph: PUBLIC) @deprecated(reason: "will be moved to @Handle in Account and Wallet") +} + +type UserContact + @join__type(graph: PUBLIC) +{ + """ + Alias the user can set for this contact. + Only the user can see the alias attached to their contact. + """ + alias: ContactAlias + id: Username! + + """Paginated list of transactions sent to/from this contact.""" + transactions( + """Returns the items in the list that come after the specified cursor.""" + after: String + + """Returns the items in the list that come before the specified cursor.""" + before: String + + """Returns the first n items from the list.""" + first: Int + + """Returns the last n items from the list.""" + last: Int + ): TransactionConnection + transactionsCount: Int! + + """Actual identifier of the contact.""" + username: Username! +} + +input UserContactUpdateAliasInput + @join__type(graph: PUBLIC) +{ + alias: ContactAlias! + username: Username! +} + +type UserContactUpdateAliasPayload + @join__type(graph: PUBLIC) +{ + contact: UserContact + errors: [Error!]! +} + +input UserDisableNotificationCategoryInput + @join__type(graph: NOTIFICATIONS) +{ + channel: UserNotificationChannel! + category: UserNotificationCategory! +} + +input UserDisableNotificationChannelInput + @join__type(graph: NOTIFICATIONS) +{ + channel: UserNotificationChannel! +} + +type UserEmailDeletePayload + @join__type(graph: PUBLIC) +{ + errors: [Error!]! + me: User +} + +input UserEmailRegistrationInitiateInput + @join__type(graph: PUBLIC) +{ + email: EmailAddress! +} + +type UserEmailRegistrationInitiatePayload + @join__type(graph: PUBLIC) +{ + emailRegistrationId: EmailRegistrationId + errors: [Error!]! + me: User +} + +input UserEmailRegistrationValidateInput + @join__type(graph: PUBLIC) +{ + code: OneTimeAuthCode! + emailRegistrationId: EmailRegistrationId! +} + +type UserEmailRegistrationValidatePayload + @join__type(graph: PUBLIC) +{ + errors: [Error!]! + me: User +} + +input UserEnableNotificationCategoryInput + @join__type(graph: NOTIFICATIONS) +{ + channel: UserNotificationChannel! + category: UserNotificationCategory! +} + +input UserEnableNotificationChannelInput + @join__type(graph: NOTIFICATIONS) +{ + channel: UserNotificationChannel! +} + +input UserLoginInput + @join__type(graph: PUBLIC) +{ + code: OneTimeAuthCode! + phone: Phone! +} + +input UserLoginUpgradeInput + @join__type(graph: PUBLIC) +{ + code: OneTimeAuthCode! + phone: Phone! +} + +input UserLogoutInput + @join__type(graph: PUBLIC) +{ + deviceToken: String! +} + +"""Unique identifier of a user""" +scalar Username + @join__type(graph: PUBLIC) + +enum UserNotificationCategory + @join__type(graph: NOTIFICATIONS) +{ + CIRCLES @join__enumValue(graph: NOTIFICATIONS) + PAYMENTS @join__enumValue(graph: NOTIFICATIONS) + BALANCE @join__enumValue(graph: NOTIFICATIONS) + ADMIN_NOTIFICATION @join__enumValue(graph: NOTIFICATIONS) +} + +enum UserNotificationChannel + @join__type(graph: NOTIFICATIONS) +{ + PUSH @join__enumValue(graph: NOTIFICATIONS) +} + +type UserNotificationChannelSettings + @join__type(graph: NOTIFICATIONS) +{ + enabled: Boolean! + disabledCategories: [UserNotificationCategory!]! +} + +type UserNotificationSettings + @join__type(graph: NOTIFICATIONS) +{ + push: UserNotificationChannelSettings! +} + +type UserPhoneDeletePayload + @join__type(graph: PUBLIC) +{ + errors: [Error!]! + me: User +} + +input UserPhoneRegistrationInitiateInput + @join__type(graph: PUBLIC) +{ + channel: PhoneCodeChannelType + phone: Phone! +} + +input UserPhoneRegistrationValidateInput + @join__type(graph: PUBLIC) +{ + code: OneTimeAuthCode! + phone: Phone! +} + +type UserPhoneRegistrationValidatePayload + @join__type(graph: PUBLIC) +{ + errors: [Error!]! + me: User +} + +type UserTotpDeletePayload + @join__type(graph: PUBLIC) +{ + errors: [Error!]! + me: User +} + +type UserTotpRegistrationInitiatePayload + @join__type(graph: PUBLIC) +{ + errors: [Error!]! + totpRegistrationId: TotpRegistrationId + totpSecret: TotpSecret +} + +input UserTotpRegistrationValidateInput + @join__type(graph: PUBLIC) +{ + authToken: AuthToken + totpCode: TotpCode! + totpRegistrationId: TotpRegistrationId! +} + +type UserTotpRegistrationValidatePayload + @join__type(graph: PUBLIC) +{ + errors: [Error!]! + me: User +} + +union UserUpdate + @join__type(graph: PUBLIC) + @join__unionMember(graph: PUBLIC, member: "IntraLedgerUpdate") + @join__unionMember(graph: PUBLIC, member: "LnUpdate") + @join__unionMember(graph: PUBLIC, member: "OnChainUpdate") + @join__unionMember(graph: PUBLIC, member: "Price") + @join__unionMember(graph: PUBLIC, member: "RealtimePrice") + = IntraLedgerUpdate | LnUpdate | OnChainUpdate | Price | RealtimePrice + +input UserUpdateLanguageInput + @join__type(graph: PUBLIC) +{ + language: Language! +} + +type UserUpdateLanguagePayload + @join__type(graph: PUBLIC) +{ + errors: [Error!]! + user: User +} + +type UserUpdateNotificationSettingsPayload + @join__type(graph: NOTIFICATIONS) +{ + notificationSettings: UserNotificationSettings! +} + +input UserUpdateUsernameInput + @join__type(graph: PUBLIC) +{ + username: Username! +} + +type UserUpdateUsernamePayload + @join__type(graph: PUBLIC) +{ + errors: [Error!]! + user: User +} + +""" +A generic wallet which stores value in one of our supported currencies. +""" +interface Wallet + @join__type(graph: PUBLIC) +{ + accountId: ID! + balance: SignedAmount! + id: ID! + invoiceByPaymentHash( + """ + The lightning invoice with the matching paymentHash belonging to this wallet. + """ + paymentHash: PaymentHash! + ): Invoice! + invoices( + """Returns the items in the list that come after the specified cursor.""" + after: String + + """Returns the items in the list that come before the specified cursor.""" + before: String + + """Returns the first n items from the list.""" + first: Int + + """Returns the last n items from the list.""" + last: Int + ): InvoiceConnection + pendingIncomingBalance: SignedAmount! + + """ + Pending incoming OnChain transactions. When transactions + are confirmed they will receive a new id and be found in the transactions + list. Transactions are ordered anti-chronologically, + ie: the newest transaction will be first + """ + pendingIncomingTransactions: [Transaction!]! + + """ + Pending incoming OnChain transactions. When transactions + are confirmed they will receive a new id and be found in the transactions + list. Transactions are ordered anti-chronologically, + ie: the newest transaction will be first + """ + pendingIncomingTransactionsByAddress( + """Returns the items that include this address.""" + address: OnChainAddress! + ): [Transaction!]! + transactionById(transactionId: ID!): Transaction! + + """ + Transactions are ordered anti-chronologically, + ie: the newest transaction will be first + """ + transactions( + """Returns the items in the list that come after the specified cursor.""" + after: String + + """Returns the items in the list that come before the specified cursor.""" + before: String + + """Returns the first n items from the list.""" + first: Int + + """Returns the last n items from the list.""" + last: Int + ): TransactionConnection + + """ + Transactions are ordered anti-chronologically, + ie: the newest transaction will be first + """ + transactionsByAddress( + """Returns the items that include this address.""" + address: OnChainAddress! + + """Returns the items in the list that come after the specified cursor.""" + after: String + + """Returns the items in the list that come before the specified cursor.""" + before: String + + """Returns the first n items from the list.""" + first: Int + + """Returns the last n items from the list.""" + last: Int + ): TransactionConnection + + """ + Returns the transactions that include this paymentHash. This should be a list of size one for a received lightning payment. This can be more that one transaction for a sent lightning payment. + """ + transactionsByPaymentHash( + """The payment hash of the lightning invoice paid in this transaction.""" + paymentHash: PaymentHash! + ): [Transaction!]! + walletCurrency: WalletCurrency! +} + +enum WalletCurrency + @join__type(graph: PUBLIC) +{ + BTC @join__enumValue(graph: PUBLIC) + USD @join__enumValue(graph: PUBLIC) +} + +"""Unique identifier of a wallet""" +scalar WalletId + @join__type(graph: PUBLIC) \ No newline at end of file diff --git a/dev/vendor/galoy-quickstart/dev/config/bitcoind/bitcoin.conf b/dev/vendor/galoy-quickstart/dev/config/bitcoind/bitcoin.conf new file mode 100644 index 0000000000..d04fb1b417 --- /dev/null +++ b/dev/vendor/galoy-quickstart/dev/config/bitcoind/bitcoin.conf @@ -0,0 +1,19 @@ +rpcuser=rpcuser +rpcpassword=rpcpassword +debug=mempool +debug=rpc +server=1 +txindex=1 +printtoconsole=1 +zmqpubrawtx=tcp://0.0.0.0:28333 +zmqpubrawblock=tcp://0.0.0.0:28332 +blockfilterindex=1 +bind=0.0.0.0 +fallbackfee=0.0002 +rpcallowip=0.0.0.0/0 +regtest=1 +[regtest] +bind=0.0.0.0 +fallbackfee=0.0002 +rpcallowip=0.0.0.0/0 +rpcbind=0.0.0.0 diff --git a/dev/vendor/galoy-quickstart/dev/config/bitcoind/bitcoind_signer_descriptors.json b/dev/vendor/galoy-quickstart/dev/config/bitcoind/bitcoind_signer_descriptors.json new file mode 100644 index 0000000000..fc0a17989b --- /dev/null +++ b/dev/vendor/galoy-quickstart/dev/config/bitcoind/bitcoind_signer_descriptors.json @@ -0,0 +1 @@ +[{"active":true,"desc":"wpkh([6f2fa1b2/84'/0'/0']tprv8gXB88g1VCScmqPp8WcetpJPRxix24fRJJ6FniYCcCUEFMREDrCfwd34zWXPiY5MW2xp8e1Z6EeBrh74zMSgfQQmTorWtE1zyBtv7yxdcoa/0/*)#88k4937c","timestamp":0},{"active":true,"desc":"wpkh([6f2fa1b2/84'/0'/0']tprv8gXB88g1VCScmqPp8WcetpJPRxix24fRJJ6FniYCcCUEFMREDrCfwd34zWXPiY5MW2xp8e1Z6EeBrh74zMSgfQQmTorWtE1zyBtv7yxdcoa/1/*)#knn5cywq","internal":true,"timestamp":0}] diff --git a/dev/vendor/galoy-quickstart/dev/config/bria.yml b/dev/vendor/galoy-quickstart/dev/config/bria.yml new file mode 100644 index 0000000000..25c27d310a --- /dev/null +++ b/dev/vendor/galoy-quickstart/dev/config/bria.yml @@ -0,0 +1,8 @@ +app: + blockchain: + network: regtest + electrum_url: fulcrum:50001 +tracing: + host: "otel-agent" + port: 4318 + service_name: "bria-dev" diff --git a/dev/vendor/galoy-quickstart/dev/config/fulcrum/fulcrum.conf b/dev/vendor/galoy-quickstart/dev/config/fulcrum/fulcrum.conf new file mode 100644 index 0000000000..8697258865 --- /dev/null +++ b/dev/vendor/galoy-quickstart/dev/config/fulcrum/fulcrum.conf @@ -0,0 +1,7 @@ +bitcoind = bitcoind:18443 +rpcuser = rpcuser +rpcpassword = rpcpassword +peering = false +announce = false +tcp = 0.0.0.0:50001 +ssl = 0.0.0.0:50002 diff --git a/dev/vendor/galoy-quickstart/dev/config/fulcrum/tls.cert b/dev/vendor/galoy-quickstart/dev/config/fulcrum/tls.cert new file mode 100644 index 0000000000..82f5259186 --- /dev/null +++ b/dev/vendor/galoy-quickstart/dev/config/fulcrum/tls.cert @@ -0,0 +1,19 @@ +-----BEGIN CERTIFICATE----- +MIIDBTCCAe2gAwIBAgIUKCSR4otDtA4+ow5z5zL9zc1CI10wDQYJKoZIhvcNAQEL +BQAwEjEQMA4GA1UECgwHRnVsY3J1bTAeFw0yMjExMjkxMDUzNDFaFw0zMjExMjYx +MDUzNDFaMBIxEDAOBgNVBAoMB0Z1bGNydW0wggEiMA0GCSqGSIb3DQEBAQUAA4IB +DwAwggEKAoIBAQDasNdsbz47BDEjzKLeG4RxOqMikrBY6fQd0+8pt8Fh/qSaF2lG +NpLbADDcszyddb0GD5tYQe7YBIyrexp9Q1gvejj1zuagXwlSYfrSkiDB3nBYreSl +wq4i87VjCMX5Fr270S3mHfptg5zbPgQvvTvnD0Y7Ur9lriNydWp9Qz6TLWWYVhui +yxLrtsxv6hRDndlkIxDbZt9kr6yzLroBtXFEFSCeROb1sE2ouVXC89eAlcpvWZF6 +MMnlAkECRS5m3QtKyYtTQ0FTGBrAN2xUnirR9z+wpAOu3S/AjEt4AC1ome75tiJv +rtCIaf438QhNerb/sQmyHXIpjw6KZxADKS3RAgMBAAGjUzBRMB0GA1UdDgQWBBS0 +xHEskJjxCg8F1YYT0NkzBVFsTDAfBgNVHSMEGDAWgBS0xHEskJjxCg8F1YYT0Nkz +BVFsTDAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBCwUAA4IBAQCwxhxRCfa1 +DXfFP+BM9OwDldNC9B66d/6hueaY26YJxcLvuKcAm+0MwciNFnWhb9yiY2wnWaZ6 +zA6VKuxCrVU7egg5gG2+lZYjAiQOkFtVNHGEIjVTow4GJAkJGjH/B9J2teHKR1a6 +XDJ5xKLAIM7hnKVjIM7cA/Y3Q/AsR/uzp4GOccqHX3g/AKKLFahLCkVv5CeIrl+y +kPv/3jXbP71iJPhG2j74EVPLeQ0qKAb03vz2Y2HaSBripGQEwnx7MoQnbRhYx00Y ++LG1WGYeNOEXfT8trewl+gfsoLenlDTLukIfjjvQ5dRDA9pD1ij+1+jz/XCyQ7w5 +LzhYnJBwIGpt +-----END CERTIFICATE----- diff --git a/dev/vendor/galoy-quickstart/dev/config/fulcrum/tls.key b/dev/vendor/galoy-quickstart/dev/config/fulcrum/tls.key new file mode 100644 index 0000000000..d2d9c6affd --- /dev/null +++ b/dev/vendor/galoy-quickstart/dev/config/fulcrum/tls.key @@ -0,0 +1,28 @@ +-----BEGIN PRIVATE KEY----- +MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDasNdsbz47BDEj +zKLeG4RxOqMikrBY6fQd0+8pt8Fh/qSaF2lGNpLbADDcszyddb0GD5tYQe7YBIyr +exp9Q1gvejj1zuagXwlSYfrSkiDB3nBYreSlwq4i87VjCMX5Fr270S3mHfptg5zb +PgQvvTvnD0Y7Ur9lriNydWp9Qz6TLWWYVhuiyxLrtsxv6hRDndlkIxDbZt9kr6yz +LroBtXFEFSCeROb1sE2ouVXC89eAlcpvWZF6MMnlAkECRS5m3QtKyYtTQ0FTGBrA +N2xUnirR9z+wpAOu3S/AjEt4AC1ome75tiJvrtCIaf438QhNerb/sQmyHXIpjw6K +ZxADKS3RAgMBAAECggEBAJB5g9f/Jf2XJ1+fMXnKdBTZyCxu/FHBPaT2/mlxHDDB +Kb0i+kmIhDxqQ92KC+F6hwYaCWalKEVNvCENktJuSzQSas75gSMxpdbnI+043Ks3 +aMEtIIDhvGka2Bo1EZUdkPsjlk8QPwFakaXFsr5XJdvgG2XVpNxnzsMvDsryQcS4 +X+foFXRFPWjTvof9v68WyeIUWVKumVA/285TmS6jMqsYkDHKxg25CiBr95WJKsSo ++o1sBmj9DvJXGxwo47MGX65dZxU4PVTBA9ABq3kA9SnOpzr0Tz27eJl8Er6zOENy +9JmijNLDTuPRwxqDMjW/He5NHz13vnXf5FasGWhfuIECgYEA+isl7jPFDAybPH1b +dL0d8NEwl8CloZ9a0AmsQZ8BGi6gn/uQAtNfZk2Q9vFMulBmppMnYTDrYh7KwZ8u +UjiSg3QIKZgixtZQelDxAv5G8VpR20DeQwn4pxBgvo0WeGKlxV2WdbouwhW1OBoj +fRnTHfzxCkqsS6B+mff8awsKfv8CgYEA38naezhfm4G54wkYUnD8cx4GvuGRHHoR +DcXMyPm2+zub4sYeVDCzh6eoIkNc8TW+YEZNsiYOxYfuYiKLmlw1m2TeZKXwf7Vc +9OkX5Is+7ARlJlG27xU4OLfOMrIdaibPUFLDTWknTryu3hLKoWGHsbfB/7hJoUBq +7np6odIhIy8CgYBgzuu5txzsocA880G99iUs+La2Mt2lorYQxX18U1yo1hxgbIf5 +H/TN8PxFI3GOs+hVU6KskLK14LaToNbbCHtiFTfHaNEkYvD3tHTftKidY1dD4mFg +Te6EL+lQM+bbJUmDC8lau3a2spHTKQJMuf6hny1jzyvHhE8ZpAZxIe+o3wKBgQCt +y0UxjIYzbnu+JcINxFFJ1XfHpcXcJ7A20fZH3iaM1a4qX1IOcAP8xed9NHNpoCNJ +AVA1mfi+zuICtHFWX2YCWEOeRoCPrXmTebJkev9Sq9ch+zPmWMRgx94K4OiXF6zI +5H1oENHGBCKJtG5JBkUrb1nqDmSgJjblHZk/MsEpYQKBgBoI4QpQ0yhn812H0BJV +T1t0SM9+bkJC40ogme0R5/gUz8aDe+A2WHN/HH+q6QKLvkLxBCH8y7RufoKSN2XB +IqtTRZQX/yQyY/AZB7Rse29fmomDGa3/xj1LK33zhYqwMgDmisymu3XER6EwGRV6 +RTv9SXp8+92eNOwSJ63hEZV9 +-----END PRIVATE KEY----- diff --git a/dev/vendor/galoy-quickstart/dev/config/lnd/lnd.conf b/dev/vendor/galoy-quickstart/dev/config/lnd/lnd.conf new file mode 100644 index 0000000000..f7d9fd4b6e --- /dev/null +++ b/dev/vendor/galoy-quickstart/dev/config/lnd/lnd.conf @@ -0,0 +1,48 @@ +[Application Options] + +accept-keysend=1 +allow-circular-route=1 +debuglevel=error +default-remote-max-htlcs=50 +maxchansize=500000000 +noseedbackup=1 +prometheus.enable=1 +prometheus.listen=0.0.0.0:9092 +restlisten=0.0.0.0:8080 +rpclisten=0.0.0.0:10009 +tlsextradomain=lnd-outside-1 +tlsextradomain=lnd-outside-2 +tlsextradomain=lnd1 +tlsextradomain=lnd2 +gc-canceled-invoices-on-the-fly=true +gc-canceled-invoices-on-startup=true +trickledelay=2000 +historicalsyncinterval=2s +tlscertduration=100800h + +[Bitcoin] + +bitcoin.active=true +bitcoin.defaultchanconfs=0 +bitcoin.node=bitcoind +bitcoin.regtest=true +; bitcoin.minhtlc=1 +bitcoin.minhtlcout=1 + +[Bitcoind] + +bitcoind.rpchost=bitcoind:18443 +bitcoind.rpcpass=rpcpassword +bitcoind.rpcuser=rpcuser +bitcoind.zmqpubrawblock=tcp://bitcoind:28332 +bitcoind.zmqpubrawtx=tcp://bitcoind:28333 + +[protocol] + +protocol.wumbo-channels=1 + +[routing] + +; Should only be used with regtest. +; Improves sync speed in slow environments. +routing.assumechanvalid=true diff --git a/dev/vendor/galoy-quickstart/dev/config/lnd/regtest/lnd-outside-1.admin.macaroon b/dev/vendor/galoy-quickstart/dev/config/lnd/regtest/lnd-outside-1.admin.macaroon new file mode 100644 index 0000000000..246395ba4b Binary files /dev/null and b/dev/vendor/galoy-quickstart/dev/config/lnd/regtest/lnd-outside-1.admin.macaroon differ diff --git a/dev/vendor/galoy-quickstart/dev/config/lnd/regtest/lnd-outside-1.admin.macaroon.base64 b/dev/vendor/galoy-quickstart/dev/config/lnd/regtest/lnd-outside-1.admin.macaroon.base64 new file mode 100644 index 0000000000..59cf5d3f0c --- /dev/null +++ b/dev/vendor/galoy-quickstart/dev/config/lnd/regtest/lnd-outside-1.admin.macaroon.base64 @@ -0,0 +1 @@ +AgEDbG5kAvgBAwoQeE+5exgz7/0ExCn7H6AJlBIBMBoWCgdhZGRyZXNzEgRyZWFkEgV3cml0ZRoTCgRpbmZvEgRyZWFkEgV3cml0ZRoXCghpbnZvaWNlcxIEcmVhZBIFd3JpdGUaIQoIbWFjYXJvb24SCGdlbmVyYXRlEgRyZWFkEgV3cml0ZRoWCgdtZXNzYWdlEgRyZWFkEgV3cml0ZRoXCghvZmZjaGFpbhIEcmVhZBIFd3JpdGUaFgoHb25jaGFpbhIEcmVhZBIFd3JpdGUaFAoFcGVlcnMSBHJlYWQSBXdyaXRlGhgKBnNpZ25lchIIZ2VuZXJhdGUSBHJlYWQAAAYgL7pU+cKOt6zGyWTdWWmAJLP1L3cnbOPb4Rd3QtniyyM= \ No newline at end of file diff --git a/dev/vendor/galoy-quickstart/dev/config/lnd/regtest/lnd-outside-1.macaroons.db b/dev/vendor/galoy-quickstart/dev/config/lnd/regtest/lnd-outside-1.macaroons.db new file mode 100644 index 0000000000..404854654f Binary files /dev/null and b/dev/vendor/galoy-quickstart/dev/config/lnd/regtest/lnd-outside-1.macaroons.db differ diff --git a/dev/vendor/galoy-quickstart/dev/config/lnd/regtest/lnd-outside-1.pubkey b/dev/vendor/galoy-quickstart/dev/config/lnd/regtest/lnd-outside-1.pubkey new file mode 100644 index 0000000000..0e42d91614 --- /dev/null +++ b/dev/vendor/galoy-quickstart/dev/config/lnd/regtest/lnd-outside-1.pubkey @@ -0,0 +1 @@ +02147eeb1561922fe768a6a92df116f5fec8c1869ddcb6e00ee1fd0df146d51c4a diff --git a/dev/vendor/galoy-quickstart/dev/config/lnd/regtest/lnd-outside-1.wallet.db b/dev/vendor/galoy-quickstart/dev/config/lnd/regtest/lnd-outside-1.wallet.db new file mode 100644 index 0000000000..11628ce86c Binary files /dev/null and b/dev/vendor/galoy-quickstart/dev/config/lnd/regtest/lnd-outside-1.wallet.db differ diff --git a/dev/vendor/galoy-quickstart/dev/config/lnd/regtest/lnd-outside-2.admin.macaroon b/dev/vendor/galoy-quickstart/dev/config/lnd/regtest/lnd-outside-2.admin.macaroon new file mode 100644 index 0000000000..e35a69ee59 Binary files /dev/null and b/dev/vendor/galoy-quickstart/dev/config/lnd/regtest/lnd-outside-2.admin.macaroon differ diff --git a/dev/vendor/galoy-quickstart/dev/config/lnd/regtest/lnd-outside-2.admin.macaroon.base64 b/dev/vendor/galoy-quickstart/dev/config/lnd/regtest/lnd-outside-2.admin.macaroon.base64 new file mode 100644 index 0000000000..826591de2e --- /dev/null +++ b/dev/vendor/galoy-quickstart/dev/config/lnd/regtest/lnd-outside-2.admin.macaroon.base64 @@ -0,0 +1 @@ +AgEDbG5kAvgBAwoQfKO82/iPT2zIwWYPrOXvABIBMBoWCgdhZGRyZXNzEgRyZWFkEgV3cml0ZRoTCgRpbmZvEgRyZWFkEgV3cml0ZRoXCghpbnZvaWNlcxIEcmVhZBIFd3JpdGUaIQoIbWFjYXJvb24SCGdlbmVyYXRlEgRyZWFkEgV3cml0ZRoWCgdtZXNzYWdlEgRyZWFkEgV3cml0ZRoXCghvZmZjaGFpbhIEcmVhZBIFd3JpdGUaFgoHb25jaGFpbhIEcmVhZBIFd3JpdGUaFAoFcGVlcnMSBHJlYWQSBXdyaXRlGhgKBnNpZ25lchIIZ2VuZXJhdGUSBHJlYWQAAAYg2XkV+4Z4inbfXGZivRoY+r7KHNZhgxkCEdKByxbeb/Q= \ No newline at end of file diff --git a/dev/vendor/galoy-quickstart/dev/config/lnd/regtest/lnd-outside-2.macaroons.db b/dev/vendor/galoy-quickstart/dev/config/lnd/regtest/lnd-outside-2.macaroons.db new file mode 100644 index 0000000000..a052db71f6 Binary files /dev/null and b/dev/vendor/galoy-quickstart/dev/config/lnd/regtest/lnd-outside-2.macaroons.db differ diff --git a/dev/vendor/galoy-quickstart/dev/config/lnd/regtest/lnd-outside-2.pubkey b/dev/vendor/galoy-quickstart/dev/config/lnd/regtest/lnd-outside-2.pubkey new file mode 100644 index 0000000000..6c6acab50f --- /dev/null +++ b/dev/vendor/galoy-quickstart/dev/config/lnd/regtest/lnd-outside-2.pubkey @@ -0,0 +1 @@ +02f4888c0fffc494874da4445918dadaf88a63dbb96bce734b087bed56f60d231b diff --git a/dev/vendor/galoy-quickstart/dev/config/lnd/regtest/lnd-outside-2.wallet.db b/dev/vendor/galoy-quickstart/dev/config/lnd/regtest/lnd-outside-2.wallet.db new file mode 100644 index 0000000000..984b96b79d Binary files /dev/null and b/dev/vendor/galoy-quickstart/dev/config/lnd/regtest/lnd-outside-2.wallet.db differ diff --git a/dev/vendor/galoy-quickstart/dev/config/lnd/regtest/lnd1.admin.macaroon b/dev/vendor/galoy-quickstart/dev/config/lnd/regtest/lnd1.admin.macaroon new file mode 100644 index 0000000000..f8faa86840 Binary files /dev/null and b/dev/vendor/galoy-quickstart/dev/config/lnd/regtest/lnd1.admin.macaroon differ diff --git a/dev/vendor/galoy-quickstart/dev/config/lnd/regtest/lnd1.admin.macaroon.base64 b/dev/vendor/galoy-quickstart/dev/config/lnd/regtest/lnd1.admin.macaroon.base64 new file mode 100644 index 0000000000..c06b347a06 --- /dev/null +++ b/dev/vendor/galoy-quickstart/dev/config/lnd/regtest/lnd1.admin.macaroon.base64 @@ -0,0 +1 @@ +AgEDbG5kAvgBAwoQB1FdhGa9xoewc1LEXmnURRIBMBoWCgdhZGRyZXNzEgRyZWFkEgV3cml0ZRoTCgRpbmZvEgRyZWFkEgV3cml0ZRoXCghpbnZvaWNlcxIEcmVhZBIFd3JpdGUaIQoIbWFjYXJvb24SCGdlbmVyYXRlEgRyZWFkEgV3cml0ZRoWCgdtZXNzYWdlEgRyZWFkEgV3cml0ZRoXCghvZmZjaGFpbhIEcmVhZBIFd3JpdGUaFgoHb25jaGFpbhIEcmVhZBIFd3JpdGUaFAoFcGVlcnMSBHJlYWQSBXdyaXRlGhgKBnNpZ25lchIIZ2VuZXJhdGUSBHJlYWQAAAYgqHDdwGCqx0aQL1/Z3uUfzCpeBhfapGf9s/AZPOVwf6s= \ No newline at end of file diff --git a/dev/vendor/galoy-quickstart/dev/config/lnd/regtest/lnd1.macaroons.db b/dev/vendor/galoy-quickstart/dev/config/lnd/regtest/lnd1.macaroons.db new file mode 100644 index 0000000000..3defb531a6 Binary files /dev/null and b/dev/vendor/galoy-quickstart/dev/config/lnd/regtest/lnd1.macaroons.db differ diff --git a/dev/vendor/galoy-quickstart/dev/config/lnd/regtest/lnd1.pubkey b/dev/vendor/galoy-quickstart/dev/config/lnd/regtest/lnd1.pubkey new file mode 100644 index 0000000000..a49cc4d770 --- /dev/null +++ b/dev/vendor/galoy-quickstart/dev/config/lnd/regtest/lnd1.pubkey @@ -0,0 +1 @@ +03ca1907342d5d37744cb7038375e1867c24a87564c293157c95b2a9d38dcfb4c2 diff --git a/dev/vendor/galoy-quickstart/dev/config/lnd/regtest/lnd1.wallet.db b/dev/vendor/galoy-quickstart/dev/config/lnd/regtest/lnd1.wallet.db new file mode 100644 index 0000000000..c73c638dd4 Binary files /dev/null and b/dev/vendor/galoy-quickstart/dev/config/lnd/regtest/lnd1.wallet.db differ diff --git a/dev/vendor/galoy-quickstart/dev/config/lnd/regtest/lnd2.admin.macaroon b/dev/vendor/galoy-quickstart/dev/config/lnd/regtest/lnd2.admin.macaroon new file mode 100644 index 0000000000..f414781ae8 Binary files /dev/null and b/dev/vendor/galoy-quickstart/dev/config/lnd/regtest/lnd2.admin.macaroon differ diff --git a/dev/vendor/galoy-quickstart/dev/config/lnd/regtest/lnd2.admin.macaroon.base64 b/dev/vendor/galoy-quickstart/dev/config/lnd/regtest/lnd2.admin.macaroon.base64 new file mode 100644 index 0000000000..22252d2a37 --- /dev/null +++ b/dev/vendor/galoy-quickstart/dev/config/lnd/regtest/lnd2.admin.macaroon.base64 @@ -0,0 +1 @@ +AgEDbG5kAvgBAwoQX0BxfhQTxLTiqaceBnGnfBIBMBoWCgdhZGRyZXNzEgRyZWFkEgV3cml0ZRoTCgRpbmZvEgRyZWFkEgV3cml0ZRoXCghpbnZvaWNlcxIEcmVhZBIFd3JpdGUaIQoIbWFjYXJvb24SCGdlbmVyYXRlEgRyZWFkEgV3cml0ZRoWCgdtZXNzYWdlEgRyZWFkEgV3cml0ZRoXCghvZmZjaGFpbhIEcmVhZBIFd3JpdGUaFgoHb25jaGFpbhIEcmVhZBIFd3JpdGUaFAoFcGVlcnMSBHJlYWQSBXdyaXRlGhgKBnNpZ25lchIIZ2VuZXJhdGUSBHJlYWQAAAYgMAKlr1HehfBpn2R5RPE2IuY9r/18QBeLZxYgRidpos4= \ No newline at end of file diff --git a/dev/vendor/galoy-quickstart/dev/config/lnd/regtest/lnd2.macaroons.db b/dev/vendor/galoy-quickstart/dev/config/lnd/regtest/lnd2.macaroons.db new file mode 100644 index 0000000000..4d55f07bc5 Binary files /dev/null and b/dev/vendor/galoy-quickstart/dev/config/lnd/regtest/lnd2.macaroons.db differ diff --git a/dev/vendor/galoy-quickstart/dev/config/lnd/regtest/lnd2.pubkey b/dev/vendor/galoy-quickstart/dev/config/lnd/regtest/lnd2.pubkey new file mode 100644 index 0000000000..6a3156846d --- /dev/null +++ b/dev/vendor/galoy-quickstart/dev/config/lnd/regtest/lnd2.pubkey @@ -0,0 +1 @@ +039341ef13e776dc1611502cf510110d9ac5cdc252141f5997adcfd72cef34c3a7 diff --git a/dev/vendor/galoy-quickstart/dev/config/lnd/regtest/lnd2.wallet.db b/dev/vendor/galoy-quickstart/dev/config/lnd/regtest/lnd2.wallet.db new file mode 100644 index 0000000000..85dd05c326 Binary files /dev/null and b/dev/vendor/galoy-quickstart/dev/config/lnd/regtest/lnd2.wallet.db differ diff --git a/dev/vendor/galoy-quickstart/dev/config/lnd/tls.cert b/dev/vendor/galoy-quickstart/dev/config/lnd/tls.cert new file mode 100644 index 0000000000..7d4058b47e --- /dev/null +++ b/dev/vendor/galoy-quickstart/dev/config/lnd/tls.cert @@ -0,0 +1,15 @@ +-----BEGIN CERTIFICATE----- +MIICYTCCAgegAwIBAgIRAOsg7XXTxruYbXdy66wtn7QwCgYIKoZIzj0EAwIwODEf +MB0GA1UEChMWbG5kIGF1dG9nZW5lcmF0ZWQgY2VydDEVMBMGA1UEAxMMODYxOTgx +MjNmODhjMB4XDTIzMDExOTIwNDE1M1oXDTM0MDcyMTIwNDE1M1owODEfMB0GA1UE +ChMWbG5kIGF1dG9nZW5lcmF0ZWQgY2VydDEVMBMGA1UEAxMMODYxOTgxMjNmODhj +MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE3YbyIJYMUro3fItPQns+1giiMr95 +IQtfrQCCba9emr28LCfnMoc/UAQpRX7AYoTTgyGb0PndcT81yeX/a9OkDKOB8TCB +7jAOBgNVHQ8BAf8EBAMCAqQwEwYDVR0lBAwwCgYIKwYBBQUHAwEwDwYDVR0TAQH/ +BAUwAwEB/zAdBgNVHQ4EFgQU/P1DzIRDsLHG1MtwskdNggInoS0wgZYGA1UdEQSB +jjCBi4IMODYxOTgxMjNmODhjgglsb2NhbGhvc3SCDWxuZC1vdXRzaWRlLTGCDWxu +ZC1vdXRzaWRlLTKCDWxuZC1vdXRzaWRlLTOCBGxuZDGCBGxuZDKCBHVuaXiCCnVu +aXhwYWNrZXSCB2J1ZmNvbm6HBH8AAAGHEAAAAAAAAAAAAAAAAAAAAAGHBKwTABAw +CgYIKoZIzj0EAwIDSAAwRQIhAINC6RVCwzK1XFqqySKcF8C49dYR98czgK5WdrcN +LXaiAiBGbkVxhZxwCh5KCZ5gc5CalCDohcqVGbhsrkHGLXitsw== +-----END CERTIFICATE----- diff --git a/dev/vendor/galoy-quickstart/dev/config/lnd/tls.key b/dev/vendor/galoy-quickstart/dev/config/lnd/tls.key new file mode 100644 index 0000000000..1f69180f73 --- /dev/null +++ b/dev/vendor/galoy-quickstart/dev/config/lnd/tls.key @@ -0,0 +1,5 @@ +-----BEGIN EC PRIVATE KEY----- +MHcCAQEEIPy74CUpAM/gvRurq0S+XiZDQOh4HZodHpY4XZzZyEkfoAoGCCqGSM49 +AwEHoUQDQgAE3YbyIJYMUro3fItPQns+1giiMr95IQtfrQCCba9emr28LCfnMoc/ +UAQpRX7AYoTTgyGb0PndcT81yeX/a9OkDA== +-----END EC PRIVATE KEY----- diff --git a/dev/vendor/galoy-quickstart/dev/config/ory/body.jsonnet b/dev/vendor/galoy-quickstart/dev/config/ory/body.jsonnet new file mode 100644 index 0000000000..2d3090b804 --- /dev/null +++ b/dev/vendor/galoy-quickstart/dev/config/ory/body.jsonnet @@ -0,0 +1,8 @@ +function(ctx) { + identity_id: if std.objectHas(ctx, "identity") then ctx.identity.id else null, + phone: if std.objectHas(ctx.identity.traits, "phone") then ctx.identity.traits.phone else null, + transient_payload: if std.objectHas(ctx.flow, "transient_payload") then ctx.flow.transient_payload else null, + schema_id: ctx.identity.schema_id, + flow_id: ctx.flow.id, + flow_type: ctx.flow.type +} diff --git a/dev/vendor/galoy-quickstart/dev/config/ory/email_no_password_v0.identity.schema.json b/dev/vendor/galoy-quickstart/dev/config/ory/email_no_password_v0.identity.schema.json new file mode 100644 index 0000000000..6b72f9c8b6 --- /dev/null +++ b/dev/vendor/galoy-quickstart/dev/config/ory/email_no_password_v0.identity.schema.json @@ -0,0 +1,33 @@ +{ + "$id": "http://mydomain.com/schemas/v2/customer.schema.json", + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "A email user", + "type": "object", + "properties": { + "traits": { + "type": "object", + "properties": { + "email": { + "title": "E-Mail", + "type": "string", + "format": "email", + "ory.sh/kratos": { + "credentials": { + "password": { + "identifier": true + } + }, + "verification": { + "via": "email" + }, + "recovery": { + "via": "email" + } + } + } + }, + "required": ["email"], + "additionalProperties": false + } + } +} diff --git a/dev/vendor/galoy-quickstart/dev/config/ory/hydra.yml b/dev/vendor/galoy-quickstart/dev/config/ory/hydra.yml new file mode 100644 index 0000000000..eeb3592a3b --- /dev/null +++ b/dev/vendor/galoy-quickstart/dev/config/ory/hydra.yml @@ -0,0 +1,22 @@ +serve: + cookies: + same_site_mode: Lax + +urls: + self: + issuer: http://localhost:4444 + consent: http://localhost:3000/consent + login: http://localhost:3000/login + logout: http://localhost:3000/logout + +secrets: + system: + - youReallyNeedToChangeThis + +oidc: + subject_identifiers: + supported_types: + - pairwise + - public + pairwise: + salt: youReallyNeedToChangeThis diff --git a/dev/vendor/galoy-quickstart/dev/config/ory/jwks.json b/dev/vendor/galoy-quickstart/dev/config/ory/jwks.json new file mode 100644 index 0000000000..9a92888331 --- /dev/null +++ b/dev/vendor/galoy-quickstart/dev/config/ory/jwks.json @@ -0,0 +1,18 @@ +{ + "keys": [ + { + "use": "sig", + "kty": "RSA", + "kid": "1b97b221-ca08-4eb2-9d09-a5770fcceb37", + "alg": "RS256", + "n": "qlvfGDcdL8kM9L6svAi4DrR8XbIfznVilo0jJVHSzCMe6gW5H_RE-yYg7bWc6t2DRRP7UUcggI4c3m3o85DeWrd-pCWQaKxhJAvMrvzbBqk8Eh9HynwG_5garUf3CWEQJWrl7UAJgBThua9QJdN6RONfTlUFlahju4difLfAIYpJyRNeGZ8oAQSiPflQ6a_Ldl6oNP5KEKB526Bx9wG0ri_m2ZB-6gkenhLwjQ2Pc8dAsb-Y1FZnNxswfnW2VPMAun7aNZKGcUXBXim3uM-H4iLvBKSG7DokfA0icqf4xS4kYkCgoo17D-yU564IuckwUGjB6eziXhBlIj-O3dS4sQ", + "e": "AQAB", + "d": "g-fOvbku6CkL1xUsOgumN_yXrxSUfA933oo5hFPunBE1ho4X4R4Jq0zCgkv0zAXn9jyagzxHdkKTJ8aCcNTi1eruK7rKLcILFRXtzjAKhwXSdVWzCJ0v7gef4Duwk5qMHey_SwwiTwHcJSIRNLiiG2TSDpzWTiKr1i_lmhvMsCpXv1331F1Yp0jVDt098Gj5E5Ppqrp2zQay94fTj07sLbRgZPmVT-rTQwjLwRC_PvWWUpxIGGW9PHjy6640t7JrUOLtBQphXrgitkQ0TRxYuot16BOTmELAStFFOmUJ2NS0DPV0Horu7B6r7Qa_9iH4XelWTlZ-bxSaiz_d9OJ9YQ", + "p": "0lPl2OpzdlbAxI4_UZvcad0MnR2vZUqc84VZyqOiC5LFV557i5-AfBZ1X5m-8CLY4L32N0zJPgsiyH4SKg_iwlYGRZX9gbFGKIEuy2J66LhrMN4N6Gu32YF7NTKjVHIpEBv3esRGeARKw16oT8_Empff1rLw0PYWL9q_xHw4UvM", + "q": "z1obr3gdTPw6R2OtgIGnGXQfz0kCm0gQhUGZDVGBLoMYzQOoiIhncYD539gAXSDMXZHxM7z_jSvbwQ0tV9p6frVw4elxY6En_V3FzBVZO823qOdgwtiz5FENbSvJX3EDpFly6h26K5Iz4Q4S71_wQFIiYnAwrDJnsfNMFYGxxss", + "dp": "xj0BZKQF08IMyrXwBDFNXBJWszepe2UJ7ZUAfrggIZximCTt-TmK1mosksDMcHXHyHwDNzgObYX9cM8yu6Zhah2-p5OpbrXxlHe97UCS7An2Lgb9QNVWYZFi2U8zFoLLJT3W0kVwzenttZrgNOl1Ouhut2PNCocHfm9FVCJoy_U", + "dq": "NYuzcpC2IFdSRXU8LN9OY4hVXpYgEjF98quJ9qKBlZ1NHkQ_lWKENA92d5O0JFh_7fnuK8o2xCH7UdMxTmqhD2-TgwNhwLSxOwCoP5eTv5nUP83gcvC7I866hOK10evBYQOoZUTf-rh6pTeZNC-2PyX2syz9pLovhQirMTKY0hk", + "qi": "NUtIm6QtQKy0j4HFXuXweQTI778pBmGgY5Ob0ZX5brFMKN2TkFLYKgX9pgiw3Lv6o9QLvYi4_YACS2vTMxUyKUIqd5FYaGHU67kwWzFdtuEgM4zcINLPmSo5pYi7n4_eA8AHBUKwz3L-UchdWbCKopYR-BrUPUQdQTLPxnSRC3U" + } + ] +} diff --git a/dev/vendor/galoy-quickstart/dev/config/ory/kratos.yml b/dev/vendor/galoy-quickstart/dev/config/ory/kratos.yml new file mode 100644 index 0000000000..825f3b96ea --- /dev/null +++ b/dev/vendor/galoy-quickstart/dev/config/ory/kratos.yml @@ -0,0 +1,173 @@ +version: v0.13.0 + +dsn: "overrided-by-env" + +serve: + public: + base_url: http://127.0.0.1:4433/ + cors: + enabled: true + allow_credentials: true + allowed_origins: + - http://127.0.0.1:4433 + - http://0.0.0.0:4434 + - http://localhost:3000 + - http://127.0.0.1:3000 + allowed_methods: + - POST + - GET + - PUT + - PATCH + - DELETE + allowed_headers: + - Authorization + - Cookie + - Content-Type + - X-Session-Token + exposed_headers: + - Content-Type + - Set-Cookie + debug: true + + admin: + base_url: http://0.0.0.0:4434/ + +selfservice: + default_browser_return_url: http://localhost:3000/ + allowed_return_urls: + - http://127.0.0.1:4455/ + - http://localhost:3000/ + + methods: + oidc: + enabled: false + webauthn: + enabled: false + totp: + enabled: true + password: + enabled: true + + code: + enabled: true + config: + # Defines how long the verification or the recovery code is valid for (default 1h) + lifespan: 15m + + flows: + error: + ui_url: http://127.0.0.1:4455/error + + settings: + ui_url: http://127.0.0.1:4455/settings + + # very short time frame because this has impact in the totp flow + privileged_session_max_age: 1s + + # to enforce the user to paste his 2fa to deactivate it, this could be set to highest_available + required_aal: aal1 + + after: + profile: + hooks: + - hook: web_hook + config: + # url: http://bats-tests:4455/auth/after_settings_hooks + url: http://invalid-because-we-dont-want-profile-to-be-updated + method: POST + body: file:///home/ory/body.jsonnet + auth: + type: api_key + config: + name: Authorization + value: The-Value-of-My-Key + in: header + + recovery: + enabled: true + ui_url: http://127.0.0.1:4455/recovery + + verification: + use: code + enabled: true + lifespan: 15m + # notify_unknown_recipients: false + + logout: + after: + default_browser_return_url: http://127.0.0.1:4455/login + + login: + ui_url: http://localhost:3000/login + lifespan: 10m + + # this below make phone authentication fails even if there is no email in the schema + # after: + # password: + # hooks: + # - hook: require_verified_address + + registration: + lifespan: 10m + ui_url: http://localhost:3000/register + after: + password: + hooks: + - hook: session + +log: + level: debug + format: json + leak_sensitive_values: true + +secrets: + cookie: + - PLEASE-CHANGE-ME-I-AM-VERY-INSECURE + cipher: + - 32-LONG-SECRET-NOT-SECURE-AT-ALL + +ciphers: + algorithm: xchacha20-poly1305 + +hashers: + algorithm: bcrypt + bcrypt: + cost: 8 + +identity: + default_schema_id: phone_no_password_v0 + schemas: + - id: phone_no_password_v0 + url: file:///home/ory/phone_no_password_v0.identity.schema.json + - id: phone_email_no_password_v0 + url: file:///home/ory/phone_email_no_password_v0.identity.schema.json + - id: email_no_password_v0 + url: file:///home/ory/email_no_password_v0.identity.schema.json + - id: username_password_deviceid_v0 + url: file:///home/ory/username_password_deviceid_v0.identity.schema.json + +courier: + smtp: + connection_uri: smtps://test:test@mailslurper:1025/?skip_ssl_verify=true + templates: + recovery_code: + valid: + email: + subject: base64://eW91ciBjb2RlCg== + body: + # courier/template/courier/builtin/templates/recovery_code/valid/email.body.plaintext.gotmpl + # Hi, + # You can confirm access to your blink account by entering the following code: + # {{ .RecoveryCode }} + # Don't share this code with anyone. Our employee will never ask for this code + plaintext: base64://SGksCgpZb3UgY2FuIGNvbmZpcm0gYWNjZXNzIHRvIHlvdXIgYmxpbmsgYWNjb3VudCBieSBlbnRlcmluZyB0aGUgZm9sbG93aW5nIGNvZGU6Cgp7eyAuUmVjb3ZlcnlDb2RlIH19CgpEb24ndCBzaGFyZSB0aGlzIGNvZGUgd2l0aCBhbnlvbmUuIE91ciBlbXBsb3llZSB3aWxsIG5ldmVyIGFzayBmb3IgdGhpcyBjb2RlCg== + html: base64://SGksCgpZb3UgY2FuIGNvbmZpcm0gYWNjZXNzIHRvIHlvdXIgYmxpbmsgYWNjb3VudCBieSBlbnRlcmluZyB0aGUgZm9sbG93aW5nIGNvZGU6Cgp7eyAuUmVjb3ZlcnlDb2RlIH19CgpEb24ndCBzaGFyZSB0aGlzIGNvZGUgd2l0aCBhbnlvbmUuIE91ciBlbXBsb3llZSB3aWxsIG5ldmVyIGFzayBmb3IgdGhpcyBjb2RlCg== + +session: + # TODO: check lifespan per schema + # or look how to extend + lifespan: "720h" # 1 month + earliest_possible_extend: "720h" # needed for test. should be shorter in prod + + whoami: + required_aal: highest_available diff --git a/dev/vendor/galoy-quickstart/dev/config/ory/oathkeeper.yml b/dev/vendor/galoy-quickstart/dev/config/ory/oathkeeper.yml new file mode 100644 index 0000000000..69b1fe6fae --- /dev/null +++ b/dev/vendor/galoy-quickstart/dev/config/ory/oathkeeper.yml @@ -0,0 +1,95 @@ +log: + level: debug + format: json + +tracing: + provider: otel + providers: + otlp: + server_url: otel-agent:4318 + insecure: true + +authenticators: + jwt: + enabled: true + config: + trusted_issuers: + - https://firebaseappcheck.googleapis.com/72279297366 + target_audience: + - projects/72279297366 + jwks_urls: + - https://firebaseappcheck.googleapis.com/v1beta/jwks + - file:///home/ory/jwks.json # ONLY FOR DEV, DO NOT USE IN PRODUCTION + token_from: + header: Appcheck + + bearer_token: + enabled: true + config: + check_session_url: http://kratos:4433/sessions/whoami + preserve_path: true + preserve_query: true + subject_from: identity.id + extra_from: "@this" + + oauth2_introspection: + enabled: true + config: + introspection_url: http://hydra:4445/admin/oauth2/introspect + token_from: + header: Oauth2-Token + + anonymous: + enabled: true + config: + subject: anon + + cookie_session: + enabled: true + config: + # TODO cluster-internal mTLS + check_session_url: http://kratos:4433/sessions/whoami + preserve_path: true + subject_from: identity.id + extra_from: identity.traits + + unauthorized: + enabled: true + + noop: + enabled: true + +authorizers: + allow: + enabled: true + +mutators: + id_token: + enabled: true + config: + jwks_url: file:///home/ory/jwks.json + issuer_url: "galoy.io" + claims: '{"sub": "{{ print .Subject }}" }' + + noop: + enabled: true + + header: + enabled: true + config: + headers: + X-Appcheck-Jti: "{{ print .Extra.jti }}" + +errors: + fallback: + - json + handlers: + json: + enabled: true + config: + verbose: true + +access_rules: + repositories: + - file:///home/ory/oathkeeper_rules.yaml + matching_strategy: regexp diff --git a/dev/vendor/galoy-quickstart/dev/config/ory/oathkeeper_rules.yaml b/dev/vendor/galoy-quickstart/dev/config/ory/oathkeeper_rules.yaml new file mode 100644 index 0000000000..ec383edae8 --- /dev/null +++ b/dev/vendor/galoy-quickstart/dev/config/ory/oathkeeper_rules.yaml @@ -0,0 +1,109 @@ +- id: anonymous-rest-auth + upstream: + url: "http://bats-tests:4012" + match: + url: "<(http|https)>://<[a-zA-Z0-9-.:]+>/auth/<.*>" + methods: ["GET", "POST", "OPTIONS"] + authenticators: + - handler: jwt + config: + trusted_issuers: + - https://firebaseappcheck.googleapis.com/72279297366 + target_audience: + - projects/72279297366 + jwks_urls: + - https://firebaseappcheck.googleapis.com/v1beta/jwks + - file:///home/ory/jwks.json # ONLY FOR DEV, DO NOT USE IN PRODUCTION + token_from: + header: Appcheck + - handler: anonymous + authorizer: + handler: allow + mutators: + - handler: header + config: + headers: + X-Appcheck-Jti: "{{ print .Extra.jti }}" + +- id: galoy-ws + upstream: + url: "http://bats-tests:4000/graphql" + strip_path: /graphqlws # ONLY FOR DEV, in prod should resolve to /graphql, like ws.blink.sv/graphql + match: + url: "<(http|https)>://<[a-zA-Z0-9-.:]+>/graphqlws" # ONLY FOR DEV, in prod should resolve to /graphql + methods: ["POST", "GET"] + authenticators: + - handler: noop + authorizer: + handler: allow + mutators: + - handler: noop + +- id: galoy-backend + upstream: + url: "http://apollo-router:4004" + match: + url: "<(http|https)>://<[a-zA-Z0-9-.:]+>/graphql" + methods: ["POST", "GET", "OPTIONS"] + authenticators: + - handler: oauth2_introspection + config: + introspection_url: http://hydra:4445/admin/oauth2/introspect + token_from: + header: Oauth2-Token + + - handler: bearer_token + config: + token_from: + header: X-API-KEY + forward_http_headers: + - "X-API-KEY" + check_session_url: "http://bats-tests:5397/auth/check" + force_method: GET + preserve_path: true + preserve_query: true + subject_from: sub + extra_from: "@this" + - handler: bearer_token + config: + check_session_url: http://kratos:4433/sessions/whoami + preserve_path: true + preserve_query: true + subject_from: identity.id + extra_from: "@this" + + - handler: anonymous + authorizer: + handler: allow + mutators: + - handler: id_token + config: #! TODO: add aud: {"aud": ["https://api/graphql"] } + claims: '{"sub": "{{ print .Subject }}", "session_id": "{{ print .Extra.id }}", "expires_at": "{{ print .Extra.expires_at }}", "scope": "{{ print .Extra.scope }}", "client_id": "{{ print .Extra.client_id }}"}' + +- id: admin-backend + upstream: + url: "http://bats-tests:4001" + strip_path: /admin + match: + url: "<(http|https)>://<.*><[0-9]+>/admin<.*>" + methods: ["GET", "POST", "OPTIONS"] + authenticators: + - handler: cookie_session + config: + check_session_url: http://host.docker.internal:3004/api/auth/session + preserve_path: true + preserve_query: true + subject_from: user.email + extra_from: "@this" + force_method: "GET" + - handler: oauth2_introspection + config: + introspection_url: http://hydra:4445/admin/oauth2/introspect + token_from: + header: Oauth2-Token + authorizer: + handler: allow + mutators: + - handler: id_token + config: #! TODO: add aud: {"aud": ["https://api/admin/graphql"] } + claims: '{"sub": "{{ print .Subject }}", "scope": "{{ print .Extra.scope }}" }' diff --git a/dev/vendor/galoy-quickstart/dev/config/ory/phone_email_no_password_v0.identity.schema.json b/dev/vendor/galoy-quickstart/dev/config/ory/phone_email_no_password_v0.identity.schema.json new file mode 100644 index 0000000000..067319a889 --- /dev/null +++ b/dev/vendor/galoy-quickstart/dev/config/ory/phone_email_no_password_v0.identity.schema.json @@ -0,0 +1,45 @@ +{ + "$id": "http://mydomain.com/schemas/v2/customer.schema.json", + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "A phone+email user", + "type": "object", + "properties": { + "traits": { + "type": "object", + "properties": { + "email": { + "title": "E-Mail", + "type": "string", + "format": "email", + "ory.sh/kratos": { + "credentials": { + "password": { + "identifier": true + } + }, + "verification": { + "via": "email" + }, + "recovery": { + "via": "email" + } + } + }, + "phone": { + "title": "Phone", + "type": "string", + "format": "string", + "ory.sh/kratos": { + "credentials": { + "password": { + "identifier": true + } + } + } + } + }, + "required": ["email", "phone"], + "additionalProperties": false + } + } +} diff --git a/dev/vendor/galoy-quickstart/dev/config/ory/phone_no_password_v0.identity.schema.json b/dev/vendor/galoy-quickstart/dev/config/ory/phone_no_password_v0.identity.schema.json new file mode 100644 index 0000000000..34773ec530 --- /dev/null +++ b/dev/vendor/galoy-quickstart/dev/config/ory/phone_no_password_v0.identity.schema.json @@ -0,0 +1,32 @@ +{ + "$id": "https://schemas.ory.sh/presets/kratos/quickstart/phone-no-password/identity.schema.json", + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "PhoneNoPassword", + "type": "object", + "properties": { + "traits": { + "type": "object", + "properties": { + "phone": { + "type": "string", + "format": "string", + "title": "phone", + "minLength": 3, + "ory.sh/kratos": { + "credentials": { + "password": { + "identifier": true + } + } + } + } + }, + "required": ["phone"], + "additionalProperties": false + }, + "transient_payload": { + "type": "object", + "additionalProperties": true + } + } +} diff --git a/dev/vendor/galoy-quickstart/dev/config/ory/username_password_deviceid_v0.identity.schema.json b/dev/vendor/galoy-quickstart/dev/config/ory/username_password_deviceid_v0.identity.schema.json new file mode 100644 index 0000000000..03176dbb06 --- /dev/null +++ b/dev/vendor/galoy-quickstart/dev/config/ory/username_password_deviceid_v0.identity.schema.json @@ -0,0 +1,25 @@ +{ + "$id": "https://schemas.ory.sh/presets/kratos/quickstart/username-password-deviceid/identity.schema.json", + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "UsernamePasswordDeviceId", + "type": "object", + "properties": { + "traits": { + "type": "object", + "properties": { + "username": { + "type": "string", + "minLength": 36, + "maxLength": 36, + "ory.sh/kratos": { + "credentials": { + "password": { + "identifier": true + } + } + } + } + } + } + } +} diff --git a/dev/vendor/galoy-quickstart/dev/config/otel-agent-config.yaml b/dev/vendor/galoy-quickstart/dev/config/otel-agent-config.yaml new file mode 100644 index 0000000000..0a7995ab2c --- /dev/null +++ b/dev/vendor/galoy-quickstart/dev/config/otel-agent-config.yaml @@ -0,0 +1,71 @@ +receivers: + jaeger: + protocols: + thrift_compact: # on port 6831 + thrift_binary: # on port 6832 + otlp: + protocols: + grpc: + endpoint: 0.0.0.0:4317 + http: + endpoint: 0.0.0.0:4318 + +processors: + filter/ottl: + error_mode: ignore + traces: + span: + - 'resource.attributes["service.name"] == "stablesats-dev"' + - 'resource.attributes["service.name"] == "bria-dev"' + - 'name == "grpc.lnrpc.State/GetState"' + - 'name == "app.prices.getCurrentSatPrice"' + - 'name == "app.prices.getCurrentUsdCentPrice"' + - 'name == "grpc.PriceFeed/GetPrice"' + - 'name == "grpc.PriceFeed/ListCurrencies"' + - 'name == "services.cache.local.set"' + - 'name == "services.cache.local.get"' + - 'name == "app.prices.listCurrencies"' + - 'name == "services.cache.local.getOrSet"' + batch: + attributes: + actions: + - key: graphql.variables.input.code + action: update + value: "" + - key: code.function.params.code + action: update + value: "" + - key: code.function.params.authToken + action: update + value: "" + - key: code.function.params.totpCode + action: update + value: "" + - key: graphql.variables.input.totpCode + action: update + value: "" + - key: graphql.variables.input.authToken + action: update + value: "" + +exporters: + logging: + loglevel: debug + otlp: + endpoint: "api.honeycomb.io:443" + headers: + "x-honeycomb-team": ${HONEYCOMB_API_KEY} + "x-honeycomb-dataset": ${HONEYCOMB_DATASET} + +extensions: + health_check: + pprof: + zpages: + +service: + extensions: [health_check, pprof, zpages] + pipelines: + traces: + receivers: [jaeger, otlp] + processors: [filter/ottl, attributes, batch] + exporters: [otlp, logging] diff --git a/dev/vendor/galoy-quickstart/dev/config/stablesats.yml b/dev/vendor/galoy-quickstart/dev/config/stablesats.yml new file mode 100644 index 0000000000..82244ad287 --- /dev/null +++ b/dev/vendor/galoy-quickstart/dev/config/stablesats.yml @@ -0,0 +1,28 @@ +exchanges: + okex: + weight: 1.0 + +price_server: + enabled: true + server: + listen_port: 3325 + fees: + base_fee_rate: 0.0005 + immediate_fee_rate: 0.0005 + delayed_fee_rate: 0.0007 + price_cache: + dev_mock_price_btc_in_usd: 20000 + +okex_price_feed: + enabled: false + +tracing: + host: "otel-agent" + port: 6831 + service_name: "stablesats-dev" + +user_trades: + enabled: false + +hedging: + enabled: false diff --git a/dev/vendor/galoy-quickstart/dev/docker-compose.deps.yml b/dev/vendor/galoy-quickstart/dev/docker-compose.deps.yml new file mode 100644 index 0000000000..6c6866fe82 --- /dev/null +++ b/dev/vendor/galoy-quickstart/dev/docker-compose.deps.yml @@ -0,0 +1,356 @@ +#@data/values +--- +version: "3" +services: + price: + image: us.gcr.io/galoy-org/price:edge + ports: + - 50051:50051 + - 9464:9464 + price-history: + image: us.gcr.io/galoy-org/price-history:edge + ports: + - 50052:50052 + command: ./scripts/run-servers-dev.sh + environment: + - DB_HOST=price-history-pg + - DB_PORT=5432 + - DB_USER=galoy-price-usr + - DB_PWD=galoy-price-pwd + - DB_DB=galoy-price-history + - DB_POOL_MIN=1 + - DB_POOL_MAX=5 + - DB_DEBUG=false + depends_on: + - price-history-pg + - price-history-migrate + price-history-migrate: + image: us.gcr.io/galoy-org/price-history-migrate:edge + ports: [] + environment: + - DB_HOST=price-history-pg + - DB_PORT=5432 + - DB_USER=galoy-price-usr + - DB_PWD=galoy-price-pwd + - DB_DB=galoy-price-history + - DB_POOL_MIN=1 + - DB_POOL_MAX=5 + - DB_DEBUG=false + depends_on: + - price-history-pg + price-history-pg: + image: postgres:14.1 + environment: + - POSTGRES_USER=galoy-price-usr + - POSTGRES_PASSWORD=galoy-price-pwd + - POSTGRES_DB=galoy-price-history + api-keys-pg: + image: postgres:14.1 + environment: + - POSTGRES_USER=user + - POSTGRES_PASSWORD=password + - POSTGRES_DB=pg + ports: + - "5431:5432" + notifications-pg: + image: postgres:14.1 + environment: + - POSTGRES_USER=user + - POSTGRES_PASSWORD=password + - POSTGRES_DB=pg + ports: + - "5433:5432" + healthcheck: + test: ["CMD-SHELL", "pg_isready"] + interval: 5s + timeout: 30s + retries: 5 + oathkeeper: + image: oryd/oathkeeper:v0.40.6-distroless + ports: + - "4455:4455" + - "4456:4456" + extra_hosts: + - "bats-tests:host-gateway" + command: serve -c /home/ory/oathkeeper.yml --sqa-opt-out + volumes: + - ${HOST_PROJECT_PATH:-.}/config/ory:/home/ory + depends_on: + - kratos + - hydra + - apollo-router + - otel-agent + hydra: + image: oryd/hydra:v2.1.2 + ports: + - "4444:4444" #! Public port + - "4445:4445" #! Admin port + command: serve -c /home/ory/hydra.yml all --dev + volumes: + - ${HOST_PROJECT_PATH:-.}/config/ory:/home/ory + environment: + - DSN=postgres://hydra:secret@hydra-pg:5432/hydra?sslmode=disable&max_conns=20&max_idle_conns=4 + restart: unless-stopped + depends_on: + - hydra-migrate + - hydra-pg + + hydra-migrate: + image: oryd/hydra:v2.1.2 + environment: + - DSN=postgres://hydra:secret@hydra-pg:5432/hydra?sslmode=disable&max_conns=20&max_idle_conns=4 + command: migrate -c /home/ory/hydra.yml sql -e --yes + volumes: + - ${HOST_PROJECT_PATH:-.}/config/ory:/home/ory + + restart: on-failure + depends_on: + - hydra-pg + + hydra-pg: + image: postgres:14.1 + environment: + - POSTGRES_USER=hydra + - POSTGRES_PASSWORD=secret + - POSTGRES_DB=hydra + kratos: + image: oryd/kratos:v1.0.0 + extra_hosts: + - "bats-tests:host-gateway" + ports: + - "4433:4433" #! public + - "4434:4434" #! admin + entrypoint: sh -c + command: '"kratos migrate sql up -y -e && kratos serve -c /home/ory/kratos.yml --watch-courier --sqa-opt-out"' + environment: + DSN: postgres://dbuser:secret@kratos-pg:5432/default?sslmode=disable + links: + - kratos-pg:kratos-pg + volumes: + - ${HOST_PROJECT_PATH:-.}/config/ory:/home/ory + kratos-pg: + image: postgres:14.1 + ports: + - "5432:5432" + environment: + - POSTGRES_USER=dbuser + - POSTGRES_PASSWORD=secret + - POSTGRES_DB=default + apollo-router: + image: ghcr.io/apollographql/router:v1.25.0 + ports: + - 4004:4004 + extra_hosts: + - "bats-tests:host-gateway" + environment: + - APOLLO_ROUTER_SUPERGRAPH_PATH=/repo/dev/supergraph.graphql + - APOLLO_ROUTER_CONFIG_PATH=/repo/dev/router.yaml + volumes: + - ${HOST_PROJECT_PATH:-.}/config/apollo-federation:/repo/dev + depends_on: + - otel-agent + redis: + image: redis:7.0.8 + ports: + - "6379:6379" + environment: + - ALLOW_EMPTY_PASSWORD=yes + - REDIS_DISABLE_COMMANDS=FLUSHDB,FLUSHALL + mongodb: + image: mongo:7.0.2 + ports: + - "27017:27017" + environment: + - MONGO_INITDB_DATABASE=galoy + lnd1: + image: lightninglabs/lnd:v0.17.3-beta + ports: + - "10009:10009" + volumes: + - ${HOST_PROJECT_PATH:-.}/config/lnd/lnd.conf:/root/.lnd/lnd.conf + - ${HOST_PROJECT_PATH:-.}/config/lnd/tls.key:/root/.lnd/tls.key + - ${HOST_PROJECT_PATH:-.}/config/lnd/tls.cert:/root/.lnd/tls.cert + - ${HOST_PROJECT_PATH:-.}/config/lnd/regtest/lnd1.wallet.db:/root/.lnd/wallet.db + - ${HOST_PROJECT_PATH:-.}/config/lnd/regtest/lnd1.macaroons.db:/root/.lnd/macaroons.db + - ${HOST_PROJECT_PATH:-.}/config/lnd/regtest/lnd1.admin.macaroon:/root/.lnd/admin.macaroon + depends_on: [bitcoind] + entrypoint: ["/bin/sh", "-c"] + command: + - | + mkdir -p /root/.lnd/data/chain/bitcoin/regtest/ + cp /root/.lnd/wallet.db /root/.lnd/data/chain/bitcoin/regtest/wallet.db + cp /root/.lnd/macaroons.db /root/.lnd/data/chain/bitcoin/regtest/macaroons.db + cp /root/.lnd/admin.macaroon /root/.lnd/data/chain/bitcoin/regtest/admin.macaroon + /bin/lnd + lnd2: + image: lightninglabs/lnd:v0.17.3-beta + ports: + - "10010:10009" + volumes: + - ${HOST_PROJECT_PATH:-.}/config/lnd/lnd.conf:/root/.lnd/lnd.conf + - ${HOST_PROJECT_PATH:-.}/config/lnd/tls.key:/root/.lnd/tls.key + - ${HOST_PROJECT_PATH:-.}/config/lnd/tls.cert:/root/.lnd/tls.cert + - ${HOST_PROJECT_PATH:-.}/config/lnd/regtest/lnd2.wallet.db:/root/.lnd/wallet.db + - ${HOST_PROJECT_PATH:-.}/config/lnd/regtest/lnd2.macaroons.db:/root/.lnd/macaroons.db + - ${HOST_PROJECT_PATH:-.}/config/lnd/regtest/lnd2.admin.macaroon:/root/.lnd/admin.macaroon + depends_on: [bitcoind] + entrypoint: ["/bin/sh", "-c"] + command: + - | + mkdir -p /root/.lnd/data/chain/bitcoin/regtest/ + cp /root/.lnd/wallet.db /root/.lnd/data/chain/bitcoin/regtest/wallet.db + cp /root/.lnd/macaroons.db /root/.lnd/data/chain/bitcoin/regtest/macaroons.db + cp /root/.lnd/admin.macaroon /root/.lnd/data/chain/bitcoin/regtest/admin.macaroon + /bin/lnd + lnd-outside-1: + image: lightninglabs/lnd:v0.17.3-beta + ports: + - "10012:10009" + volumes: + - ${HOST_PROJECT_PATH:-.}/config/lnd/lnd.conf:/root/.lnd/lnd.conf + - ${HOST_PROJECT_PATH:-.}/config/lnd/tls.key:/root/.lnd/tls.key + - ${HOST_PROJECT_PATH:-.}/config/lnd/tls.cert:/root/.lnd/tls.cert + - ${HOST_PROJECT_PATH:-.}/config/lnd/regtest/lnd-outside-1.wallet.db:/root/.lnd/wallet.db + - ${HOST_PROJECT_PATH:-.}/config/lnd/regtest/lnd-outside-1.macaroons.db:/root/.lnd/macaroons.db + - ${HOST_PROJECT_PATH:-.}/config/lnd/regtest/lnd-outside-1.admin.macaroon:/root/.lnd/admin.macaroon + entrypoint: ["/bin/sh", "-c"] + command: + - | + mkdir -p /root/.lnd/data/chain/bitcoin/regtest/ + cp /root/.lnd/wallet.db /root/.lnd/data/chain/bitcoin/regtest/wallet.db + cp /root/.lnd/macaroons.db /root/.lnd/data/chain/bitcoin/regtest/macaroons.db + cp /root/.lnd/admin.macaroon /root/.lnd/data/chain/bitcoin/regtest/admin.macaroon + /bin/lnd + depends_on: [bitcoind] + lnd-outside-2: + image: lightninglabs/lnd:v0.17.3-beta + ports: + - "10013:10009" + volumes: + - ${HOST_PROJECT_PATH:-.}/config/lnd/lnd.conf:/root/.lnd/lnd.conf + - ${HOST_PROJECT_PATH:-.}/config/lnd/tls.key:/root/.lnd/tls.key + - ${HOST_PROJECT_PATH:-.}/config/lnd/tls.cert:/root/.lnd/tls.cert + - ${HOST_PROJECT_PATH:-.}/config/lnd/regtest/lnd-outside-2.wallet.db:/root/.lnd/wallet.db + - ${HOST_PROJECT_PATH:-.}/config/lnd/regtest/lnd-outside-2.macaroons.db:/root/.lnd/macaroons.db + - ${HOST_PROJECT_PATH:-.}/config/lnd/regtest/lnd-outside-2.admin.macaroon:/root/.lnd/admin.macaroon + entrypoint: ["/bin/sh", "-c"] + command: + - | + mkdir -p /root/.lnd/data/chain/bitcoin/regtest/ + cp /root/.lnd/wallet.db /root/.lnd/data/chain/bitcoin/regtest/wallet.db + cp /root/.lnd/macaroons.db /root/.lnd/data/chain/bitcoin/regtest/macaroons.db + cp /root/.lnd/admin.macaroon /root/.lnd/data/chain/bitcoin/regtest/admin.macaroon + /bin/lnd + depends_on: [bitcoind] + bria: + image: us.gcr.io/galoy-org/bria:latest + ports: + - "2743:2743" + - "2742:2742" + environment: + - PG_CON=postgres://user:password@bria-pg:5432/pg + - BITCOIND_SIGNER_ENDPOINT=https://bitcoind-signer:18443 + command: + - bria + - daemon + - --config + - /bria.yml + - dev + - -x + - tpubDDDDGYiFda8HfJRc2AHFJDxVzzEtBPrKsbh35EaW2UGd5qfzrF2G87ewAgeeRyHEz4iB3kvhAYW1sH6dpLepTkFUzAktumBN8AXeXWE9nd1 + - -d + - m/84h/0h/0h + volumes: + - ${HOST_PROJECT_PATH:-.}/config/bria.yml:/bria.yml + depends_on: + bitcoind-signer: + condition: service_started + otel-agent: + condition: service_started + fulcrum: + condition: service_started + bria-pg: + condition: service_healthy + bria-pg: + image: postgres:14.1 + environment: + - POSTGRES_USER=user + - POSTGRES_PASSWORD=password + - POSTGRES_DB=pg + healthcheck: + test: ["CMD-SHELL", "pg_isready"] + interval: 5s + timeout: 30s + retries: 5 + fulcrum: + image: cculianu/fulcrum:latest + ports: + - "50001:50001" + depends_on: [bitcoind] + volumes: + - ${HOST_PROJECT_PATH:-.}/config/fulcrum/fulcrum.conf:/fulcrum.conf + - ${HOST_PROJECT_PATH:-.}/config/fulcrum/tls.key:/tls.key + - ${HOST_PROJECT_PATH:-.}/config/fulcrum/tls.cert:/tls.cert + environment: + - DATA_DIR=/db + - SSL_CERTFILE=/tls.cert + - SSL_KEYFILE=/tls.key + command: ["Fulcrum", "/fulcrum.conf"] + bitcoind: + image: lncm/bitcoind:v25.1 + ports: + - "18443:18443" + volumes: + - ${HOST_PROJECT_PATH:-.}/config/bitcoind/bitcoin.conf:/data/.bitcoin/bitcoin.conf + bitcoind-signer: + image: lncm/bitcoind:v25.1 + ports: [] + volumes: + - ${HOST_PROJECT_PATH:-.}/config/bitcoind/bitcoin.conf:/data/.bitcoin/bitcoin.conf + depends_on: [bitcoind] + entrypoint: ["/bin/sh", "-c"] + command: + - | + bitcoind -connect=bitcoind:18444 + otel-agent: + ports: + - "4318:4318" #! http receiver + - "4317:4317" #! grpc receiver + image: otel/opentelemetry-collector-contrib:0.84.0 + command: ["--config=/etc/otel-agent-config.yaml"] + environment: + - HONEYCOMB_DATASET=${HONEYCOMB_DATASET} + - HONEYCOMB_API_KEY=${HONEYCOMB_API_KEY} + volumes: + - ${HOST_PROJECT_PATH:-.}/config/otel-agent-config.yaml:/etc/otel-agent-config.yaml + svix: + image: svix/svix-server:v1.11 + platform: linux/amd64 + environment: + WAIT_FOR: "true" + SVIX_DB_DSN: postgresql://postgres:postgres@svix-pg/postgres + SVIX_JWT_SECRET: 8KjzRXrKkd9YFcNyqLSIY8JwiaCeRc6WK4UkMnSW + SVIX_WHITELIST_SUBNETS: "[0.0.0.0/0]" + SVIX_QUEUE_TYPE: memory + depends_on: + - svix-pg + ports: + - 8071:8071 + extra_hosts: + - bats-tests:host-gateway + svix-pg: + image: postgres:14.1 + environment: + POSTGRES_PASSWORD: postgres + + stablesats: + image: us.gcr.io/galoy-org/stablesats-rs:latest + ports: + - "3325:3325" + command: ["stablesats", "run"] + working_dir: /repo/config + depends_on: + - otel-agent + restart: on-failure:10 + volumes: + - ${HOST_PROJECT_PATH:-.}/:/repo diff --git a/dev/vendor/galoy-quickstart/dev/healthcheck.py b/dev/vendor/galoy-quickstart/dev/healthcheck.py new file mode 100644 index 0000000000..f8bb1f1d33 --- /dev/null +++ b/dev/vendor/galoy-quickstart/dev/healthcheck.py @@ -0,0 +1,165 @@ +#!/usr/bin/env python3 +""" +Detects and reports the max number of open files allowed per process. +""" +import argparse +import subprocess +import shutil +import sys + +MIN_OPENFILES_VALUE = 1024 + + +def main() -> int: + parser = argparse.ArgumentParser(description=__doc__) + parser.parse_args() + + remediations = 0 + + section("Running health check on system for developing in the Galoy project") + + docker_cmd = detect_docker_command() + remediations += docker_cmd + if docker_cmd == 0: + remediations += detect_docker_engine() + remediations += detect_docker_compose() + remediations += detect_nix_bash() + remediations += detect_openfiles_soft_limit() + + blank() + if remediations > 0: + section(f"Health check complete with _{remediations}_ " + "suggested remediation(s)") + else: + section(f"Health check complete with **no** suggested remediations.") + + # If there are remediations, exit non-zero so scripts can detect that the + # current setup may not be healthy + return remediations + + +def detect_docker_command() -> int: + result = detect_command("docker") + return result + + +def detect_docker_engine() -> int: + result = subprocess.run(["docker", "info"], capture_output=True) + if result.returncode == 0: + info("Detected running Docker Engine") + return 0 + else: + warn("Failed to detect running Docker Engine") + indent("Output from `docker info` stderr:") + indent("-----") + for line in result.stderr.splitlines(): + indent(line.decode("ascii")) + indent("-----") + indent("Ensure that the Docker Engine is running and try again") + return 1 + + +def detect_docker_compose() -> int: + result = subprocess.run( + [ + "docker", + "compose", + "version", + ], + capture_output=True, + ) + if result.returncode == 0: + info("Detected Docker Compose is installed") + return 0 + else: + warn("Failed to detect Docker Compose installation") + indent("Output from `docker compose version` stderr:") + indent("-----") + for line in result.stderr.splitlines(): + indent(line.decode("ascii")) + indent("-----") + indent("Ensure that the Docker Compose is running and try again") + return 1 + + +def detect_nix_bash() -> int: + cmd = "bash" + result = shutil.which(cmd) + if result and result.startswith("/nix/store/"): + info(f"Found `{cmd}` in Nix environment") + return 0 + elif result: + warn(f"Failed to find `{cmd}` in Nix environment (cmd={result})") + indent("Ensure that your direnv setup is correct or that you have ran " + "`nix develop`") + return 1 + else: + warn(f"Failed to find `{cmd}` in Nix environment or on system") + indent("Ensure that your direnv setup is correct or that you have ran " + "`nix develop`") + return 1 + + +def detect_openfiles_soft_limit() -> int: + soft_limit = current_openfiles_soft_limit() + + if soft_limit < MIN_OPENFILES_VALUE: + new = MIN_OPENFILES_VALUE + warn("Low value for max open files soft limit detected in " + f"current shell (current={soft_limit})") + blank() + indent("To set a value for this shell session **only** run:") + indent(f"ulimit -Sn {new}", amount=2) + blank() + indent( + "To make a **permanent** change for all new shell sessions run:") + indent(f"echo 'ulimit -Sn {new}' >>\"$HOME/.profile\"", amount=2) + return 1 + else: + info("Reasonable value for max open files soft limit detected in " + f"current shell (current={soft_limit})") + return 0 + + +def detect_command(cmd: str) -> int: + result = shutil.which(cmd) + if result: + info(f"Detected `{cmd}` command (cmd={result})") + return 0 + else: + warn(f"Failed to find `{cmd}` on PATH and is required for development") + return 1 + + +def current_openfiles_soft_limit() -> int: + result = subprocess.run( + ["bash", "-c", "ulimit -Sn"], + capture_output=True, + ) + result.check_returncode() + return int(result.stdout.strip().decode("ascii")) + + +def section(msg: str): + print(f"--- {msg}") + + +def info(msg: str): + print(f" - {msg}") + + +def warn(msg: str): + print(f" x {msg}") + + +def indent(msg: str, amount=1): + print("{:>{width}}{}".format("", msg, width=amount * 4)) + + +def blank(): + print("") + + +if __name__ == "__main__": + sys.exit(main()) + diff --git a/dev/vendor/galoy-quickstart/dev/helpers/auth.sh b/dev/vendor/galoy-quickstart/dev/helpers/auth.sh new file mode 100644 index 0000000000..f2e78b4c48 --- /dev/null +++ b/dev/vendor/galoy-quickstart/dev/helpers/auth.sh @@ -0,0 +1,15 @@ +#!/bin/bash + +AUTH_ENDPOINT="http://localhost:4455/auth/phone/login" + +login_user() { + phone="$1" + + login_response=$(curl \ + -s \ + -X POST $AUTH_ENDPOINT \ + -H "Content-Type: application/json" \ + -d '{"phone": "'$phone'", "code":"000000"}') + + echo "$login_response" | jq -r '.authToken' +} diff --git a/dev/vendor/galoy-quickstart/dev/helpers/cli.sh b/dev/vendor/galoy-quickstart/dev/helpers/cli.sh new file mode 100755 index 0000000000..f86979a0cc --- /dev/null +++ b/dev/vendor/galoy-quickstart/dev/helpers/cli.sh @@ -0,0 +1,54 @@ +#!/bin/bash + +COMPOSE_PROJECT_NAME="${COMPOSE_PROJECT_NAME:-quickstart}" + +bitcoin_cli() { + docker exec "${COMPOSE_PROJECT_NAME}-bitcoind-1" bitcoin-cli "$@" +} + +bitcoin_signer_cli() { + docker exec "${COMPOSE_PROJECT_NAME}-bitcoind-signer-1" bitcoin-cli "$@" +} + +bria_cli() { + docker exec "${COMPOSE_PROJECT_NAME}-bria-1" bria "$@" +} + +lnd_cli() { + docker exec "${COMPOSE_PROJECT_NAME}-lnd1-1" \ + lncli \ + --macaroonpath /root/.lnd/admin.macaroon \ + --tlscertpath /root/.lnd/tls.cert \ + $@ +} + +lnd_outside_cli() { + docker exec "${COMPOSE_PROJECT_NAME}-lnd-outside-1-1" \ + lncli \ + --macaroonpath /root/.lnd/admin.macaroon \ + --tlscertpath /root/.lnd/tls.cert \ + $@ +} + +lnd_outside_2_cli() { + docker exec "${COMPOSE_PROJECT_NAME}-lnd-outside-2-1" \ + lncli \ + --macaroonpath /root/.lnd/admin.macaroon \ + --tlscertpath /root/.lnd/tls.cert \ + $@ +} + +hydra_cli() { + docker exec "${COMPOSE_PROJECT_NAME}-hydra-1" hydra "$@" +} + +kratos_pg() { + DB_USER="dbuser" + DB_NAME="default" + + docker exec "${COMPOSE_PROJECT_NAME}-kratos-pg-1" psql -U $DB_USER -d $DB_NAME -t "$@" +} + +mongo_cli() { + docker exec "${COMPOSE_PROJECT_NAME}-mongodb-1" mongosh --quiet mongodb://localhost:27017/galoy --eval $@ +} diff --git a/dev/vendor/galoy-quickstart/dev/helpers/gql.sh b/dev/vendor/galoy-quickstart/dev/helpers/gql.sh new file mode 100644 index 0000000000..4ed0b44ba9 --- /dev/null +++ b/dev/vendor/galoy-quickstart/dev/helpers/gql.sh @@ -0,0 +1,58 @@ +#!/bin/bash + +GQL_DIR="$(dirname "$(readlink -f "${BASH_SOURCE[0]}")")/gql" +HELPERS_DIR="$(dirname "$(readlink -f "${BASH_SOURCE[0]}")")" +source "${HELPERS_DIR}/cli.sh" + +GALOY_ENDPOINT="http://localhost:4455/graphql" + +register_email_to_user() { + local token=$1 + local email=$2 + + variables="{\"input\": {\"email\": \"$email\"}}" + registration_id=$(exec_graphql $token 'user-email-registration-initiate' "${variables}" '.data.userEmailRegistrationInitiate.emailRegistrationId') + + email_code_response=$(kratos_pg -c "SELECT body FROM courier_messages WHERE recipient='$email' ORDER BY created_at DESC LIMIT 1;") + email_code=$(echo "$email_code_response" | grep -oP '\d{6}') + + variables="{\"input\": {\"code\": \"$email_code\", \"emailRegistrationId\": \"$registration_id\"}}" + exec_graphql $token 'user-email-registration-validate' "${variables}" +} + +gql_file() { + echo "${GQL_DIR}/$1.gql" +} + +gql_query() { + cat "$(gql_file $1)" | tr '\n' ' ' | sed 's/"/\\"/g' +} + +exec_graphql() { + local token=$1 + local query_name=$2 + local variables=${3:-"{}"} + local output=${4:-"."} + + if [[ ${token} == "anon" ]]; then + AUTH_HEADER="" + else + AUTH_HEADER="Authorization: Bearer ${token}" + fi + + curl -s \ + -X POST \ + ${AUTH_HEADER:+ -H "$AUTH_HEADER"} \ + -H "Content-Type: application/json" \ + -H "X-Idempotency-Key: $(random_uuid)" \ + -d "{\"query\": \"$(gql_query $query_name)\", \"variables\": $variables}" \ + "${GALOY_ENDPOINT}" | jq -r "${output}" +} + +random_uuid() { + if [[ -e /proc/sys/kernel/random/uuid ]]; then + cat /proc/sys/kernel/random/uuid + else + uuidgen + fi +} diff --git a/dev/vendor/galoy-quickstart/dev/helpers/gql/default-account.gql b/dev/vendor/galoy-quickstart/dev/helpers/gql/default-account.gql new file mode 100644 index 0000000000..d32015b3b8 --- /dev/null +++ b/dev/vendor/galoy-quickstart/dev/helpers/gql/default-account.gql @@ -0,0 +1,7 @@ +query defaultAccount { + me { + defaultAccount { + id + } + } +} diff --git a/dev/vendor/galoy-quickstart/dev/helpers/gql/on-chain-address-create.gql b/dev/vendor/galoy-quickstart/dev/helpers/gql/on-chain-address-create.gql new file mode 100644 index 0000000000..b8992d2763 --- /dev/null +++ b/dev/vendor/galoy-quickstart/dev/helpers/gql/on-chain-address-create.gql @@ -0,0 +1,8 @@ +mutation onChainAddressCreate($input: OnChainAddressCreateInput!) { + onChainAddressCreate(input: $input) { + address + errors { + message + } + } +} diff --git a/dev/vendor/galoy-quickstart/dev/helpers/gql/transactions.gql b/dev/vendor/galoy-quickstart/dev/helpers/gql/transactions.gql new file mode 100644 index 0000000000..5955d7a311 --- /dev/null +++ b/dev/vendor/galoy-quickstart/dev/helpers/gql/transactions.gql @@ -0,0 +1,66 @@ +query transactions($walletIds: [WalletId], $first: Int, $after: String) { + me { + defaultAccount { + defaultWallet { + id + } + transactions(walletIds: $walletIds, first: $first, after: $after) { + ...TransactionList + } + } + } +} + +fragment TransactionList on TransactionConnection { + pageInfo { + hasNextPage + } + edges { + cursor + node { + __typename + id + status + direction + memo + createdAt + settlementAmount + settlementFee + settlementDisplayAmount + settlementDisplayFee + settlementDisplayCurrency + settlementCurrency + settlementPrice { + base + offset + } + initiationVia { + __typename + ... on InitiationViaIntraLedger { + counterPartyWalletId + counterPartyUsername + } + ... on InitiationViaLn { + paymentHash + paymentRequest + } + ... on InitiationViaOnChain { + address + } + } + settlementVia { + __typename + ... on SettlementViaIntraLedger { + counterPartyWalletId + counterPartyUsername + } + ... on SettlementViaLn { + preImage + } + ... on SettlementViaOnChain { + transactionHash + } + } + } + } +} diff --git a/dev/vendor/galoy-quickstart/dev/helpers/gql/update-username.gql b/dev/vendor/galoy-quickstart/dev/helpers/gql/update-username.gql new file mode 100644 index 0000000000..47b734f166 --- /dev/null +++ b/dev/vendor/galoy-quickstart/dev/helpers/gql/update-username.gql @@ -0,0 +1,10 @@ +mutation UserUpdateUsername($input: UserUpdateUsernameInput!) { + userUpdateUsername(input: $input) { + errors { + message + } + user { + id + } + } +} diff --git a/dev/vendor/galoy-quickstart/dev/helpers/gql/user-email-registration-initiate.gql b/dev/vendor/galoy-quickstart/dev/helpers/gql/user-email-registration-initiate.gql new file mode 100644 index 0000000000..e71d774a3d --- /dev/null +++ b/dev/vendor/galoy-quickstart/dev/helpers/gql/user-email-registration-initiate.gql @@ -0,0 +1,15 @@ +mutation userEmailRegistrationInitiate($input: UserEmailRegistrationInitiateInput!) { + userEmailRegistrationInitiate(input: $input) { + errors { + message + } + emailRegistrationId + me { + id + email { + address + verified + } + } + } +} diff --git a/dev/vendor/galoy-quickstart/dev/helpers/gql/user-email-registration-validate.gql b/dev/vendor/galoy-quickstart/dev/helpers/gql/user-email-registration-validate.gql new file mode 100644 index 0000000000..14fc670c2f --- /dev/null +++ b/dev/vendor/galoy-quickstart/dev/helpers/gql/user-email-registration-validate.gql @@ -0,0 +1,14 @@ +mutation userEmailRegistrationValidate($input: UserEmailRegistrationValidateInput!) { + userEmailRegistrationValidate(input: $input) { + errors { + message + } + me { + id + email { + address + verified + } + } + } +} diff --git a/dev/vendor/galoy-quickstart/dev/helpers/gql/wallets-for-account.gql b/dev/vendor/galoy-quickstart/dev/helpers/gql/wallets-for-account.gql new file mode 100644 index 0000000000..4679226643 --- /dev/null +++ b/dev/vendor/galoy-quickstart/dev/helpers/gql/wallets-for-account.gql @@ -0,0 +1,13 @@ +query me { + me { + defaultAccount { + id + wallets { + id + walletCurrency + balance + pendingIncomingBalance + } + } + } +} diff --git a/dev/vendor/galoy-quickstart/dev/helpers/onchain.sh b/dev/vendor/galoy-quickstart/dev/helpers/onchain.sh new file mode 100644 index 0000000000..f521d08496 --- /dev/null +++ b/dev/vendor/galoy-quickstart/dev/helpers/onchain.sh @@ -0,0 +1,59 @@ +DEV_DIR="$(dirname "$(dirname "$(readlink -f "${BASH_SOURCE[0]}")")")" +source "${DEV_DIR}/helpers/gql.sh" +source "${DEV_DIR}/helpers/cli.sh" + + +fund_user_onchain() { + local token=$1 + local wallet_currency=$2 + local btc_amount_in_btc=${3:-"0.01"} + + response="$(exec_graphql "$token" "wallets-for-account")" + wallet_id=$(echo "$response" | jq -r --arg wc "$wallet_currency" '.data.me.defaultAccount.wallets[] | select(.walletCurrency == $wc) .id') + + echo "Creating variables for GraphQL query for :====> $wallet_id wallet ID i.e :===> $wallet_currency" + variables=$( + jq -n \ + --arg wallet_id "$wallet_id" \ + '{input: {walletId: $wallet_id}}' + ) + + response=$(exec_graphql "$token" 'on-chain-address-create' "$variables") + address=$(echo "$response" | jq -r '.data.onChainAddressCreate.address') + [[ "${address}" != "null" ]] || exit 1 + + + bitcoin_cli -regtest loadwallet "outside" + bitcoin_cli -regtest listwallets + bitcoin_cli -regtest sendtoaddress "$address" "$btc_amount_in_btc" + bitcoin_cli -regtest -generate 4 + + variables=$( + jq -n \ + --argjson first "1" \ + '{"first": $first}' + ) + local success=false + for i in {1..60}; do + response=$(exec_graphql "$token" 'transactions' "$variables") + jq_query='.data.me.defaultAccount.transactions.edges[] | select(.node.initiationVia.address == $address) .node' + transaction_info=$(echo $response \ + | jq -r --arg address "$address" "$jq_query") + + settled_status=$(echo "$transaction_info" | jq -r ".status") + settled_currency=$(echo "$transaction_info" | jq -r ".settlementCurrency") + + if [[ "${settled_status}" == "SUCCESS" && "${settled_currency}" == "$wallet_currency" ]]; then + echo "Transaction successful with correct settlement currency" + success=true + break + fi + + sleep 1 + done + + if [[ $success != true ]]; then + echo "Failed to fund user: response ==> $response" + exit 1 + fi +} diff --git a/dev/vendor/galoy-quickstart/dev/tilt.bzl b/dev/vendor/galoy-quickstart/dev/tilt.bzl new file mode 100644 index 0000000000..0305c605f3 --- /dev/null +++ b/dev/vendor/galoy-quickstart/dev/tilt.bzl @@ -0,0 +1,51 @@ +def tilt_impl(ctx: AnalysisContext) -> list[[DefaultInfo, RunInfo]]: + return _invoke_tilt(ctx, ctx.attrs.subcmd) + +tilt = rule( + impl = tilt_impl, + attrs = { + "subcmd": attrs.enum(["up", "down"]), + "tiltfile": attrs.string( + default = "Tiltfile", + doc = """The Tiltfile to run.""", + ), + "args": attrs.list( + attrs.string(), + default = [], + doc = """Additional arguments passed as .""", + ), + }, +) + +def _invoke_tilt(ctx: AnalysisContext, subcmd: str) -> list[[DefaultInfo, RunInfo]]: + tiltfile = "{}/{}".format( + ctx.label.package, + ctx.attrs.tiltfile, + ) + + script = ctx.actions.write("tilt-run.sh", """\ +#!/usr/bin/env bash +set -euo pipefail + +rootpath="$(git rev-parse --show-toplevel)" +subcmd="$1" +tiltfile="$2" +args=("${@:3}") + +exec tilt "$subcmd" --file "$rootpath"/"$tiltfile" -- "${args[@]}" +""", is_executable = True) + + run_cmd_args = cmd_args([ + script, + subcmd, + tiltfile, + ctx.attrs.args + ]) + + args_file = ctx.actions.write("tilt-args.txt", run_cmd_args) + + return [ + DefaultInfo(default_output = args_file), + RunInfo(run_cmd_args), + ] + diff --git a/dev/vendor/galoy-quickstart/docker-compose.yml b/dev/vendor/galoy-quickstart/docker-compose.yml new file mode 100644 index 0000000000..951b087fea --- /dev/null +++ b/dev/vendor/galoy-quickstart/docker-compose.yml @@ -0,0 +1,465 @@ +version: "3" +services: + quickstart-test: + image: busybox + depends_on: + - apollo-router + - oathkeeper + - kratos + - galoy + - trigger + - redis + - mongodb + - mongodb-migrate + - price + - bitcoind + - bitcoind-signer + - lnd1 + - lnd-outside-1 + - bria + - fulcrum + - stablesats + - svix + - hydra + restart: on-failure:10 + apollo-router: + image: ghcr.io/apollographql/router:v1.25.0 + ports: + - 4004:4004 + environment: + - APOLLO_ROUTER_SUPERGRAPH_PATH=/repo/dev/supergraph.graphql + - APOLLO_ROUTER_CONFIG_PATH=/repo/dev/router.yaml + volumes: + - ${HOST_PROJECT_PATH:-.}/${GALOY_QUICKSTART_PATH:-vendor/galoy-quickstart}/dev/config/apollo-federation:/repo/dev + depends_on: + - otel-agent + oathkeeper: + image: oryd/oathkeeper:v0.40.6-distroless + ports: + - 4455:4455 + - 4456:4456 + command: serve -c /home/ory/oathkeeper.yml --sqa-opt-out + volumes: + - ${HOST_PROJECT_PATH:-.}/${GALOY_QUICKSTART_PATH:-vendor/galoy-quickstart}/dev/config/ory:/home/ory + depends_on: + - kratos + - hydra + - apollo-router + - otel-agent + kratos: + image: oryd/kratos:v1.0.0 + ports: + - 4433:4433 + - 4434:4434 + entrypoint: sh -c + command: '"kratos migrate sql up -y -e && kratos serve -c /home/ory/kratos.yml --watch-courier --sqa-opt-out"' + environment: + DSN: postgres://dbuser:secret@kratos-pg:5432/default?sslmode=disable + links: + - kratos-pg:kratos-pg + volumes: + - ${HOST_PROJECT_PATH:-.}/${GALOY_QUICKSTART_PATH:-vendor/galoy-quickstart}/dev/config/ory:/home/ory + kratos-pg: + image: postgres:14.1 + ports: + - 5432:5432 + environment: + - POSTGRES_USER=dbuser + - POSTGRES_PASSWORD=secret + - POSTGRES_DB=default + hydra: + image: oryd/hydra:v2.1.2 + ports: + - 4444:4444 + - 4445:4445 + command: serve -c /home/ory/hydra.yml all --dev + volumes: + - ${HOST_PROJECT_PATH:-.}/${GALOY_QUICKSTART_PATH:-vendor/galoy-quickstart}/dev/config/ory:/home/ory + environment: + - DSN=postgres://hydra:secret@hydra-pg:5432/hydra?sslmode=disable&max_conns=20&max_idle_conns=4 + restart: unless-stopped + depends_on: + - hydra-migrate + - hydra-pg + hydra-migrate: + image: oryd/hydra:v2.1.2 + environment: + - DSN=postgres://hydra:secret@hydra-pg:5432/hydra?sslmode=disable&max_conns=20&max_idle_conns=4 + command: migrate -c /home/ory/hydra.yml sql -e --yes + volumes: + - ${HOST_PROJECT_PATH:-.}/${GALOY_QUICKSTART_PATH:-vendor/galoy-quickstart}/dev/config/ory:/home/ory + restart: on-failure + depends_on: + - hydra-pg + hydra-pg: + image: postgres:14.1 + environment: + - POSTGRES_USER=hydra + - POSTGRES_PASSWORD=secret + - POSTGRES_DB=hydra + galoy: + image: us.gcr.io/galoy-org/galoy-api@sha256:c707ddebb0e6e8e79bd1c7dd58b7483064c77609e9eb30fd0a5c59f1d6206af3 + environment: + - HELMREVISION=dev + - NETWORK=regtest + - OATHKEEPER_DECISION_ENDPOINT=http://oathkeeper:4456 + - TWILIO_ACCOUNT_SID=AC_twilio_id + - TWILIO_AUTH_TOKEN=AC_twilio_auth_token + - TWILIO_VERIFY_SERVICE_ID=VA_twilio_service + - KRATOS_PG_CON=postgres://dbuser:secret@kratos-pg:5432/default?sslmode=disable + - KRATOS_PUBLIC_API=http://kratos:4433 + - KRATOS_ADMIN_API=http://kratos:4434 + - KRATOS_MASTER_USER_PASSWORD=passwordHardtoFindWithNumber123 + - KRATOS_CALLBACK_API_KEY=The-Value-of-My-Key + - PRICE_HOST=price + - PRICE_HISTORY_HOST=price-history + - PRICE_SERVER_HOST=stablesats + - BRIA_HOST=bria + - BRIA_API_KEY=bria_dev_000000000000000000000 + - NOTIFICATIONS_HOST=notifications + - MONGODB_CON=mongodb://mongodb:27017/galoy + - REDIS_MASTER_NAME=mymaster + - REDIS_PASSWORD= + - REDIS_0_DNS=redis + - REDIS_0_PORT=6379 + - REDIS_TYPE=standalone + - UNSECURE_IP_FROM_REQUEST_OBJECT=true + - UNSECURE_DEFAULT_LOGIN_CODE=000000 + - GEETEST_ID=geetest_id + - GEETEST_KEY=geetest_key + - LND1_TLS=LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUNZVENDQWdlZ0F3SUJBZ0lSQU9zZzdYWFR4cnVZYlhkeTY2d3RuN1F3Q2dZSUtvWkl6ajBFQXdJd09ERWYKTUIwR0ExVUVDaE1XYkc1a0lHRjFkRzluWlc1bGNtRjBaV1FnWTJWeWRERVZNQk1HQTFVRUF4TU1PRFl4T1RneApNak5tT0Roak1CNFhEVEl6TURFeE9USXdOREUxTTFvWERUTTBNRGN5TVRJd05ERTFNMW93T0RFZk1CMEdBMVVFCkNoTVdiRzVrSUdGMWRHOW5aVzVsY21GMFpXUWdZMlZ5ZERFVk1CTUdBMVVFQXhNTU9EWXhPVGd4TWpObU9EaGoKTUZrd0V3WUhLb1pJemowQ0FRWUlLb1pJemowREFRY0RRZ0FFM1lieUlKWU1Vcm8zZkl0UFFucysxZ2lpTXI5NQpJUXRmclFDQ2JhOWVtcjI4TENmbk1vYy9VQVFwUlg3QVlvVFRneUdiMFBuZGNUODF5ZVgvYTlPa0RLT0I4VENCCjdqQU9CZ05WSFE4QkFmOEVCQU1DQXFRd0V3WURWUjBsQkF3d0NnWUlLd1lCQlFVSEF3RXdEd1lEVlIwVEFRSC8KQkFVd0F3RUIvekFkQmdOVkhRNEVGZ1FVL1AxRHpJUkRzTEhHMU10d3NrZE5nZ0lub1Mwd2daWUdBMVVkRVFTQgpqakNCaTRJTU9EWXhPVGd4TWpObU9EaGpnZ2xzYjJOaGJHaHZjM1NDRFd4dVpDMXZkWFJ6YVdSbExUR0NEV3h1ClpDMXZkWFJ6YVdSbExUS0NEV3h1WkMxdmRYUnphV1JsTFRPQ0JHeHVaREdDQkd4dVpES0NCSFZ1YVhpQ0NuVnUKYVhod1lXTnJaWFNDQjJKMVptTnZibTZIQkg4QUFBR0hFQUFBQUFBQUFBQUFBQUFBQUFBQUFBR0hCS3dUQUJBdwpDZ1lJS29aSXpqMEVBd0lEU0FBd1JRSWhBSU5DNlJWQ3d6SzFYRnFxeVNLY0Y4QzQ5ZFlSOThjemdLNVdkcmNOCkxYYWlBaUJHYmtWeGhaeHdDaDVLQ1o1Z2M1Q2FsQ0RvaGNxVkdiaHNya0hHTFhpdHN3PT0KLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQo= + - LND1_MACAROON=AgEDbG5kAvgBAwoQB1FdhGa9xoewc1LEXmnURRIBMBoWCgdhZGRyZXNzEgRyZWFkEgV3cml0ZRoTCgRpbmZvEgRyZWFkEgV3cml0ZRoXCghpbnZvaWNlcxIEcmVhZBIFd3JpdGUaIQoIbWFjYXJvb24SCGdlbmVyYXRlEgRyZWFkEgV3cml0ZRoWCgdtZXNzYWdlEgRyZWFkEgV3cml0ZRoXCghvZmZjaGFpbhIEcmVhZBIFd3JpdGUaFgoHb25jaGFpbhIEcmVhZBIFd3JpdGUaFAoFcGVlcnMSBHJlYWQSBXdyaXRlGhgKBnNpZ25lchIIZ2VuZXJhdGUSBHJlYWQAAAYgqHDdwGCqx0aQL1/Z3uUfzCpeBhfapGf9s/AZPOVwf6s= + - LND1_PUBKEY=03ca1907342d5d37744cb7038375e1867c24a87564c293157c95b2a9d38dcfb4c2 + - LND1_DNS=lnd1 + - LND1_RPCPORT=10009 + - LND1_NAME=lnd1 + - LND1_TYPE=offchain,onchain + - LND2_TLS=LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUNZVENDQWdlZ0F3SUJBZ0lSQU9zZzdYWFR4cnVZYlhkeTY2d3RuN1F3Q2dZSUtvWkl6ajBFQXdJd09ERWYKTUIwR0ExVUVDaE1XYkc1a0lHRjFkRzluWlc1bGNtRjBaV1FnWTJWeWRERVZNQk1HQTFVRUF4TU1PRFl4T1RneApNak5tT0Roak1CNFhEVEl6TURFeE9USXdOREUxTTFvWERUTTBNRGN5TVRJd05ERTFNMW93T0RFZk1CMEdBMVVFCkNoTVdiRzVrSUdGMWRHOW5aVzVsY21GMFpXUWdZMlZ5ZERFVk1CTUdBMVVFQXhNTU9EWXhPVGd4TWpObU9EaGoKTUZrd0V3WUhLb1pJemowQ0FRWUlLb1pJemowREFRY0RRZ0FFM1lieUlKWU1Vcm8zZkl0UFFucysxZ2lpTXI5NQpJUXRmclFDQ2JhOWVtcjI4TENmbk1vYy9VQVFwUlg3QVlvVFRneUdiMFBuZGNUODF5ZVgvYTlPa0RLT0I4VENCCjdqQU9CZ05WSFE4QkFmOEVCQU1DQXFRd0V3WURWUjBsQkF3d0NnWUlLd1lCQlFVSEF3RXdEd1lEVlIwVEFRSC8KQkFVd0F3RUIvekFkQmdOVkhRNEVGZ1FVL1AxRHpJUkRzTEhHMU10d3NrZE5nZ0lub1Mwd2daWUdBMVVkRVFTQgpqakNCaTRJTU9EWXhPVGd4TWpObU9EaGpnZ2xzYjJOaGJHaHZjM1NDRFd4dVpDMXZkWFJ6YVdSbExUR0NEV3h1ClpDMXZkWFJ6YVdSbExUS0NEV3h1WkMxdmRYUnphV1JsTFRPQ0JHeHVaREdDQkd4dVpES0NCSFZ1YVhpQ0NuVnUKYVhod1lXTnJaWFNDQjJKMVptTnZibTZIQkg4QUFBR0hFQUFBQUFBQUFBQUFBQUFBQUFBQUFBR0hCS3dUQUJBdwpDZ1lJS29aSXpqMEVBd0lEU0FBd1JRSWhBSU5DNlJWQ3d6SzFYRnFxeVNLY0Y4QzQ5ZFlSOThjemdLNVdkcmNOCkxYYWlBaUJHYmtWeGhaeHdDaDVLQ1o1Z2M1Q2FsQ0RvaGNxVkdiaHNya0hHTFhpdHN3PT0KLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQo= + - LND2_MACAROON=AgEDbG5kAvgBAwoQX0BxfhQTxLTiqaceBnGnfBIBMBoWCgdhZGRyZXNzEgRyZWFkEgV3cml0ZRoTCgRpbmZvEgRyZWFkEgV3cml0ZRoXCghpbnZvaWNlcxIEcmVhZBIFd3JpdGUaIQoIbWFjYXJvb24SCGdlbmVyYXRlEgRyZWFkEgV3cml0ZRoWCgdtZXNzYWdlEgRyZWFkEgV3cml0ZRoXCghvZmZjaGFpbhIEcmVhZBIFd3JpdGUaFgoHb25jaGFpbhIEcmVhZBIFd3JpdGUaFAoFcGVlcnMSBHJlYWQSBXdyaXRlGhgKBnNpZ25lchIIZ2VuZXJhdGUSBHJlYWQAAAYgMAKlr1HehfBpn2R5RPE2IuY9r/18QBeLZxYgRidpos4= + - LND2_PUBKEY=039341ef13e776dc1611502cf510110d9ac5cdc252141f5997adcfd72cef34c3a7 + - LND2_DNS=lnd2 + - LND2_RPCPORT=10010 + - LND2_NAME=lnd2 + - LND2_TYPE=offchain + - SVIX_SECRET=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE2OTE2NzIwMTQsImV4cCI6MjAwNzAzMjAxNCwibmJmIjoxNjkxNjcyMDE0LCJpc3MiOiJzdml4LXNlcnZlciIsInN1YiI6Im9yZ18yM3JiOFlkR3FNVDBxSXpwZ0d3ZFhmSGlyTXUifQ.b9s0aWSisNdUNki4edabBEToLNSwjC9-AiJQr4J3y4E + - SVIX_ENDPOINT=http://svix:8071 + - EXPORTER_PORT=3003 + - OTEL_EXPORTER_OTLP_ENDPOINT=http://otel-agent:4318 + depends_on: + - trigger + - apollo-router + - oathkeeper + - kratos + - lnd1 + - lnd-outside-1 + - bria + - mongodb + - redis + - stablesats + networks: + default: + aliases: + - bats-tests + trigger: + image: us.gcr.io/galoy-org/galoy-api-trigger@sha256:8c6224c7478ec509bdda00ec61cdcd68c964bffd6c8aebfbbc66ea396579f6a3 + environment: + - HELMREVISION=dev + - NETWORK=regtest + - OATHKEEPER_DECISION_ENDPOINT=http://oathkeeper:4456 + - TWILIO_ACCOUNT_SID=AC_twilio_id + - TWILIO_AUTH_TOKEN=AC_twilio_auth_token + - TWILIO_VERIFY_SERVICE_ID=VA_twilio_service + - KRATOS_PG_CON=postgres://dbuser:secret@kratos-pg:5432/default?sslmode=disable + - KRATOS_PUBLIC_API=http://kratos:4433 + - KRATOS_ADMIN_API=http://kratos:4434 + - KRATOS_MASTER_USER_PASSWORD=passwordHardtoFindWithNumber123 + - KRATOS_CALLBACK_API_KEY=The-Value-of-My-Key + - PRICE_HOST=price + - PRICE_HISTORY_HOST=price-history + - PRICE_SERVER_HOST=stablesats + - BRIA_HOST=bria + - BRIA_API_KEY=bria_dev_000000000000000000000 + - NOTIFICATIONS_HOST=notifications + - MONGODB_CON=mongodb://mongodb:27017/galoy + - REDIS_MASTER_NAME=mymaster + - REDIS_PASSWORD= + - REDIS_0_DNS=redis + - REDIS_0_PORT=6379 + - REDIS_TYPE=standalone + - UNSECURE_IP_FROM_REQUEST_OBJECT=true + - UNSECURE_DEFAULT_LOGIN_CODE=000000 + - GEETEST_ID=geetest_id + - GEETEST_KEY=geetest_key + - LND1_TLS=LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUNZVENDQWdlZ0F3SUJBZ0lSQU9zZzdYWFR4cnVZYlhkeTY2d3RuN1F3Q2dZSUtvWkl6ajBFQXdJd09ERWYKTUIwR0ExVUVDaE1XYkc1a0lHRjFkRzluWlc1bGNtRjBaV1FnWTJWeWRERVZNQk1HQTFVRUF4TU1PRFl4T1RneApNak5tT0Roak1CNFhEVEl6TURFeE9USXdOREUxTTFvWERUTTBNRGN5TVRJd05ERTFNMW93T0RFZk1CMEdBMVVFCkNoTVdiRzVrSUdGMWRHOW5aVzVsY21GMFpXUWdZMlZ5ZERFVk1CTUdBMVVFQXhNTU9EWXhPVGd4TWpObU9EaGoKTUZrd0V3WUhLb1pJemowQ0FRWUlLb1pJemowREFRY0RRZ0FFM1lieUlKWU1Vcm8zZkl0UFFucysxZ2lpTXI5NQpJUXRmclFDQ2JhOWVtcjI4TENmbk1vYy9VQVFwUlg3QVlvVFRneUdiMFBuZGNUODF5ZVgvYTlPa0RLT0I4VENCCjdqQU9CZ05WSFE4QkFmOEVCQU1DQXFRd0V3WURWUjBsQkF3d0NnWUlLd1lCQlFVSEF3RXdEd1lEVlIwVEFRSC8KQkFVd0F3RUIvekFkQmdOVkhRNEVGZ1FVL1AxRHpJUkRzTEhHMU10d3NrZE5nZ0lub1Mwd2daWUdBMVVkRVFTQgpqakNCaTRJTU9EWXhPVGd4TWpObU9EaGpnZ2xzYjJOaGJHaHZjM1NDRFd4dVpDMXZkWFJ6YVdSbExUR0NEV3h1ClpDMXZkWFJ6YVdSbExUS0NEV3h1WkMxdmRYUnphV1JsTFRPQ0JHeHVaREdDQkd4dVpES0NCSFZ1YVhpQ0NuVnUKYVhod1lXTnJaWFNDQjJKMVptTnZibTZIQkg4QUFBR0hFQUFBQUFBQUFBQUFBQUFBQUFBQUFBR0hCS3dUQUJBdwpDZ1lJS29aSXpqMEVBd0lEU0FBd1JRSWhBSU5DNlJWQ3d6SzFYRnFxeVNLY0Y4QzQ5ZFlSOThjemdLNVdkcmNOCkxYYWlBaUJHYmtWeGhaeHdDaDVLQ1o1Z2M1Q2FsQ0RvaGNxVkdiaHNya0hHTFhpdHN3PT0KLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQo= + - LND1_MACAROON=AgEDbG5kAvgBAwoQB1FdhGa9xoewc1LEXmnURRIBMBoWCgdhZGRyZXNzEgRyZWFkEgV3cml0ZRoTCgRpbmZvEgRyZWFkEgV3cml0ZRoXCghpbnZvaWNlcxIEcmVhZBIFd3JpdGUaIQoIbWFjYXJvb24SCGdlbmVyYXRlEgRyZWFkEgV3cml0ZRoWCgdtZXNzYWdlEgRyZWFkEgV3cml0ZRoXCghvZmZjaGFpbhIEcmVhZBIFd3JpdGUaFgoHb25jaGFpbhIEcmVhZBIFd3JpdGUaFAoFcGVlcnMSBHJlYWQSBXdyaXRlGhgKBnNpZ25lchIIZ2VuZXJhdGUSBHJlYWQAAAYgqHDdwGCqx0aQL1/Z3uUfzCpeBhfapGf9s/AZPOVwf6s= + - LND1_PUBKEY=03ca1907342d5d37744cb7038375e1867c24a87564c293157c95b2a9d38dcfb4c2 + - LND1_DNS=lnd1 + - LND1_RPCPORT=10009 + - LND1_NAME=lnd1 + - LND1_TYPE=offchain,onchain + - LND2_TLS=LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUNZVENDQWdlZ0F3SUJBZ0lSQU9zZzdYWFR4cnVZYlhkeTY2d3RuN1F3Q2dZSUtvWkl6ajBFQXdJd09ERWYKTUIwR0ExVUVDaE1XYkc1a0lHRjFkRzluWlc1bGNtRjBaV1FnWTJWeWRERVZNQk1HQTFVRUF4TU1PRFl4T1RneApNak5tT0Roak1CNFhEVEl6TURFeE9USXdOREUxTTFvWERUTTBNRGN5TVRJd05ERTFNMW93T0RFZk1CMEdBMVVFCkNoTVdiRzVrSUdGMWRHOW5aVzVsY21GMFpXUWdZMlZ5ZERFVk1CTUdBMVVFQXhNTU9EWXhPVGd4TWpObU9EaGoKTUZrd0V3WUhLb1pJemowQ0FRWUlLb1pJemowREFRY0RRZ0FFM1lieUlKWU1Vcm8zZkl0UFFucysxZ2lpTXI5NQpJUXRmclFDQ2JhOWVtcjI4TENmbk1vYy9VQVFwUlg3QVlvVFRneUdiMFBuZGNUODF5ZVgvYTlPa0RLT0I4VENCCjdqQU9CZ05WSFE4QkFmOEVCQU1DQXFRd0V3WURWUjBsQkF3d0NnWUlLd1lCQlFVSEF3RXdEd1lEVlIwVEFRSC8KQkFVd0F3RUIvekFkQmdOVkhRNEVGZ1FVL1AxRHpJUkRzTEhHMU10d3NrZE5nZ0lub1Mwd2daWUdBMVVkRVFTQgpqakNCaTRJTU9EWXhPVGd4TWpObU9EaGpnZ2xzYjJOaGJHaHZjM1NDRFd4dVpDMXZkWFJ6YVdSbExUR0NEV3h1ClpDMXZkWFJ6YVdSbExUS0NEV3h1WkMxdmRYUnphV1JsTFRPQ0JHeHVaREdDQkd4dVpES0NCSFZ1YVhpQ0NuVnUKYVhod1lXTnJaWFNDQjJKMVptTnZibTZIQkg4QUFBR0hFQUFBQUFBQUFBQUFBQUFBQUFBQUFBR0hCS3dUQUJBdwpDZ1lJS29aSXpqMEVBd0lEU0FBd1JRSWhBSU5DNlJWQ3d6SzFYRnFxeVNLY0Y4QzQ5ZFlSOThjemdLNVdkcmNOCkxYYWlBaUJHYmtWeGhaeHdDaDVLQ1o1Z2M1Q2FsQ0RvaGNxVkdiaHNya0hHTFhpdHN3PT0KLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQo= + - LND2_MACAROON=AgEDbG5kAvgBAwoQX0BxfhQTxLTiqaceBnGnfBIBMBoWCgdhZGRyZXNzEgRyZWFkEgV3cml0ZRoTCgRpbmZvEgRyZWFkEgV3cml0ZRoXCghpbnZvaWNlcxIEcmVhZBIFd3JpdGUaIQoIbWFjYXJvb24SCGdlbmVyYXRlEgRyZWFkEgV3cml0ZRoWCgdtZXNzYWdlEgRyZWFkEgV3cml0ZRoXCghvZmZjaGFpbhIEcmVhZBIFd3JpdGUaFgoHb25jaGFpbhIEcmVhZBIFd3JpdGUaFAoFcGVlcnMSBHJlYWQSBXdyaXRlGhgKBnNpZ25lchIIZ2VuZXJhdGUSBHJlYWQAAAYgMAKlr1HehfBpn2R5RPE2IuY9r/18QBeLZxYgRidpos4= + - LND2_PUBKEY=039341ef13e776dc1611502cf510110d9ac5cdc252141f5997adcfd72cef34c3a7 + - LND2_DNS=lnd2 + - LND2_RPCPORT=10010 + - LND2_NAME=lnd2 + - LND2_TYPE=offchain + - SVIX_SECRET=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE2OTE2NzIwMTQsImV4cCI6MjAwNzAzMjAxNCwibmJmIjoxNjkxNjcyMDE0LCJpc3MiOiJzdml4LXNlcnZlciIsInN1YiI6Im9yZ18yM3JiOFlkR3FNVDBxSXpwZ0d3ZFhmSGlyTXUifQ.b9s0aWSisNdUNki4edabBEToLNSwjC9-AiJQr4J3y4E + - SVIX_ENDPOINT=http://svix:8071 + - EXPORTER_PORT=3003 + - OTEL_EXPORTER_OTLP_ENDPOINT=http://otel-agent:4318 + depends_on: + - lnd1 + - bria + - mongodb + notifications: + image: us.gcr.io/galoy-org/galoy-notifications@sha256:a580eceec5260d6c06221b03f5e1e45c7545b6eb380961c9285206011d1b96bd + environment: + - PG_CON=postgres://user:password@notifications-pg:5432/pg + - OTEL_EXPORTER_OTLP_ENDPOINT=http://otel-agent:4318 + ports: + - 6685:6685 + notifications-pg: + image: postgres:14.1 + environment: + - POSTGRES_USER=user + - POSTGRES_PASSWORD=password + - POSTGRES_DB=pg + ports: + - 5433:5432 + healthcheck: + test: + - CMD-SHELL + - pg_isready + interval: 5s + timeout: 30s + retries: 5 + redis: + image: redis:7.0.8 + ports: + - 6379:6379 + environment: + - ALLOW_EMPTY_PASSWORD=yes + - REDIS_DISABLE_COMMANDS=FLUSHDB,FLUSHALL + mongodb: + image: mongo:7.0.2 + ports: + - 27017:27017 + environment: + - MONGO_INITDB_DATABASE=galoy + mongodb-migrate: + image: us.gcr.io/galoy-org/galoy-api-migrate@sha256:a0862f9b08eebab72e17fadf8ad9b7292b984428e982eb8fea21a81edadcefd1 + depends_on: + - mongodb + environment: + - MONGODB_ADDRESS=mongodb + price: + image: us.gcr.io/galoy-org/price:edge + ports: + - 50051:50051 + - 9464:9464 + price-history: + image: us.gcr.io/galoy-org/price-history:edge + ports: + - 50052:50052 + command: ./scripts/run-servers-dev.sh + environment: + - DB_HOST=price-history-pg + - DB_PORT=5432 + - DB_USER=galoy-price-usr + - DB_PWD=galoy-price-pwd + - DB_DB=galoy-price-history + - DB_POOL_MIN=1 + - DB_POOL_MAX=5 + - DB_DEBUG=false + depends_on: + - price-history-pg + - price-history-migrate + price-history-migrate: + image: us.gcr.io/galoy-org/price-history-migrate:edge + ports: [] + environment: + - DB_HOST=price-history-pg + - DB_PORT=5432 + - DB_USER=galoy-price-usr + - DB_PWD=galoy-price-pwd + - DB_DB=galoy-price-history + - DB_POOL_MIN=1 + - DB_POOL_MAX=5 + - DB_DEBUG=false + depends_on: + - price-history-pg + price-history-pg: + image: postgres:14.1 + environment: + - POSTGRES_USER=galoy-price-usr + - POSTGRES_PASSWORD=galoy-price-pwd + - POSTGRES_DB=galoy-price-history + bitcoind: + image: lncm/bitcoind:v25.1 + ports: + - 18443:18443 + volumes: + - ${HOST_PROJECT_PATH:-.}/${GALOY_QUICKSTART_PATH:-vendor/galoy-quickstart}/dev/config/bitcoind/bitcoin.conf:/data/.bitcoin/bitcoin.conf + bitcoind-signer: + image: lncm/bitcoind:v25.1 + ports: [] + volumes: + - ${HOST_PROJECT_PATH:-.}/${GALOY_QUICKSTART_PATH:-vendor/galoy-quickstart}/dev/config/bitcoind/bitcoin.conf:/data/.bitcoin/bitcoin.conf + depends_on: + - bitcoind + entrypoint: + - /bin/sh + - -c + command: + - | + bitcoind -connect=bitcoind:18444 + lnd1: + image: lightninglabs/lnd:v0.17.3-beta + ports: + - 10009:10009 + volumes: + - ${HOST_PROJECT_PATH:-.}/${GALOY_QUICKSTART_PATH:-vendor/galoy-quickstart}/dev/config/lnd/lnd.conf:/root/.lnd/lnd.conf + - ${HOST_PROJECT_PATH:-.}/${GALOY_QUICKSTART_PATH:-vendor/galoy-quickstart}/dev/config/lnd/tls.key:/root/.lnd/tls.key + - ${HOST_PROJECT_PATH:-.}/${GALOY_QUICKSTART_PATH:-vendor/galoy-quickstart}/dev/config/lnd/tls.cert:/root/.lnd/tls.cert + - ${HOST_PROJECT_PATH:-.}/${GALOY_QUICKSTART_PATH:-vendor/galoy-quickstart}/dev/config/lnd/regtest/lnd1.wallet.db:/root/.lnd/wallet.db + - ${HOST_PROJECT_PATH:-.}/${GALOY_QUICKSTART_PATH:-vendor/galoy-quickstart}/dev/config/lnd/regtest/lnd1.macaroons.db:/root/.lnd/macaroons.db + - ${HOST_PROJECT_PATH:-.}/${GALOY_QUICKSTART_PATH:-vendor/galoy-quickstart}/dev/config/lnd/regtest/lnd1.admin.macaroon:/root/.lnd/admin.macaroon + depends_on: + - bitcoind + entrypoint: + - /bin/sh + - -c + command: + - | + mkdir -p /root/.lnd/data/chain/bitcoin/regtest/ + cp /root/.lnd/wallet.db /root/.lnd/data/chain/bitcoin/regtest/wallet.db + cp /root/.lnd/macaroons.db /root/.lnd/data/chain/bitcoin/regtest/macaroons.db + cp /root/.lnd/admin.macaroon /root/.lnd/data/chain/bitcoin/regtest/admin.macaroon + /bin/lnd + lnd-outside-1: + image: lightninglabs/lnd:v0.17.3-beta + ports: + - 10012:10009 + volumes: + - ${HOST_PROJECT_PATH:-.}/${GALOY_QUICKSTART_PATH:-vendor/galoy-quickstart}/dev/config/lnd/lnd.conf:/root/.lnd/lnd.conf + - ${HOST_PROJECT_PATH:-.}/${GALOY_QUICKSTART_PATH:-vendor/galoy-quickstart}/dev/config/lnd/tls.key:/root/.lnd/tls.key + - ${HOST_PROJECT_PATH:-.}/${GALOY_QUICKSTART_PATH:-vendor/galoy-quickstart}/dev/config/lnd/tls.cert:/root/.lnd/tls.cert + - ${HOST_PROJECT_PATH:-.}/${GALOY_QUICKSTART_PATH:-vendor/galoy-quickstart}/dev/config/lnd/regtest/lnd-outside-1.wallet.db:/root/.lnd/wallet.db + - ${HOST_PROJECT_PATH:-.}/${GALOY_QUICKSTART_PATH:-vendor/galoy-quickstart}/dev/config/lnd/regtest/lnd-outside-1.macaroons.db:/root/.lnd/macaroons.db + - ${HOST_PROJECT_PATH:-.}/${GALOY_QUICKSTART_PATH:-vendor/galoy-quickstart}/dev/config/lnd/regtest/lnd-outside-1.admin.macaroon:/root/.lnd/admin.macaroon + entrypoint: + - /bin/sh + - -c + command: + - | + mkdir -p /root/.lnd/data/chain/bitcoin/regtest/ + cp /root/.lnd/wallet.db /root/.lnd/data/chain/bitcoin/regtest/wallet.db + cp /root/.lnd/macaroons.db /root/.lnd/data/chain/bitcoin/regtest/macaroons.db + cp /root/.lnd/admin.macaroon /root/.lnd/data/chain/bitcoin/regtest/admin.macaroon + /bin/lnd + depends_on: + - bitcoind + bria: + image: us.gcr.io/galoy-org/bria:latest + ports: + - 2743:2743 + - 2742:2742 + environment: + - PG_CON=postgres://user:password@bria-pg:5432/pg + - BITCOIND_SIGNER_ENDPOINT=https://bitcoind-signer:18443 + command: + - bria + - daemon + - --config + - /bria.yml + - dev + - -x + - tpubDDDDGYiFda8HfJRc2AHFJDxVzzEtBPrKsbh35EaW2UGd5qfzrF2G87ewAgeeRyHEz4iB3kvhAYW1sH6dpLepTkFUzAktumBN8AXeXWE9nd1 + - -d + - m/84h/0h/0h + volumes: + - ${HOST_PROJECT_PATH:-.}/${GALOY_QUICKSTART_PATH:-vendor/galoy-quickstart}/dev/config/bria.yml:/bria.yml + depends_on: + bitcoind-signer: + condition: service_started + otel-agent: + condition: service_started + fulcrum: + condition: service_started + bria-pg: + condition: service_healthy + bria-pg: + image: postgres:14.1 + environment: + - POSTGRES_USER=user + - POSTGRES_PASSWORD=password + - POSTGRES_DB=pg + healthcheck: + test: + - CMD-SHELL + - pg_isready + interval: 5s + timeout: 30s + retries: 5 + fulcrum: + image: cculianu/fulcrum:latest + ports: + - 50001:50001 + depends_on: + - bitcoind + volumes: + - ${HOST_PROJECT_PATH:-.}/${GALOY_QUICKSTART_PATH:-vendor/galoy-quickstart}/dev/config/fulcrum/fulcrum.conf:/fulcrum.conf + - ${HOST_PROJECT_PATH:-.}/${GALOY_QUICKSTART_PATH:-vendor/galoy-quickstart}/dev/config/fulcrum/tls.key:/tls.key + - ${HOST_PROJECT_PATH:-.}/${GALOY_QUICKSTART_PATH:-vendor/galoy-quickstart}/dev/config/fulcrum/tls.cert:/tls.cert + environment: + - DATA_DIR=/db + - SSL_CERTFILE=/tls.cert + - SSL_KEYFILE=/tls.key + command: + - Fulcrum + - /fulcrum.conf + stablesats: + image: us.gcr.io/galoy-org/stablesats-rs:latest + ports: + - 3325:3325 + command: + - stablesats + - run + working_dir: /repo/config + depends_on: + - otel-agent + restart: on-failure:10 + volumes: + - ${HOST_PROJECT_PATH:-.}/${GALOY_QUICKSTART_PATH:-vendor/galoy-quickstart}/dev/:/repo + otel-agent: + ports: + - 4318:4318 + - 4317:4317 + image: otel/opentelemetry-collector-contrib:0.84.0 + command: + - --config=/etc/otel-agent-config.yaml + environment: + - HONEYCOMB_DATASET=${HONEYCOMB_DATASET} + - HONEYCOMB_API_KEY=${HONEYCOMB_API_KEY} + volumes: + - ${HOST_PROJECT_PATH:-.}/${GALOY_QUICKSTART_PATH:-vendor/galoy-quickstart}/dev/config/otel-agent-config.yaml:/etc/otel-agent-config.yaml + svix: + image: svix/svix-server:v1.11 + platform: linux/amd64 + environment: + WAIT_FOR: "true" + SVIX_DB_DSN: postgresql://postgres:postgres@svix-pg/postgres + SVIX_JWT_SECRET: 8KjzRXrKkd9YFcNyqLSIY8JwiaCeRc6WK4UkMnSW + SVIX_WHITELIST_SUBNETS: '[0.0.0.0/0]' + SVIX_QUEUE_TYPE: memory + depends_on: + - svix-pg + ports: + - 8071:8071 + extra_hosts: + - dockerhost-alias:host-gateway + svix-pg: + image: postgres:14.1 + environment: + POSTGRES_PASSWORD: postgres diff --git a/dev/vendor/galoy-quickstart/graphql/gql/account-default-wallet.gql b/dev/vendor/galoy-quickstart/graphql/gql/account-default-wallet.gql new file mode 100644 index 0000000000..bd00e3b846 --- /dev/null +++ b/dev/vendor/galoy-quickstart/graphql/gql/account-default-wallet.gql @@ -0,0 +1,6 @@ +query accountDefaultWallet($username: Username!, $walletCurrency: WalletCurrency) { + accountDefaultWallet(username: $username, walletCurrency: $walletCurrency) { + id + currency + } +} diff --git a/dev/vendor/galoy-quickstart/graphql/gql/account-delete.gql b/dev/vendor/galoy-quickstart/graphql/gql/account-delete.gql new file mode 100644 index 0000000000..b0b8bac643 --- /dev/null +++ b/dev/vendor/galoy-quickstart/graphql/gql/account-delete.gql @@ -0,0 +1,9 @@ +mutation accountDelete { + accountDelete { + errors { + message + code + } + success + } +} diff --git a/dev/vendor/galoy-quickstart/graphql/gql/account-details.gql b/dev/vendor/galoy-quickstart/graphql/gql/account-details.gql new file mode 100644 index 0000000000..adc71fd240 --- /dev/null +++ b/dev/vendor/galoy-quickstart/graphql/gql/account-details.gql @@ -0,0 +1,8 @@ +query me { + me { + defaultAccount { + id + level + } + } +} diff --git a/dev/vendor/galoy-quickstart/graphql/gql/account-disable-notification-category.gql b/dev/vendor/galoy-quickstart/graphql/gql/account-disable-notification-category.gql new file mode 100644 index 0000000000..771a6c7e9f --- /dev/null +++ b/dev/vendor/galoy-quickstart/graphql/gql/account-disable-notification-category.gql @@ -0,0 +1,15 @@ +mutation accountDisableNotificationCategory($input: AccountDisableNotificationCategoryInput!) { + accountDisableNotificationCategory(input: $input) { + errors { + message + } + account { + notificationSettings { + push { + enabled + disabledCategories + } + } + } + } +} diff --git a/dev/vendor/galoy-quickstart/graphql/gql/account-disable-notification-channel.gql b/dev/vendor/galoy-quickstart/graphql/gql/account-disable-notification-channel.gql new file mode 100644 index 0000000000..34e9a5795b --- /dev/null +++ b/dev/vendor/galoy-quickstart/graphql/gql/account-disable-notification-channel.gql @@ -0,0 +1,15 @@ +mutation accountDisableNotificationChannel($input: AccountDisableNotificationChannelInput!) { + accountDisableNotificationChannel(input: $input) { + errors { + message + } + account { + notificationSettings { + push { + enabled + disabledCategories + } + } + } + } +} diff --git a/dev/vendor/galoy-quickstart/graphql/gql/account-enable-notification-category.gql b/dev/vendor/galoy-quickstart/graphql/gql/account-enable-notification-category.gql new file mode 100644 index 0000000000..5b5b752fe9 --- /dev/null +++ b/dev/vendor/galoy-quickstart/graphql/gql/account-enable-notification-category.gql @@ -0,0 +1,15 @@ +mutation accountEnableNotificationCategory($input: AccountEnableNotificationCategoryInput!) { + accountEnableNotificationCategory(input: $input) { + errors { + message + } + account { + notificationSettings { + push { + enabled + disabledCategories + } + } + } + } +} diff --git a/dev/vendor/galoy-quickstart/graphql/gql/account-enable-notification-channel.gql b/dev/vendor/galoy-quickstart/graphql/gql/account-enable-notification-channel.gql new file mode 100644 index 0000000000..a3593270dc --- /dev/null +++ b/dev/vendor/galoy-quickstart/graphql/gql/account-enable-notification-channel.gql @@ -0,0 +1,15 @@ +mutation accountEnableNotificationChannel($input: AccountEnableNotificationChannelInput!) { + accountEnableNotificationChannel(input: $input) { + errors { + message + } + account { + notificationSettings { + push { + enabled + disabledCategories + } + } + } + } +} diff --git a/dev/vendor/galoy-quickstart/graphql/gql/account-limits.gql b/dev/vendor/galoy-quickstart/graphql/gql/account-limits.gql new file mode 100644 index 0000000000..7250714207 --- /dev/null +++ b/dev/vendor/galoy-quickstart/graphql/gql/account-limits.gql @@ -0,0 +1,23 @@ +query accountLimits { + me { + defaultAccount { + limits { + convert { + interval + remainingLimit + totalLimit + } + internalSend { + interval + remainingLimit + totalLimit + } + withdrawal { + interval + remainingLimit + totalLimit + } + } + } + } +} diff --git a/dev/vendor/galoy-quickstart/graphql/gql/account-update-default-wallet-id.gql b/dev/vendor/galoy-quickstart/graphql/gql/account-update-default-wallet-id.gql new file mode 100644 index 0000000000..b175a77260 --- /dev/null +++ b/dev/vendor/galoy-quickstart/graphql/gql/account-update-default-wallet-id.gql @@ -0,0 +1,7 @@ +mutation accountUpdateDefaultWalletId($input: AccountUpdateDefaultWalletIdInput!) { + accountUpdateDefaultWalletId(input: $input) { + account { + defaultWalletId + } + } +} diff --git a/dev/vendor/galoy-quickstart/graphql/gql/api-key-create.gql b/dev/vendor/galoy-quickstart/graphql/gql/api-key-create.gql new file mode 100644 index 0000000000..aaeb1e7cd0 --- /dev/null +++ b/dev/vendor/galoy-quickstart/graphql/gql/api-key-create.gql @@ -0,0 +1,12 @@ +mutation apiKeyCreate($input: ApiKeyCreateInput!) { + apiKeyCreate(input: $input) { + apiKey { + id + name + createdAt + expiresAt + readOnly + } + apiKeySecret + } +} diff --git a/dev/vendor/galoy-quickstart/graphql/gql/api-keys.gql b/dev/vendor/galoy-quickstart/graphql/gql/api-keys.gql new file mode 100644 index 0000000000..2537653784 --- /dev/null +++ b/dev/vendor/galoy-quickstart/graphql/gql/api-keys.gql @@ -0,0 +1,15 @@ +query apiKeys { + me { + defaultAccount { + id + } + apiKeys { + id + name + revoked + createdAt + expiresAt + readOnly + } + } +} diff --git a/dev/vendor/galoy-quickstart/graphql/gql/business-map-markers.gql b/dev/vendor/galoy-quickstart/graphql/gql/business-map-markers.gql new file mode 100644 index 0000000000..0cab0a0e45 --- /dev/null +++ b/dev/vendor/galoy-quickstart/graphql/gql/business-map-markers.gql @@ -0,0 +1,12 @@ + query businessMapMarkers { + businessMapMarkers { + username + mapInfo { + title + coordinates { + longitude + latitude + } + } + } +} diff --git a/dev/vendor/galoy-quickstart/graphql/gql/callback-endpoint-add.gql b/dev/vendor/galoy-quickstart/graphql/gql/callback-endpoint-add.gql new file mode 100644 index 0000000000..0b5f7ee9b0 --- /dev/null +++ b/dev/vendor/galoy-quickstart/graphql/gql/callback-endpoint-add.gql @@ -0,0 +1,8 @@ +mutation callbackEndpointAdd($input: CallbackEndpointAddInput!) { + callbackEndpointAdd(input: $input) { + errors { + message + } + id + } +} diff --git a/dev/vendor/galoy-quickstart/graphql/gql/callback-endpoint-delete.gql b/dev/vendor/galoy-quickstart/graphql/gql/callback-endpoint-delete.gql new file mode 100644 index 0000000000..82a9812398 --- /dev/null +++ b/dev/vendor/galoy-quickstart/graphql/gql/callback-endpoint-delete.gql @@ -0,0 +1,8 @@ +mutation callbackEndpointDelete($input: CallbackEndpointDeleteInput!) { + callbackEndpointDelete(input: $input) { + errors { + message + } + success + } +} diff --git a/dev/vendor/galoy-quickstart/graphql/gql/callback-endpoints-list.gql b/dev/vendor/galoy-quickstart/graphql/gql/callback-endpoints-list.gql new file mode 100644 index 0000000000..66aca31353 --- /dev/null +++ b/dev/vendor/galoy-quickstart/graphql/gql/callback-endpoints-list.gql @@ -0,0 +1,10 @@ +query callbackEndpointsList { + me { + defaultAccount { + callbackEndpoints { + id + url + } + } + } +} diff --git a/dev/vendor/galoy-quickstart/graphql/gql/contacts.gql b/dev/vendor/galoy-quickstart/graphql/gql/contacts.gql new file mode 100644 index 0000000000..285ab41a4a --- /dev/null +++ b/dev/vendor/galoy-quickstart/graphql/gql/contacts.gql @@ -0,0 +1,7 @@ +query me { + me { + contacts { + username + } + } +} diff --git a/dev/vendor/galoy-quickstart/graphql/gql/default-account.gql b/dev/vendor/galoy-quickstart/graphql/gql/default-account.gql new file mode 100644 index 0000000000..d32015b3b8 --- /dev/null +++ b/dev/vendor/galoy-quickstart/graphql/gql/default-account.gql @@ -0,0 +1,7 @@ +query defaultAccount { + me { + defaultAccount { + id + } + } +} diff --git a/dev/vendor/galoy-quickstart/graphql/gql/globals.gql b/dev/vendor/galoy-quickstart/graphql/gql/globals.gql new file mode 100644 index 0000000000..150920389a --- /dev/null +++ b/dev/vendor/galoy-quickstart/graphql/gql/globals.gql @@ -0,0 +1,6 @@ +query Globals { + globals { + network + nodesIds + } +} diff --git a/dev/vendor/galoy-quickstart/graphql/gql/identity.gql b/dev/vendor/galoy-quickstart/graphql/gql/identity.gql new file mode 100644 index 0000000000..04643e0c9f --- /dev/null +++ b/dev/vendor/galoy-quickstart/graphql/gql/identity.gql @@ -0,0 +1,11 @@ +query identity { + me { + id + phone + email { + address + verified + } + totpEnabled + } +} diff --git a/dev/vendor/galoy-quickstart/graphql/gql/intraledger-payment-send.gql b/dev/vendor/galoy-quickstart/graphql/gql/intraledger-payment-send.gql new file mode 100644 index 0000000000..c0e6486715 --- /dev/null +++ b/dev/vendor/galoy-quickstart/graphql/gql/intraledger-payment-send.gql @@ -0,0 +1,9 @@ +mutation intraLedgerPaymentSend($input: IntraLedgerPaymentSendInput!) { + intraLedgerPaymentSend(input: $input) { + status + errors { + message + path + } + } +} diff --git a/dev/vendor/galoy-quickstart/graphql/gql/intraledger-usd-payment-send.gql b/dev/vendor/galoy-quickstart/graphql/gql/intraledger-usd-payment-send.gql new file mode 100644 index 0000000000..5e72e9d70a --- /dev/null +++ b/dev/vendor/galoy-quickstart/graphql/gql/intraledger-usd-payment-send.gql @@ -0,0 +1,9 @@ +mutation intraLedgerUsdPaymentSend($input: IntraLedgerUsdPaymentSendInput!) { + intraLedgerUsdPaymentSend(input: $input) { + status + errors { + message + path + } + } +} diff --git a/dev/vendor/galoy-quickstart/graphql/gql/invoice-for-wallet-by-payment-hash.gql b/dev/vendor/galoy-quickstart/graphql/gql/invoice-for-wallet-by-payment-hash.gql new file mode 100644 index 0000000000..147bb65714 --- /dev/null +++ b/dev/vendor/galoy-quickstart/graphql/gql/invoice-for-wallet-by-payment-hash.gql @@ -0,0 +1,17 @@ +query me($walletId: WalletId!, $paymentHash: PaymentHash!) { + me { + defaultAccount { + id + walletById(walletId: $walletId) { + id + invoiceByPaymentHash(paymentHash: $paymentHash) { + paymentHash + paymentStatus + ... on LnInvoice { + satoshis + } + } + } + } + } +} diff --git a/dev/vendor/galoy-quickstart/graphql/gql/invoices-by-wallet.gql b/dev/vendor/galoy-quickstart/graphql/gql/invoices-by-wallet.gql new file mode 100644 index 0000000000..7deb404b5d --- /dev/null +++ b/dev/vendor/galoy-quickstart/graphql/gql/invoices-by-wallet.gql @@ -0,0 +1,27 @@ +query invoicesForWallet($walletId: WalletId!, $first: Int, $after: String) { + me { + defaultAccount { + id + displayCurrency + walletById(walletId: $walletId) { + id + invoices(first: $first, after: $after) { + ...InvoiceList + } + } + } + } +} + +fragment InvoiceList on InvoiceConnection { + pageInfo { + hasNextPage + } + edges { + cursor + node { + __typename + paymentHash + } + } +} diff --git a/dev/vendor/galoy-quickstart/graphql/gql/invoices.gql b/dev/vendor/galoy-quickstart/graphql/gql/invoices.gql new file mode 100644 index 0000000000..9086c64ce2 --- /dev/null +++ b/dev/vendor/galoy-quickstart/graphql/gql/invoices.gql @@ -0,0 +1,25 @@ +query invoices($walletIds: [WalletId], $first: Int, $after: String) { + me { + defaultAccount { + defaultWallet { + id + } + invoices(walletIds: $walletIds, first: $first, after: $after) { + ...InvoiceList + } + } + } +} + +fragment InvoiceList on InvoiceConnection { + pageInfo { + hasNextPage + } + edges { + cursor + node { + __typename + paymentHash + } + } +} diff --git a/dev/vendor/galoy-quickstart/graphql/gql/ln-invoice-create-on-behalf-of-recipient.gql b/dev/vendor/galoy-quickstart/graphql/gql/ln-invoice-create-on-behalf-of-recipient.gql new file mode 100644 index 0000000000..85978f60e3 --- /dev/null +++ b/dev/vendor/galoy-quickstart/graphql/gql/ln-invoice-create-on-behalf-of-recipient.gql @@ -0,0 +1,13 @@ +mutation lnInvoiceCreateOnBehalfOfRecipient( + $input: LnInvoiceCreateOnBehalfOfRecipientInput! +) { + lnInvoiceCreateOnBehalfOfRecipient(input: $input) { + invoice { + paymentRequest + paymentHash + } + errors { + message + } + } +} diff --git a/dev/vendor/galoy-quickstart/graphql/gql/ln-invoice-create.gql b/dev/vendor/galoy-quickstart/graphql/gql/ln-invoice-create.gql new file mode 100644 index 0000000000..3e3a27d0a0 --- /dev/null +++ b/dev/vendor/galoy-quickstart/graphql/gql/ln-invoice-create.gql @@ -0,0 +1,11 @@ +mutation lnInvoiceCreateInput($input: LnInvoiceCreateInput!) { + lnInvoiceCreate(input: $input) { + invoice { + paymentRequest + paymentHash + } + errors { + message + } + } +} diff --git a/dev/vendor/galoy-quickstart/graphql/gql/ln-invoice-fee-probe.gql b/dev/vendor/galoy-quickstart/graphql/gql/ln-invoice-fee-probe.gql new file mode 100644 index 0000000000..3064f585df --- /dev/null +++ b/dev/vendor/galoy-quickstart/graphql/gql/ln-invoice-fee-probe.gql @@ -0,0 +1,8 @@ +mutation LnInvoiceFeeProbe($input: LnInvoiceFeeProbeInput!) { + lnInvoiceFeeProbe(input: $input) { + errors { + message + } + amount + } +} diff --git a/dev/vendor/galoy-quickstart/graphql/gql/ln-invoice-payment-send.gql b/dev/vendor/galoy-quickstart/graphql/gql/ln-invoice-payment-send.gql new file mode 100644 index 0000000000..d13fdc3b7e --- /dev/null +++ b/dev/vendor/galoy-quickstart/graphql/gql/ln-invoice-payment-send.gql @@ -0,0 +1,24 @@ +mutation lnInvoicePaymentSend($input: LnInvoicePaymentInput!) { + lnInvoicePaymentSend(input: $input) { + errors { + message + } + status + transaction { + initiationVia { + ... on InitiationViaLn { + paymentHash + paymentRequest + } + } + settlementVia { + ... on SettlementViaIntraLedger { + preImage + } + ... on SettlementViaLn { + preImage + } + } + } + } +} diff --git a/dev/vendor/galoy-quickstart/graphql/gql/ln-invoice-payment-status-sub.gql b/dev/vendor/galoy-quickstart/graphql/gql/ln-invoice-payment-status-sub.gql new file mode 100644 index 0000000000..6e26bd0732 --- /dev/null +++ b/dev/vendor/galoy-quickstart/graphql/gql/ln-invoice-payment-status-sub.gql @@ -0,0 +1,8 @@ +subscription lnInvoicePaymentStatusSubscription($input: LnInvoicePaymentStatusInput!) { + lnInvoicePaymentStatus(input: $input) { + errors { + message + } + status + } +} diff --git a/dev/vendor/galoy-quickstart/graphql/gql/ln-invoice-payment-status.gql b/dev/vendor/galoy-quickstart/graphql/gql/ln-invoice-payment-status.gql new file mode 100644 index 0000000000..af9e729f35 --- /dev/null +++ b/dev/vendor/galoy-quickstart/graphql/gql/ln-invoice-payment-status.gql @@ -0,0 +1,5 @@ +query LnInvoicePaymentStatusQuery($input: LnInvoicePaymentStatusInput!) { + lnInvoicePaymentStatus(input: $input) { + status + } +} diff --git a/dev/vendor/galoy-quickstart/graphql/gql/ln-no-amount-invoice-create-on-behalf-of-recipient.gql b/dev/vendor/galoy-quickstart/graphql/gql/ln-no-amount-invoice-create-on-behalf-of-recipient.gql new file mode 100644 index 0000000000..5521fc6d92 --- /dev/null +++ b/dev/vendor/galoy-quickstart/graphql/gql/ln-no-amount-invoice-create-on-behalf-of-recipient.gql @@ -0,0 +1,13 @@ +mutation lnNoAmountInvoiceCreateOnBehalfOfRecipient( + $input: LnNoAmountInvoiceCreateOnBehalfOfRecipientInput! +) { + lnNoAmountInvoiceCreateOnBehalfOfRecipient(input: $input) { + invoice { + paymentRequest + paymentHash + } + errors { + message + } + } +} diff --git a/dev/vendor/galoy-quickstart/graphql/gql/ln-no-amount-invoice-create.gql b/dev/vendor/galoy-quickstart/graphql/gql/ln-no-amount-invoice-create.gql new file mode 100644 index 0000000000..ac03667394 --- /dev/null +++ b/dev/vendor/galoy-quickstart/graphql/gql/ln-no-amount-invoice-create.gql @@ -0,0 +1,11 @@ +mutation lnNoAmountInvoiceCreate($input: LnNoAmountInvoiceCreateInput!) { + lnNoAmountInvoiceCreate(input: $input) { + invoice { + paymentRequest + paymentHash + } + errors { + message + } + } +} diff --git a/dev/vendor/galoy-quickstart/graphql/gql/ln-no-amount-invoice-fee-probe.gql b/dev/vendor/galoy-quickstart/graphql/gql/ln-no-amount-invoice-fee-probe.gql new file mode 100644 index 0000000000..cbd12026ac --- /dev/null +++ b/dev/vendor/galoy-quickstart/graphql/gql/ln-no-amount-invoice-fee-probe.gql @@ -0,0 +1,8 @@ +mutation lnNoAmountInvoiceFeeProbe($input: LnNoAmountInvoiceFeeProbeInput!) { + lnNoAmountInvoiceFeeProbe(input: $input) { + errors { + message + } + amount + } +} diff --git a/dev/vendor/galoy-quickstart/graphql/gql/ln-no-amount-invoice-payment-send.gql b/dev/vendor/galoy-quickstart/graphql/gql/ln-no-amount-invoice-payment-send.gql new file mode 100644 index 0000000000..7131b589b4 --- /dev/null +++ b/dev/vendor/galoy-quickstart/graphql/gql/ln-no-amount-invoice-payment-send.gql @@ -0,0 +1,8 @@ +mutation lnNoAmountInvoicePaymentSend($input: LnNoAmountInvoicePaymentInput!) { + lnNoAmountInvoicePaymentSend(input: $input) { + errors { + message + } + status + } +} diff --git a/dev/vendor/galoy-quickstart/graphql/gql/ln-no-amount-usd-invoice-fee-probe.gql b/dev/vendor/galoy-quickstart/graphql/gql/ln-no-amount-usd-invoice-fee-probe.gql new file mode 100644 index 0000000000..00bde20e62 --- /dev/null +++ b/dev/vendor/galoy-quickstart/graphql/gql/ln-no-amount-usd-invoice-fee-probe.gql @@ -0,0 +1,8 @@ +mutation lnNoAmountUsdInvoiceFeeProbe($input: LnNoAmountUsdInvoiceFeeProbeInput!) { + lnNoAmountUsdInvoiceFeeProbe(input: $input) { + errors { + message + } + amount + } +} diff --git a/dev/vendor/galoy-quickstart/graphql/gql/ln-no-amount-usd-invoice-payment-send.gql b/dev/vendor/galoy-quickstart/graphql/gql/ln-no-amount-usd-invoice-payment-send.gql new file mode 100644 index 0000000000..a34ccee880 --- /dev/null +++ b/dev/vendor/galoy-quickstart/graphql/gql/ln-no-amount-usd-invoice-payment-send.gql @@ -0,0 +1,8 @@ +mutation lnNoAmountUsdInvoicePaymentSend($input: LnNoAmountUsdInvoicePaymentInput!) { + lnNoAmountUsdInvoicePaymentSend(input: $input) { + errors { + message + } + status + } +} diff --git a/dev/vendor/galoy-quickstart/graphql/gql/ln-usd-invoice-btc-denominated-create-on-behalf-of-recipient.gql b/dev/vendor/galoy-quickstart/graphql/gql/ln-usd-invoice-btc-denominated-create-on-behalf-of-recipient.gql new file mode 100644 index 0000000000..d2df19ad48 --- /dev/null +++ b/dev/vendor/galoy-quickstart/graphql/gql/ln-usd-invoice-btc-denominated-create-on-behalf-of-recipient.gql @@ -0,0 +1,13 @@ +mutation lnUsdInvoiceBtcDenominatedCreateOnBehalfOfRecipient( + $input: LnUsdInvoiceBtcDenominatedCreateOnBehalfOfRecipientInput! +) { + lnUsdInvoiceBtcDenominatedCreateOnBehalfOfRecipient(input: $input) { + invoice { + paymentRequest + paymentHash + } + errors { + message + } + } +} diff --git a/dev/vendor/galoy-quickstart/graphql/gql/ln-usd-invoice-create-on-behalf-of-recipient.gql b/dev/vendor/galoy-quickstart/graphql/gql/ln-usd-invoice-create-on-behalf-of-recipient.gql new file mode 100644 index 0000000000..80c07e35b1 --- /dev/null +++ b/dev/vendor/galoy-quickstart/graphql/gql/ln-usd-invoice-create-on-behalf-of-recipient.gql @@ -0,0 +1,13 @@ +mutation lnUsdInvoiceCreateOnBehalfOfRecipient( + $input: LnUsdInvoiceCreateOnBehalfOfRecipientInput! +) { + lnUsdInvoiceCreateOnBehalfOfRecipient(input: $input) { + invoice { + paymentRequest + paymentHash + } + errors { + message + } + } +} diff --git a/dev/vendor/galoy-quickstart/graphql/gql/ln-usd-invoice-create.gql b/dev/vendor/galoy-quickstart/graphql/gql/ln-usd-invoice-create.gql new file mode 100644 index 0000000000..270e9ef009 --- /dev/null +++ b/dev/vendor/galoy-quickstart/graphql/gql/ln-usd-invoice-create.gql @@ -0,0 +1,11 @@ +mutation lnUsdInvoiceCreate($input: LnUsdInvoiceCreateInput!) { + lnUsdInvoiceCreate(input: $input) { + invoice { + paymentRequest + paymentHash + } + errors { + message + } + } +} diff --git a/dev/vendor/galoy-quickstart/graphql/gql/ln-usd-invoice-fee-probe.gql b/dev/vendor/galoy-quickstart/graphql/gql/ln-usd-invoice-fee-probe.gql new file mode 100644 index 0000000000..1508e144aa --- /dev/null +++ b/dev/vendor/galoy-quickstart/graphql/gql/ln-usd-invoice-fee-probe.gql @@ -0,0 +1,8 @@ +mutation lnUsdInvoiceFeeProbe($input: LnUsdInvoiceFeeProbeInput!) { + lnUsdInvoiceFeeProbe(input: $input) { + errors { + message + } + amount + } +} diff --git a/dev/vendor/galoy-quickstart/graphql/gql/lnurl-payment-send.gql b/dev/vendor/galoy-quickstart/graphql/gql/lnurl-payment-send.gql new file mode 100644 index 0000000000..f92ecbf898 --- /dev/null +++ b/dev/vendor/galoy-quickstart/graphql/gql/lnurl-payment-send.gql @@ -0,0 +1,12 @@ +mutation lnurlPaymentSend($input: LnurlPaymentSendInput!) { + lnurlPaymentSend(input: $input) { + errors { + message + path + } + status + transaction { + id + } + } +} diff --git a/dev/vendor/galoy-quickstart/graphql/gql/logout.gql b/dev/vendor/galoy-quickstart/graphql/gql/logout.gql new file mode 100644 index 0000000000..e94bcc3d86 --- /dev/null +++ b/dev/vendor/galoy-quickstart/graphql/gql/logout.gql @@ -0,0 +1,6 @@ +mutation userLogout { + userLogout { + success + __typename + } +} diff --git a/dev/vendor/galoy-quickstart/graphql/gql/my-updates-sub.gql b/dev/vendor/galoy-quickstart/graphql/gql/my-updates-sub.gql new file mode 100644 index 0000000000..94297df873 --- /dev/null +++ b/dev/vendor/galoy-quickstart/graphql/gql/my-updates-sub.gql @@ -0,0 +1,57 @@ +subscription myUpdates { + myUpdates { + errors { + message + } + me { + id + defaultAccount { + id + wallets { + id + walletCurrency + balance + } + } + } + update { + type: __typename + ... on Price { + base + offset + currencyUnit + formattedAmount + } + ... on RealtimePrice { + id + timestamp + denominatorCurrency + btcSatPrice { + base + offset + currencyUnit + } + usdCentPrice { + base + offset + currencyUnit + } + } + ... on LnUpdate { + paymentHash + status + } + ... on OnChainUpdate { + txNotificationType + txHash + amount + usdPerSat + } + ... on IntraLedgerUpdate { + txNotificationType + amount + usdPerSat + } + } + } +} diff --git a/dev/vendor/galoy-quickstart/graphql/gql/on-chain-address-create.gql b/dev/vendor/galoy-quickstart/graphql/gql/on-chain-address-create.gql new file mode 100644 index 0000000000..b8992d2763 --- /dev/null +++ b/dev/vendor/galoy-quickstart/graphql/gql/on-chain-address-create.gql @@ -0,0 +1,8 @@ +mutation onChainAddressCreate($input: OnChainAddressCreateInput!) { + onChainAddressCreate(input: $input) { + address + errors { + message + } + } +} diff --git a/dev/vendor/galoy-quickstart/graphql/gql/on-chain-address-current.gql b/dev/vendor/galoy-quickstart/graphql/gql/on-chain-address-current.gql new file mode 100644 index 0000000000..f6d82f37bb --- /dev/null +++ b/dev/vendor/galoy-quickstart/graphql/gql/on-chain-address-current.gql @@ -0,0 +1,8 @@ +mutation onChainAddressCurrent($input: OnChainAddressCurrentInput!) { + onChainAddressCurrent(input: $input) { + address + errors { + message + } + } +} diff --git a/dev/vendor/galoy-quickstart/graphql/gql/on-chain-payment-send-all.gql b/dev/vendor/galoy-quickstart/graphql/gql/on-chain-payment-send-all.gql new file mode 100644 index 0000000000..197e9732a0 --- /dev/null +++ b/dev/vendor/galoy-quickstart/graphql/gql/on-chain-payment-send-all.gql @@ -0,0 +1,8 @@ +mutation onChainPaymentSendAll($input: OnChainPaymentSendAllInput!) { + onChainPaymentSendAll(input: $input) { + errors { + message + } + status + } +} diff --git a/dev/vendor/galoy-quickstart/graphql/gql/on-chain-payment-send.gql b/dev/vendor/galoy-quickstart/graphql/gql/on-chain-payment-send.gql new file mode 100644 index 0000000000..097cb6fa4b --- /dev/null +++ b/dev/vendor/galoy-quickstart/graphql/gql/on-chain-payment-send.gql @@ -0,0 +1,8 @@ +mutation onChainPaymentSend($input: OnChainPaymentSendInput!) { + onChainPaymentSend(input: $input) { + errors { + message + } + status + } +} diff --git a/dev/vendor/galoy-quickstart/graphql/gql/on-chain-tx-fee.gql b/dev/vendor/galoy-quickstart/graphql/gql/on-chain-tx-fee.gql new file mode 100644 index 0000000000..df5780cef5 --- /dev/null +++ b/dev/vendor/galoy-quickstart/graphql/gql/on-chain-tx-fee.gql @@ -0,0 +1,5 @@ +query onChainTxFee($walletId: WalletId!, $address: OnChainAddress!, $amount: SatAmount!) { + onChainTxFee(walletId: $walletId, address: $address, amount: $amount) { + amount + } +} diff --git a/dev/vendor/galoy-quickstart/graphql/gql/on-chain-usd-payment-send-as-btc-denominated.gql b/dev/vendor/galoy-quickstart/graphql/gql/on-chain-usd-payment-send-as-btc-denominated.gql new file mode 100644 index 0000000000..e25c6ec282 --- /dev/null +++ b/dev/vendor/galoy-quickstart/graphql/gql/on-chain-usd-payment-send-as-btc-denominated.gql @@ -0,0 +1,10 @@ +mutation onChainUsdPaymentSendAsBtcDenominated( + $input: OnChainUsdPaymentSendAsBtcDenominatedInput! +) { + onChainUsdPaymentSendAsBtcDenominated(input: $input) { + errors { + message + } + status + } +} diff --git a/dev/vendor/galoy-quickstart/graphql/gql/on-chain-usd-payment-send.gql b/dev/vendor/galoy-quickstart/graphql/gql/on-chain-usd-payment-send.gql new file mode 100644 index 0000000000..47003b24bf --- /dev/null +++ b/dev/vendor/galoy-quickstart/graphql/gql/on-chain-usd-payment-send.gql @@ -0,0 +1,8 @@ +mutation onChainUsdPaymentSend($input: OnChainUsdPaymentSendInput!) { + onChainUsdPaymentSend(input: $input) { + errors { + message + } + status + } +} diff --git a/dev/vendor/galoy-quickstart/graphql/gql/on-chain-usd-tx-fee-as-btc-denominated.gql b/dev/vendor/galoy-quickstart/graphql/gql/on-chain-usd-tx-fee-as-btc-denominated.gql new file mode 100644 index 0000000000..0997c148ea --- /dev/null +++ b/dev/vendor/galoy-quickstart/graphql/gql/on-chain-usd-tx-fee-as-btc-denominated.gql @@ -0,0 +1,13 @@ +query onChainUsdTxFeeAsBtcDenominated( + $walletId: WalletId! + $address: OnChainAddress! + $amount: SatAmount! +) { + onChainUsdTxFeeAsBtcDenominated( + walletId: $walletId + address: $address + amount: $amount + ) { + amount + } +} diff --git a/dev/vendor/galoy-quickstart/graphql/gql/on-chain-usd-tx-fee.gql b/dev/vendor/galoy-quickstart/graphql/gql/on-chain-usd-tx-fee.gql new file mode 100644 index 0000000000..0a7444a388 --- /dev/null +++ b/dev/vendor/galoy-quickstart/graphql/gql/on-chain-usd-tx-fee.gql @@ -0,0 +1,9 @@ +query onChainUsdTxFee( + $walletId: WalletId! + $address: OnChainAddress! + $amount: CentAmount! +) { + onChainUsdTxFee(walletId: $walletId, address: $address, amount: $amount) { + amount + } +} diff --git a/dev/vendor/galoy-quickstart/graphql/gql/pending-incoming-transactions-by-address.gql b/dev/vendor/galoy-quickstart/graphql/gql/pending-incoming-transactions-by-address.gql new file mode 100644 index 0000000000..942f9503a4 --- /dev/null +++ b/dev/vendor/galoy-quickstart/graphql/gql/pending-incoming-transactions-by-address.gql @@ -0,0 +1,56 @@ +query pendingIncomingTransactionsByAddress($address: OnChainAddress!) { + me { + defaultAccount { + displayCurrency + wallets { + __typename + id + walletCurrency + pendingIncomingTransactionsByAddress(address: $address) { + __typename + id + status + direction + memo + createdAt + settlementAmount + settlementFee + settlementDisplayAmount + settlementDisplayFee + settlementDisplayCurrency + settlementCurrency + settlementPrice { + base + offset + } + initiationVia { + __typename + ... on InitiationViaIntraLedger { + counterPartyWalletId + counterPartyUsername + } + ... on InitiationViaLn { + paymentHash + } + ... on InitiationViaOnChain { + address + } + } + settlementVia { + __typename + ... on SettlementViaIntraLedger { + counterPartyWalletId + counterPartyUsername + } + ... on SettlementViaLn { + preImage + } + ... on SettlementViaOnChain { + transactionHash + } + } + } + } + } + } +} diff --git a/dev/vendor/galoy-quickstart/graphql/gql/pending-incoming-transactions.gql b/dev/vendor/galoy-quickstart/graphql/gql/pending-incoming-transactions.gql new file mode 100644 index 0000000000..9e7dde50fb --- /dev/null +++ b/dev/vendor/galoy-quickstart/graphql/gql/pending-incoming-transactions.gql @@ -0,0 +1,51 @@ +query pendingIncomingTransactions { + me { + defaultAccount { + displayCurrency + pendingIncomingTransactions { + __typename + id + status + direction + memo + createdAt + settlementAmount + settlementFee + settlementDisplayAmount + settlementDisplayFee + settlementDisplayCurrency + settlementCurrency + settlementPrice { + base + offset + } + initiationVia { + __typename + ... on InitiationViaIntraLedger { + counterPartyWalletId + counterPartyUsername + } + ... on InitiationViaLn { + paymentHash + } + ... on InitiationViaOnChain { + address + } + } + settlementVia { + __typename + ... on SettlementViaIntraLedger { + counterPartyWalletId + counterPartyUsername + } + ... on SettlementViaLn { + preImage + } + ... on SettlementViaOnChain { + transactionHash + } + } + } + } + } +} diff --git a/dev/vendor/galoy-quickstart/graphql/gql/price-sub.gql b/dev/vendor/galoy-quickstart/graphql/gql/price-sub.gql new file mode 100644 index 0000000000..a00f77db48 --- /dev/null +++ b/dev/vendor/galoy-quickstart/graphql/gql/price-sub.gql @@ -0,0 +1,14 @@ +subscription { + price( + input: { amount: 100 amountCurrencyUnit: BTCSAT priceCurrencyUnit: USDCENT } + ) { + errors { + message + } + price { + base + offset + currencyUnit + } + } +} diff --git a/dev/vendor/galoy-quickstart/graphql/gql/quiz-claim.gql b/dev/vendor/galoy-quickstart/graphql/gql/quiz-claim.gql new file mode 100644 index 0000000000..a581b2e5cd --- /dev/null +++ b/dev/vendor/galoy-quickstart/graphql/gql/quiz-claim.gql @@ -0,0 +1,15 @@ +mutation quizClaim($input: QuizClaimInput!) { + quizClaim(input: $input) { + quizzes { + amount + completed + id + notBefore + } + errors { + code + message + path + } + } +} diff --git a/dev/vendor/galoy-quickstart/graphql/gql/quiz-question.gql b/dev/vendor/galoy-quickstart/graphql/gql/quiz-question.gql new file mode 100644 index 0000000000..648be43836 --- /dev/null +++ b/dev/vendor/galoy-quickstart/graphql/gql/quiz-question.gql @@ -0,0 +1,14 @@ +mutation quizQuestion($input: QuizCompletedInput!) { + quizCompleted(input: $input) { + quiz { + amount + completed + id + } + errors { + code + message + path + } + } +} diff --git a/dev/vendor/galoy-quickstart/graphql/gql/quiz.gql b/dev/vendor/galoy-quickstart/graphql/gql/quiz.gql new file mode 100644 index 0000000000..b93946e577 --- /dev/null +++ b/dev/vendor/galoy-quickstart/graphql/gql/quiz.gql @@ -0,0 +1,16 @@ +query myQuizQuestions { + me { + id + defaultAccount { + id + ... on ConsumerAccount { + quiz { + id + amount + completed + notBefore + } + } + } + } +} diff --git a/dev/vendor/galoy-quickstart/graphql/gql/real-time-price-sub.gql b/dev/vendor/galoy-quickstart/graphql/gql/real-time-price-sub.gql new file mode 100644 index 0000000000..00c13d1b29 --- /dev/null +++ b/dev/vendor/galoy-quickstart/graphql/gql/real-time-price-sub.gql @@ -0,0 +1,22 @@ +subscription realtimePrice($currency: DisplayCurrency!) { + realtimePrice(input: { currency: $currency }) { + errors { + message + } + realtimePrice { + id + timestamp + denominatorCurrency + btcSatPrice { + base + offset + currencyUnit + } + usdCentPrice { + base + offset + currencyUnit + } + } + } +} diff --git a/dev/vendor/galoy-quickstart/graphql/gql/revoke-api-key.gql b/dev/vendor/galoy-quickstart/graphql/gql/revoke-api-key.gql new file mode 100644 index 0000000000..d671dabc47 --- /dev/null +++ b/dev/vendor/galoy-quickstart/graphql/gql/revoke-api-key.gql @@ -0,0 +1,13 @@ +mutation ApiKeyRevoke($input: ApiKeyRevokeInput!) { + apiKeyRevoke(input: $input) { + apiKey { + id + name + createdAt + revoked + expired + lastUsedAt + expiresAt + } + } +} diff --git a/dev/vendor/galoy-quickstart/graphql/gql/transaction-for-wallet-by-id.gql b/dev/vendor/galoy-quickstart/graphql/gql/transaction-for-wallet-by-id.gql new file mode 100644 index 0000000000..2fbf247a24 --- /dev/null +++ b/dev/vendor/galoy-quickstart/graphql/gql/transaction-for-wallet-by-id.gql @@ -0,0 +1,55 @@ +query transactionForWalletById($walletId: WalletId!, $transactionId: ID!) { + me { + defaultAccount { + id + displayCurrency + walletById(walletId: $walletId) { + transactionById(transactionId: $transactionId) { + __typename + id + status + direction + memo + createdAt + settlementAmount + settlementFee + settlementDisplayAmount + settlementDisplayFee + settlementDisplayCurrency + settlementCurrency + settlementPrice { + base + offset + } + initiationVia { + __typename + ... on InitiationViaIntraLedger { + counterPartyWalletId + counterPartyUsername + } + ... on InitiationViaLn { + paymentHash + paymentRequest + } + ... on InitiationViaOnChain { + address + } + } + settlementVia { + __typename + ... on SettlementViaIntraLedger { + counterPartyWalletId + counterPartyUsername + } + ... on SettlementViaLn { + preImage + } + ... on SettlementViaOnChain { + transactionHash + } + } + } + } + } + } +} diff --git a/dev/vendor/galoy-quickstart/graphql/gql/transactions-by-address.gql b/dev/vendor/galoy-quickstart/graphql/gql/transactions-by-address.gql new file mode 100644 index 0000000000..00ff80989a --- /dev/null +++ b/dev/vendor/galoy-quickstart/graphql/gql/transactions-by-address.gql @@ -0,0 +1,68 @@ +query transactionsByAddress($first: Int, $after: String, $address: OnChainAddress!) { + me { + defaultAccount { + displayCurrency + wallets { + __typename + id + walletCurrency + transactionsByAddress(first: $first, after: $after, address: $address) { + ...TransactionList + } + } + } + } +} + +fragment TransactionList on TransactionConnection { + pageInfo { + hasNextPage + } + edges { + cursor + node { + __typename + id + status + direction + memo + createdAt + settlementAmount + settlementFee + settlementDisplayAmount + settlementDisplayFee + settlementDisplayCurrency + settlementCurrency + settlementPrice { + base + offset + } + initiationVia { + __typename + ... on InitiationViaIntraLedger { + counterPartyWalletId + counterPartyUsername + } + ... on InitiationViaLn { + paymentHash + } + ... on InitiationViaOnChain { + address + } + } + settlementVia { + __typename + ... on SettlementViaIntraLedger { + counterPartyWalletId + counterPartyUsername + } + ... on SettlementViaLn { + preImage + } + ... on SettlementViaOnChain { + transactionHash + } + } + } + } +} diff --git a/dev/vendor/galoy-quickstart/graphql/gql/transactions-by-wallet.gql b/dev/vendor/galoy-quickstart/graphql/gql/transactions-by-wallet.gql new file mode 100644 index 0000000000..494cbb3d96 --- /dev/null +++ b/dev/vendor/galoy-quickstart/graphql/gql/transactions-by-wallet.gql @@ -0,0 +1,79 @@ +query transactionsByWallet($first: Int, $after: String) { + me { + defaultAccount { + displayCurrency + wallets { + ... on BTCWallet { + __typename + id + walletCurrency + transactions(first: $first, after: $after) { + ...TransactionList + } + } + ... on UsdWallet { + __typename + id + walletCurrency + transactions(first: $first, after: $after) { + ...TransactionList + } + } + } + } + } +} + +fragment TransactionList on TransactionConnection { + pageInfo { + hasNextPage + } + edges { + cursor + node { + __typename + id + status + direction + memo + createdAt + settlementAmount + settlementFee + settlementDisplayAmount + settlementDisplayFee + settlementDisplayCurrency + settlementCurrency + settlementPrice { + base + offset + } + initiationVia { + __typename + ... on InitiationViaIntraLedger { + counterPartyWalletId + counterPartyUsername + } + ... on InitiationViaLn { + paymentHash + paymentRequest + } + ... on InitiationViaOnChain { + address + } + } + settlementVia { + __typename + ... on SettlementViaIntraLedger { + counterPartyWalletId + counterPartyUsername + } + ... on SettlementViaLn { + preImage + } + ... on SettlementViaOnChain { + transactionHash + } + } + } + } +} diff --git a/dev/vendor/galoy-quickstart/graphql/gql/transactions-for-wallet-by-payment-hash.gql b/dev/vendor/galoy-quickstart/graphql/gql/transactions-for-wallet-by-payment-hash.gql new file mode 100644 index 0000000000..f90d1c7af9 --- /dev/null +++ b/dev/vendor/galoy-quickstart/graphql/gql/transactions-for-wallet-by-payment-hash.gql @@ -0,0 +1,58 @@ +query transactionsForWalletByPaymentHash( + $walletId: WalletId! + $paymentHash: PaymentHash! +) { + me { + defaultAccount { + displayCurrency + walletById(walletId: $walletId) { + id + transactionsByPaymentHash(paymentHash: $paymentHash) { + __typename + id + status + direction + memo + createdAt + settlementAmount + settlementFee + settlementDisplayAmount + settlementDisplayFee + settlementDisplayCurrency + settlementCurrency + settlementPrice { + base + offset + } + initiationVia { + __typename + ... on InitiationViaIntraLedger { + counterPartyWalletId + counterPartyUsername + } + ... on InitiationViaLn { + paymentHash + paymentRequest + } + ... on InitiationViaOnChain { + address + } + } + settlementVia { + __typename + ... on SettlementViaIntraLedger { + counterPartyWalletId + counterPartyUsername + } + ... on SettlementViaLn { + preImage + } + ... on SettlementViaOnChain { + transactionHash + } + } + } + } + } + } +} diff --git a/dev/vendor/galoy-quickstart/graphql/gql/transactions.gql b/dev/vendor/galoy-quickstart/graphql/gql/transactions.gql new file mode 100644 index 0000000000..5955d7a311 --- /dev/null +++ b/dev/vendor/galoy-quickstart/graphql/gql/transactions.gql @@ -0,0 +1,66 @@ +query transactions($walletIds: [WalletId], $first: Int, $after: String) { + me { + defaultAccount { + defaultWallet { + id + } + transactions(walletIds: $walletIds, first: $first, after: $after) { + ...TransactionList + } + } + } +} + +fragment TransactionList on TransactionConnection { + pageInfo { + hasNextPage + } + edges { + cursor + node { + __typename + id + status + direction + memo + createdAt + settlementAmount + settlementFee + settlementDisplayAmount + settlementDisplayFee + settlementDisplayCurrency + settlementCurrency + settlementPrice { + base + offset + } + initiationVia { + __typename + ... on InitiationViaIntraLedger { + counterPartyWalletId + counterPartyUsername + } + ... on InitiationViaLn { + paymentHash + paymentRequest + } + ... on InitiationViaOnChain { + address + } + } + settlementVia { + __typename + ... on SettlementViaIntraLedger { + counterPartyWalletId + counterPartyUsername + } + ... on SettlementViaLn { + preImage + } + ... on SettlementViaOnChain { + transactionHash + } + } + } + } +} diff --git a/dev/vendor/galoy-quickstart/graphql/gql/update-display-currency.gql b/dev/vendor/galoy-quickstart/graphql/gql/update-display-currency.gql new file mode 100644 index 0000000000..a813ceef1d --- /dev/null +++ b/dev/vendor/galoy-quickstart/graphql/gql/update-display-currency.gql @@ -0,0 +1,7 @@ +mutation displayCurrencyUpdate($input: AccountUpdateDisplayCurrencyInput!) { + accountUpdateDisplayCurrency(input: $input) { + account { + displayCurrency + } + } +} diff --git a/dev/vendor/galoy-quickstart/graphql/gql/user-details.gql b/dev/vendor/galoy-quickstart/graphql/gql/user-details.gql new file mode 100644 index 0000000000..931ac80c19 --- /dev/null +++ b/dev/vendor/galoy-quickstart/graphql/gql/user-details.gql @@ -0,0 +1,6 @@ +query userDetails { + me { + id + language + } +} diff --git a/dev/vendor/galoy-quickstart/graphql/gql/user-disable-notification-category.gql b/dev/vendor/galoy-quickstart/graphql/gql/user-disable-notification-category.gql new file mode 100644 index 0000000000..5a7ac5c7e6 --- /dev/null +++ b/dev/vendor/galoy-quickstart/graphql/gql/user-disable-notification-category.gql @@ -0,0 +1,12 @@ +mutation userDisableNotificationCategory( + $input: UserDisableNotificationCategoryInput! +) { + userDisableNotificationCategory(input: $input) { + notificationSettings { + push { + enabled + disabledCategories + } + } + } +} diff --git a/dev/vendor/galoy-quickstart/graphql/gql/user-disable-notification-channel.gql b/dev/vendor/galoy-quickstart/graphql/gql/user-disable-notification-channel.gql new file mode 100644 index 0000000000..b9ad7df580 --- /dev/null +++ b/dev/vendor/galoy-quickstart/graphql/gql/user-disable-notification-channel.gql @@ -0,0 +1,12 @@ +mutation userDisableNotificationChannel( + $input: UserDisableNotificationChannelInput! +) { + userDisableNotificationChannel(input: $input) { + notificationSettings { + push { + enabled + disabledCategories + } + } + } +} diff --git a/dev/vendor/galoy-quickstart/graphql/gql/user-email-delete.gql b/dev/vendor/galoy-quickstart/graphql/gql/user-email-delete.gql new file mode 100644 index 0000000000..a83e165a5f --- /dev/null +++ b/dev/vendor/galoy-quickstart/graphql/gql/user-email-delete.gql @@ -0,0 +1,14 @@ +mutation userEmailDelete { + userEmailDelete { + errors { + message + } + me { + id + email { + address + verified + } + } + } +} diff --git a/dev/vendor/galoy-quickstart/graphql/gql/user-email-registration-initiate.gql b/dev/vendor/galoy-quickstart/graphql/gql/user-email-registration-initiate.gql new file mode 100644 index 0000000000..e71d774a3d --- /dev/null +++ b/dev/vendor/galoy-quickstart/graphql/gql/user-email-registration-initiate.gql @@ -0,0 +1,15 @@ +mutation userEmailRegistrationInitiate($input: UserEmailRegistrationInitiateInput!) { + userEmailRegistrationInitiate(input: $input) { + errors { + message + } + emailRegistrationId + me { + id + email { + address + verified + } + } + } +} diff --git a/dev/vendor/galoy-quickstart/graphql/gql/user-email-registration-validate.gql b/dev/vendor/galoy-quickstart/graphql/gql/user-email-registration-validate.gql new file mode 100644 index 0000000000..14fc670c2f --- /dev/null +++ b/dev/vendor/galoy-quickstart/graphql/gql/user-email-registration-validate.gql @@ -0,0 +1,14 @@ +mutation userEmailRegistrationValidate($input: UserEmailRegistrationValidateInput!) { + userEmailRegistrationValidate(input: $input) { + errors { + message + } + me { + id + email { + address + verified + } + } + } +} diff --git a/dev/vendor/galoy-quickstart/graphql/gql/user-enable-notification-category.gql b/dev/vendor/galoy-quickstart/graphql/gql/user-enable-notification-category.gql new file mode 100644 index 0000000000..e613b1b742 --- /dev/null +++ b/dev/vendor/galoy-quickstart/graphql/gql/user-enable-notification-category.gql @@ -0,0 +1,12 @@ +mutation userEnableNotificationCategory( + $input: UserEnableNotificationCategoryInput! +) { + userEnableNotificationCategory(input: $input) { + notificationSettings { + push { + enabled + disabledCategories + } + } + } +} diff --git a/dev/vendor/galoy-quickstart/graphql/gql/user-enable-notification-channel.gql b/dev/vendor/galoy-quickstart/graphql/gql/user-enable-notification-channel.gql new file mode 100644 index 0000000000..d52dfdd58f --- /dev/null +++ b/dev/vendor/galoy-quickstart/graphql/gql/user-enable-notification-channel.gql @@ -0,0 +1,12 @@ +mutation userEnableNotificationChannel( + $input: UserEnableNotificationChannelInput! +) { + userEnableNotificationChannel(input: $input) { + notificationSettings { + push { + enabled + disabledCategories + } + } + } +} diff --git a/dev/vendor/galoy-quickstart/graphql/gql/user-login-upgrade.gql b/dev/vendor/galoy-quickstart/graphql/gql/user-login-upgrade.gql new file mode 100644 index 0000000000..3c8045f877 --- /dev/null +++ b/dev/vendor/galoy-quickstart/graphql/gql/user-login-upgrade.gql @@ -0,0 +1,10 @@ +mutation userLoginUpgrade($input: UserLoginUpgradeInput!) { + userLoginUpgrade(input: $input) { + errors { + message + code + } + success + authToken + } +} diff --git a/dev/vendor/galoy-quickstart/graphql/gql/user-login.gql b/dev/vendor/galoy-quickstart/graphql/gql/user-login.gql new file mode 100644 index 0000000000..44b1b124c0 --- /dev/null +++ b/dev/vendor/galoy-quickstart/graphql/gql/user-login.gql @@ -0,0 +1,9 @@ +mutation userLogin($input: UserLoginInput!) { + userLogin(input: $input) { + errors { + code + message + } + authToken + } +} diff --git a/dev/vendor/galoy-quickstart/graphql/gql/user-notification-settings.gql b/dev/vendor/galoy-quickstart/graphql/gql/user-notification-settings.gql new file mode 100644 index 0000000000..f412ddd833 --- /dev/null +++ b/dev/vendor/galoy-quickstart/graphql/gql/user-notification-settings.gql @@ -0,0 +1,10 @@ +query userNotificationSettings { + me { + id + notificationSettings { + push { + enabled + } + } + } +} diff --git a/dev/vendor/galoy-quickstart/graphql/gql/user-phone-delete.gql b/dev/vendor/galoy-quickstart/graphql/gql/user-phone-delete.gql new file mode 100644 index 0000000000..be0befde8c --- /dev/null +++ b/dev/vendor/galoy-quickstart/graphql/gql/user-phone-delete.gql @@ -0,0 +1,15 @@ +mutation userPhoneDelete { + userPhoneDelete { + errors { + message + } + me { + id + phone + email { + address + verified + } + } + } +} diff --git a/dev/vendor/galoy-quickstart/graphql/gql/user-phone-registration-initiate.gql b/dev/vendor/galoy-quickstart/graphql/gql/user-phone-registration-initiate.gql new file mode 100644 index 0000000000..db8ad8cd2e --- /dev/null +++ b/dev/vendor/galoy-quickstart/graphql/gql/user-phone-registration-initiate.gql @@ -0,0 +1,8 @@ +mutation userPhoneRegistrationInitiate($input: UserPhoneRegistrationInitiateInput!) { + userPhoneRegistrationInitiate(input: $input) { + errors { + message + } + success + } +} diff --git a/dev/vendor/galoy-quickstart/graphql/gql/user-phone-registration-validate.gql b/dev/vendor/galoy-quickstart/graphql/gql/user-phone-registration-validate.gql new file mode 100644 index 0000000000..43030c9981 --- /dev/null +++ b/dev/vendor/galoy-quickstart/graphql/gql/user-phone-registration-validate.gql @@ -0,0 +1,11 @@ +mutation userPhoneRegistrationValidate($input: UserPhoneRegistrationValidateInput!) { + userPhoneRegistrationValidate(input: $input) { + errors { + message + } + me { + id + phone + } + } +} diff --git a/dev/vendor/galoy-quickstart/graphql/gql/user-totp-delete.gql b/dev/vendor/galoy-quickstart/graphql/gql/user-totp-delete.gql new file mode 100644 index 0000000000..02210750b7 --- /dev/null +++ b/dev/vendor/galoy-quickstart/graphql/gql/user-totp-delete.gql @@ -0,0 +1,14 @@ +mutation userTotpDelete { + userTotpDelete { + errors { + message + } + me { + totpEnabled + email { + address + verified + } + } + } +} diff --git a/dev/vendor/galoy-quickstart/graphql/gql/user-totp-registration-initiate.gql b/dev/vendor/galoy-quickstart/graphql/gql/user-totp-registration-initiate.gql new file mode 100644 index 0000000000..205ab12282 --- /dev/null +++ b/dev/vendor/galoy-quickstart/graphql/gql/user-totp-registration-initiate.gql @@ -0,0 +1,9 @@ +mutation userTotpRegistrationInitiate { + userTotpRegistrationInitiate { + errors { + message + } + totpRegistrationId + totpSecret + } +} diff --git a/dev/vendor/galoy-quickstart/graphql/gql/user-totp-registration-validate.gql b/dev/vendor/galoy-quickstart/graphql/gql/user-totp-registration-validate.gql new file mode 100644 index 0000000000..2f3c54b253 --- /dev/null +++ b/dev/vendor/galoy-quickstart/graphql/gql/user-totp-registration-validate.gql @@ -0,0 +1,14 @@ +mutation userTotpRegistrationValidate($input: UserTotpRegistrationValidateInput!) { + userTotpRegistrationValidate(input: $input) { + errors { + message + } + me { + totpEnabled + email { + address + verified + } + } + } +} diff --git a/dev/vendor/galoy-quickstart/graphql/gql/user-update-language.gql b/dev/vendor/galoy-quickstart/graphql/gql/user-update-language.gql new file mode 100644 index 0000000000..f1683e61ad --- /dev/null +++ b/dev/vendor/galoy-quickstart/graphql/gql/user-update-language.gql @@ -0,0 +1,11 @@ +mutation userUpdateLanguage($input: UserUpdateLanguageInput!) { + userUpdateLanguage(input: $input) { + user { + language + } + errors { + code + message + } + } +} diff --git a/dev/vendor/galoy-quickstart/graphql/gql/user-update-username.gql b/dev/vendor/galoy-quickstart/graphql/gql/user-update-username.gql new file mode 100644 index 0000000000..a971942f98 --- /dev/null +++ b/dev/vendor/galoy-quickstart/graphql/gql/user-update-username.gql @@ -0,0 +1,14 @@ +mutation userUpdateUsername($input: UserUpdateUsernameInput!) { + userUpdateUsername(input: $input) { + errors { + message + __typename + } + user { + id + username + __typename + } + __typename + } +} diff --git a/dev/vendor/galoy-quickstart/graphql/gql/username-available.gql b/dev/vendor/galoy-quickstart/graphql/gql/username-available.gql new file mode 100644 index 0000000000..dabe694afe --- /dev/null +++ b/dev/vendor/galoy-quickstart/graphql/gql/username-available.gql @@ -0,0 +1,3 @@ +query usernameAvailable($username: Username!) { + usernameAvailable(username: $username) +} diff --git a/dev/vendor/galoy-quickstart/graphql/gql/wallets-for-account.gql b/dev/vendor/galoy-quickstart/graphql/gql/wallets-for-account.gql new file mode 100644 index 0000000000..4679226643 --- /dev/null +++ b/dev/vendor/galoy-quickstart/graphql/gql/wallets-for-account.gql @@ -0,0 +1,13 @@ +query me { + me { + defaultAccount { + id + wallets { + id + walletCurrency + balance + pendingIncomingBalance + } + } + } +} diff --git a/dev/vendor/galoy-quickstart/graphql/schemas/admin/schema.graphql b/dev/vendor/galoy-quickstart/graphql/schemas/admin/schema.graphql new file mode 100644 index 0000000000..98d9247965 --- /dev/null +++ b/dev/vendor/galoy-quickstart/graphql/schemas/admin/schema.graphql @@ -0,0 +1,653 @@ +type AccountDetailPayload { + accountDetails: AuditedAccount + errors: [Error!]! +} + +"""Unique identifier of an account""" +scalar AccountId + +enum AccountLevel { + ONE + TWO + ZERO +} + +enum AccountStatus { + ACTIVE + CLOSED + LOCKED + NEW + PENDING +} + +input AccountUpdateLevelInput { + accountId: AccountId! + level: AccountLevel! +} + +input AccountUpdateStatusInput { + accountId: AccountId! + comment: String + status: AccountStatus! +} + +input AdminPushNotificationSendInput { + accountId: String! + body: String! + data: Object + notificationCategory: NotificationCategory + title: String! +} + +type AdminPushNotificationSendPayload { + errors: [Error!]! + success: Boolean +} + +""" +Accounts are core to the Galoy architecture. they have users, and own wallets +""" +type AuditedAccount { + createdAt: Timestamp! + id: ID! + level: AccountLevel! + owner: AuditedUser! + status: AccountStatus! + username: Username + wallets: [Wallet!]! +} + +type AuditedMerchant { + """ + GPS coordinates for the merchant that can be used to place the related business on a map + """ + coordinates: Coordinates + createdAt: Timestamp! + id: ID! + title: String! + + """The username of the merchant""" + username: Username! + + """Whether the merchant has been validated""" + validated: Boolean! +} + +type AuditedUser { + createdAt: Timestamp! + + """Email address""" + email: Email + id: ID! + language: Language! + phone: Phone +} + +""" +A wallet belonging to an account which contains a BTC balance and a list of transactions. +""" +type BTCWallet implements Wallet { + accountId: ID! + + """A balance stored in BTC.""" + balance: SignedAmount! + id: ID! + invoiceByPaymentHash(paymentHash: PaymentHash!): Invoice! + + """A list of all invoices associated with walletIds optionally passed.""" + invoices( + """Returns the items in the list that come after the specified cursor.""" + after: String + + """Returns the items in the list that come before the specified cursor.""" + before: String + + """Returns the first n items from the list.""" + first: Int + + """Returns the last n items from the list.""" + last: Int + ): InvoiceConnection + + """An unconfirmed incoming onchain balance.""" + pendingIncomingBalance: SignedAmount! + pendingIncomingTransactions: [Transaction!]! + pendingIncomingTransactionsByAddress( + """Returns the items that include this address.""" + address: OnChainAddress! + ): [Transaction!]! + transactionById(transactionId: ID!): Transaction! + + """A list of BTC transactions associated with this wallet.""" + transactions( + """Returns the items in the list that come after the specified cursor.""" + after: String + + """Returns the items in the list that come before the specified cursor.""" + before: String + + """Returns the first n items from the list.""" + first: Int + + """Returns the last n items from the list.""" + last: Int + ): TransactionConnection + transactionsByAddress( + """Returns the items that include this address.""" + address: OnChainAddress! + + """Returns the items in the list that come after the specified cursor.""" + after: String + + """Returns the items in the list that come before the specified cursor.""" + before: String + + """Returns the first n items from the list.""" + first: Int + + """Returns the last n items from the list.""" + last: Int + ): TransactionConnection + transactionsByPaymentHash(paymentHash: PaymentHash!): [Transaction!]! + walletCurrency: WalletCurrency! +} + +input BusinessDeleteMapInfoInput { + username: Username! +} + +input BusinessUpdateMapInfoInput { + latitude: Float! + longitude: Float! + title: String! + username: Username! +} + +type Coordinates { + latitude: Float! + longitude: Float! +} + +"""Display currency of an account""" +scalar DisplayCurrency + +type Email { + address: EmailAddress + verified: Boolean +} + +"""Email address""" +scalar EmailAddress + +interface Error { + code: String + message: String! + path: [String] +} + +type GraphQLApplicationError implements Error { + code: String + message: String! + path: [String] +} + +union InitiationVia = InitiationViaIntraLedger | InitiationViaLn | InitiationViaOnChain + +type InitiationViaIntraLedger { + counterPartyUsername: Username + counterPartyWalletId: WalletId +} + +type InitiationViaLn { + paymentHash: PaymentHash! + + """Bolt11 invoice""" + paymentRequest: LnPaymentRequest! +} + +type InitiationViaOnChain { + address: OnChainAddress! +} + +"""A lightning invoice.""" +interface Invoice { + createdAt: Timestamp! + + """The payment hash of the lightning invoice.""" + paymentHash: PaymentHash! + + """The bolt11 invoice to be paid.""" + paymentRequest: LnPaymentRequest! + + """ + The payment secret of the lightning invoice. This is not the preimage of the payment hash. + """ + paymentSecret: LnPaymentSecret! + + """The payment status of the invoice.""" + paymentStatus: InvoicePaymentStatus! +} + +"""A connection to a list of items.""" +type InvoiceConnection { + """A list of edges.""" + edges: [InvoiceEdge!] + + """Information to aid in pagination.""" + pageInfo: PageInfo! +} + +"""An edge in a connection.""" +type InvoiceEdge { + """A cursor for use in pagination""" + cursor: String! + + """The item at the end of the edge""" + node: Invoice! +} + +enum InvoicePaymentStatus { + EXPIRED + PAID + PENDING +} + +scalar Language + +type LightningInvoice { + confirmedAt: Timestamp + createdAt: Timestamp! + description: String! + expiresAt: Timestamp + isSettled: Boolean! + received: SatAmount! + request: LnPaymentRequest + secretPreImage: LnPaymentPreImage! +} + +type LightningPayment { + amount: SatAmount + confirmedAt: Timestamp + createdAt: Timestamp + destination: LnPubkey + request: LnPaymentRequest + revealedPreImage: LnPaymentPreImage + roundedUpFee: SatAmount + status: LnPaymentStatus +} + +scalar LnPaymentPreImage + +"""BOLT11 lightning invoice payment request with the amount included""" +scalar LnPaymentRequest + +scalar LnPaymentSecret + +enum LnPaymentStatus { + FAILED + PENDING + SETTLED +} + +scalar LnPubkey + +"""Text field in a lightning payment transaction""" +scalar Memo + +type MerchantPayload { + errors: [Error!]! + merchant: AuditedMerchant +} + +type Mutation { + accountUpdateLevel(input: AccountUpdateLevelInput!): AccountDetailPayload! + accountUpdateStatus(input: AccountUpdateStatusInput!): AccountDetailPayload! + adminPushNotificationSend(input: AdminPushNotificationSendInput!): AdminPushNotificationSendPayload! + businessDeleteMapInfo(input: BusinessDeleteMapInfoInput!): AccountDetailPayload! + businessUpdateMapInfo(input: BusinessUpdateMapInfoInput!): MerchantPayload! + userUpdatePhone(input: UserUpdatePhoneInput!): AccountDetailPayload! +} + +scalar NotificationCategory + +scalar Object + +"""An address for an on-chain bitcoin destination""" +scalar OnChainAddress + +scalar OnChainTxHash + +"""Information about pagination in a connection.""" +type PageInfo { + """When paginating forwards, the cursor to continue.""" + endCursor: String + + """When paginating forwards, are there more items?""" + hasNextPage: Boolean! + + """When paginating backwards, are there more items?""" + hasPreviousPage: Boolean! + + """When paginating backwards, the cursor to continue.""" + startCursor: String +} + +scalar PaymentHash + +"""Phone number which includes country code""" +scalar Phone + +interface PriceInterface { + base: SafeInt! + currencyUnit: String! @deprecated(reason: "Deprecated due to type renaming") + offset: Int! +} + +""" +Price of 1 sat or 1 usd cent in base/offset. To calculate, use: `base / 10^offset` +""" +type PriceOfOneSettlementMinorUnitInDisplayMinorUnit implements PriceInterface { + base: SafeInt! + currencyUnit: String! @deprecated(reason: "Deprecated due to type renaming") + formattedAmount: String! @deprecated(reason: "Deprecated please use `base / 10^offset`") + offset: Int! +} + +type Query { + accountDetailsByAccountId(accountId: ID!): AuditedAccount! + accountDetailsByEmail(email: EmailAddress!): AuditedAccount! + accountDetailsByUserId(userId: ID!): AuditedAccount! + accountDetailsByUserPhone(phone: Phone!): AuditedAccount! + accountDetailsByUsername(username: Username!): AuditedAccount! + allLevels: [AccountLevel!]! + lightningInvoice(hash: PaymentHash!): LightningInvoice! + lightningPayment(hash: PaymentHash!): LightningPayment! + listWalletIds(walletCurrency: WalletCurrency!): [WalletId!]! + transactionById(id: ID!): Transaction + transactionsByHash(hash: PaymentHash!): [Transaction] + wallet(walletId: WalletId!): Wallet! +} + +""" +Non-fractional signed whole numeric value between -(2^53) + 1 and 2^53 - 1 +""" +scalar SafeInt + +"""(Positive) Satoshi amount""" +scalar SatAmount + +union SettlementVia = SettlementViaIntraLedger | SettlementViaLn | SettlementViaOnChain + +type SettlementViaIntraLedger { + """ + Settlement destination: Could be null if the payee does not have a username + """ + counterPartyUsername: Username + counterPartyWalletId: WalletId + preImage: LnPaymentPreImage +} + +type SettlementViaLn { + paymentSecret: LnPaymentSecret @deprecated(reason: "Shifting property to 'preImage' to improve granularity of the LnPaymentSecret type") + preImage: LnPaymentPreImage +} + +type SettlementViaOnChain { + arrivalInMempoolEstimatedAt: Timestamp + transactionHash: OnChainTxHash + vout: Int +} + +"""An amount (of a currency) that can be negative (e.g. in a transaction)""" +scalar SignedAmount + +""" +A string amount (of a currency) that can be negative (e.g. in a transaction) +""" +scalar SignedDisplayMajorAmount + +""" +Timestamp field, serialized as Unix time (the number of seconds since the Unix epoch) +""" +scalar Timestamp + +""" +Give details about an individual transaction. +Galoy have a smart routing system which is automatically +settling intraledger when both the payer and payee use the same wallet +therefore it's possible the transactions is being initiated onchain +or with lightning but settled intraledger. +""" +type Transaction { + createdAt: Timestamp! + direction: TxDirection! + id: ID! + + """From which protocol the payment has been initiated.""" + initiationVia: InitiationVia! + memo: Memo + + """Amount of the settlement currency sent or received.""" + settlementAmount: SignedAmount! + + """Wallet currency for transaction.""" + settlementCurrency: WalletCurrency! + settlementDisplayAmount: SignedDisplayMajorAmount! + settlementDisplayCurrency: DisplayCurrency! + settlementDisplayFee: SignedDisplayMajorAmount! + settlementFee: SignedAmount! + + """Price in WALLETCURRENCY/SETTLEMENTUNIT at time of settlement.""" + settlementPrice: PriceOfOneSettlementMinorUnitInDisplayMinorUnit! + + """To which protocol the payment has settled on.""" + settlementVia: SettlementVia! + status: TxStatus! +} + +"""A connection to a list of items.""" +type TransactionConnection { + """A list of edges.""" + edges: [TransactionEdge!] + + """Information to aid in pagination.""" + pageInfo: PageInfo! +} + +"""An edge in a connection.""" +type TransactionEdge { + """A cursor for use in pagination""" + cursor: String! + + """The item at the end of the edge""" + node: Transaction! +} + +enum TxDirection { + RECEIVE + SEND +} + +enum TxStatus { + FAILURE + PENDING + SUCCESS +} + +""" +A wallet belonging to an account which contains a USD balance and a list of transactions. +""" +type UsdWallet implements Wallet { + accountId: ID! + balance: SignedAmount! + id: ID! + invoiceByPaymentHash(paymentHash: PaymentHash!): Invoice! + + """A list of all invoices associated with walletIds optionally passed.""" + invoices( + """Returns the items in the list that come after the specified cursor.""" + after: String + + """Returns the items in the list that come before the specified cursor.""" + before: String + + """Returns the first n items from the list.""" + first: Int + + """Returns the last n items from the list.""" + last: Int + ): InvoiceConnection + + """An unconfirmed incoming onchain balance.""" + pendingIncomingBalance: SignedAmount! + pendingIncomingTransactions: [Transaction!]! + pendingIncomingTransactionsByAddress( + """Returns the items that include this address.""" + address: OnChainAddress! + ): [Transaction!]! + transactionById(transactionId: ID!): Transaction! + transactions( + """Returns the items in the list that come after the specified cursor.""" + after: String + + """Returns the items in the list that come before the specified cursor.""" + before: String + + """Returns the first n items from the list.""" + first: Int + + """Returns the last n items from the list.""" + last: Int + ): TransactionConnection + transactionsByAddress( + """Returns the items that include this address.""" + address: OnChainAddress! + + """Returns the items in the list that come after the specified cursor.""" + after: String + + """Returns the items in the list that come before the specified cursor.""" + before: String + + """Returns the first n items from the list.""" + first: Int + + """Returns the last n items from the list.""" + last: Int + ): TransactionConnection + transactionsByPaymentHash(paymentHash: PaymentHash!): [Transaction!]! + walletCurrency: WalletCurrency! +} + +input UserUpdatePhoneInput { + accountId: AccountId! + phone: Phone! +} + +"""Unique identifier of a user""" +scalar Username + +""" +A generic wallet which stores value in one of our supported currencies. +""" +interface Wallet { + accountId: ID! + balance: SignedAmount! + id: ID! + invoiceByPaymentHash( + """ + The lightning invoice with the matching paymentHash belonging to this wallet. + """ + paymentHash: PaymentHash! + ): Invoice! + invoices( + """Returns the items in the list that come after the specified cursor.""" + after: String + + """Returns the items in the list that come before the specified cursor.""" + before: String + + """Returns the first n items from the list.""" + first: Int + + """Returns the last n items from the list.""" + last: Int + ): InvoiceConnection + pendingIncomingBalance: SignedAmount! + + """ + Pending incoming OnChain transactions. When transactions + are confirmed they will receive a new id and be found in the transactions + list. Transactions are ordered anti-chronologically, + ie: the newest transaction will be first + """ + pendingIncomingTransactions: [Transaction!]! + + """ + Pending incoming OnChain transactions. When transactions + are confirmed they will receive a new id and be found in the transactions + list. Transactions are ordered anti-chronologically, + ie: the newest transaction will be first + """ + pendingIncomingTransactionsByAddress( + """Returns the items that include this address.""" + address: OnChainAddress! + ): [Transaction!]! + transactionById(transactionId: ID!): Transaction! + + """ + Transactions are ordered anti-chronologically, + ie: the newest transaction will be first + """ + transactions( + """Returns the items in the list that come after the specified cursor.""" + after: String + + """Returns the items in the list that come before the specified cursor.""" + before: String + + """Returns the first n items from the list.""" + first: Int + + """Returns the last n items from the list.""" + last: Int + ): TransactionConnection + + """ + Transactions are ordered anti-chronologically, + ie: the newest transaction will be first + """ + transactionsByAddress( + """Returns the items that include this address.""" + address: OnChainAddress! + + """Returns the items in the list that come after the specified cursor.""" + after: String + + """Returns the items in the list that come before the specified cursor.""" + before: String + + """Returns the first n items from the list.""" + first: Int + + """Returns the last n items from the list.""" + last: Int + ): TransactionConnection + + """ + Returns the transactions that include this paymentHash. This should be a list of size one for a received lightning payment. This can be more that one transaction for a sent lightning payment. + """ + transactionsByPaymentHash( + """The payment hash of the lightning invoice paid in this transaction.""" + paymentHash: PaymentHash! + ): [Transaction!]! + walletCurrency: WalletCurrency! +} + +enum WalletCurrency { + BTC + USD +} + +"""Unique identifier of a wallet""" +scalar WalletId diff --git a/dev/vendor/galoy-quickstart/graphql/schemas/public/schema.graphql b/dev/vendor/galoy-quickstart/graphql/schemas/public/schema.graphql new file mode 100644 index 0000000000..a11ad983eb --- /dev/null +++ b/dev/vendor/galoy-quickstart/graphql/schemas/public/schema.graphql @@ -0,0 +1,1724 @@ +interface Account { + callbackEndpoints: [CallbackEndpoint!]! + csvTransactions(walletIds: [WalletId!]!): String! + defaultWallet: PublicWallet! + defaultWalletId: WalletId! @deprecated(reason: "Shifting property to 'defaultWallet.id'") + displayCurrency: DisplayCurrency! + id: ID! + invoices( + """Returns the items in the list that come after the specified cursor.""" + after: String + + """Returns the items in the list that come before the specified cursor.""" + before: String + + """Returns the first n items from the list.""" + first: Int + + """Returns the last n items from the list.""" + last: Int + walletIds: [WalletId] + ): InvoiceConnection + level: AccountLevel! + limits: AccountLimits! + notificationSettings: NotificationSettings! + pendingIncomingTransactions(walletIds: [WalletId]): [Transaction!]! + realtimePrice: RealtimePrice! + transactions( + """Returns the items in the list that come after the specified cursor.""" + after: String + + """Returns the items in the list that come before the specified cursor.""" + before: String + + """Returns the first n items from the list.""" + first: Int + + """Returns the last n items from the list.""" + last: Int + walletIds: [WalletId] + ): TransactionConnection + walletById(walletId: WalletId!): Wallet! + wallets: [Wallet!]! +} + +type AccountDeletePayload { + errors: [Error!]! + success: Boolean! +} + +input AccountDisableNotificationCategoryInput { + category: NotificationCategory! + channel: NotificationChannel +} + +input AccountDisableNotificationChannelInput { + channel: NotificationChannel! +} + +input AccountEnableNotificationCategoryInput { + category: NotificationCategory! + channel: NotificationChannel +} + +input AccountEnableNotificationChannelInput { + channel: NotificationChannel! +} + +enum AccountLevel { + ONE + TWO + ZERO +} + +interface AccountLimit { + """The rolling time interval in seconds that the limits would apply for.""" + interval: Seconds + + """ + The amount of cents remaining below the limit for the current 24 hour period. + """ + remainingLimit: CentAmount + + """The current maximum limit for a given 24 hour period.""" + totalLimit: CentAmount! +} + +type AccountLimits { + """ + Limits for converting between currencies among a account's own wallets. + """ + convert: [AccountLimit!]! + + """Limits for sending to other internal accounts.""" + internalSend: [AccountLimit!]! + + """Limits for withdrawing to external onchain or lightning destinations.""" + withdrawal: [AccountLimit!]! +} + +input AccountUpdateDefaultWalletIdInput { + walletId: WalletId! +} + +type AccountUpdateDefaultWalletIdPayload { + account: ConsumerAccount + errors: [Error!]! +} + +input AccountUpdateDisplayCurrencyInput { + currency: DisplayCurrency! +} + +type AccountUpdateDisplayCurrencyPayload { + account: ConsumerAccount + errors: [Error!]! +} + +type AccountUpdateNotificationSettingsPayload { + account: ConsumerAccount + errors: [Error!]! +} + +"""An Opaque Bearer token""" +scalar AuthToken + +type AuthTokenPayload { + authToken: AuthToken + errors: [Error!]! + totpRequired: Boolean +} + +""" +A wallet belonging to an account which contains a BTC balance and a list of transactions. +""" +type BTCWallet implements Wallet { + accountId: ID! + + """A balance stored in BTC.""" + balance: SignedAmount! + id: ID! + invoiceByPaymentHash(paymentHash: PaymentHash!): Invoice! + + """A list of all invoices associated with walletIds optionally passed.""" + invoices( + """Returns the items in the list that come after the specified cursor.""" + after: String + + """Returns the items in the list that come before the specified cursor.""" + before: String + + """Returns the first n items from the list.""" + first: Int + + """Returns the last n items from the list.""" + last: Int + ): InvoiceConnection + + """An unconfirmed incoming onchain balance.""" + pendingIncomingBalance: SignedAmount! + pendingIncomingTransactions: [Transaction!]! + pendingIncomingTransactionsByAddress( + """Returns the items that include this address.""" + address: OnChainAddress! + ): [Transaction!]! + transactionById(transactionId: ID!): Transaction! + + """A list of BTC transactions associated with this wallet.""" + transactions( + """Returns the items in the list that come after the specified cursor.""" + after: String + + """Returns the items in the list that come before the specified cursor.""" + before: String + + """Returns the first n items from the list.""" + first: Int + + """Returns the last n items from the list.""" + last: Int + ): TransactionConnection + transactionsByAddress( + """Returns the items that include this address.""" + address: OnChainAddress! + + """Returns the items in the list that come after the specified cursor.""" + after: String + + """Returns the items in the list that come before the specified cursor.""" + before: String + + """Returns the first n items from the list.""" + first: Int + + """Returns the last n items from the list.""" + last: Int + ): TransactionConnection + transactionsByPaymentHash(paymentHash: PaymentHash!): [Transaction!]! + walletCurrency: WalletCurrency! +} + +type BuildInformation { + commitHash: String + helmRevision: Int +} + +type CallbackEndpoint { + id: EndpointId! + url: EndpointUrl! +} + +input CallbackEndpointAddInput { + """callback endpoint to be called""" + url: EndpointUrl! +} + +type CallbackEndpointAddPayload { + errors: [Error!]! + id: EndpointId +} + +input CallbackEndpointDeleteInput { + id: EndpointId! +} + +type CaptchaCreateChallengePayload { + errors: [Error!]! + result: CaptchaCreateChallengeResult +} + +type CaptchaCreateChallengeResult { + challengeCode: String! + failbackMode: Boolean! + id: String! + newCaptcha: Boolean! +} + +input CaptchaRequestAuthCodeInput { + challengeCode: String! + channel: PhoneCodeChannelType + phone: Phone! + secCode: String! + validationCode: String! +} + +"""(Positive) Cent amount (1/100 of a dollar)""" +scalar CentAmount + +type CentAmountPayload { + amount: CentAmount + errors: [Error!]! +} + +type ConsumerAccount implements Account { + callbackEndpoints: [CallbackEndpoint!]! + + """ + return CSV stream, base64 encoded, of the list of transactions in the wallet + """ + csvTransactions(walletIds: [WalletId!]!): String! + defaultWallet: PublicWallet! + defaultWalletId: WalletId! + displayCurrency: DisplayCurrency! + id: ID! + + """A list of all invoices associated with walletIds optionally passed.""" + invoices( + """Returns the items in the list that come after the specified cursor.""" + after: String + + """Returns the items in the list that come before the specified cursor.""" + before: String + + """Returns the first n items from the list.""" + first: Int + + """Returns the last n items from the list.""" + last: Int + walletIds: [WalletId] + ): InvoiceConnection + level: AccountLevel! + limits: AccountLimits! + notificationSettings: NotificationSettings! + pendingIncomingTransactions(walletIds: [WalletId]): [Transaction!]! + + """List the quiz questions of the consumer account""" + quiz: [Quiz!]! + realtimePrice: RealtimePrice! + + """ + A list of all transactions associated with walletIds optionally passed. + """ + transactions( + """Returns the items in the list that come after the specified cursor.""" + after: String + + """Returns the items in the list that come before the specified cursor.""" + before: String + + """Returns the first n items from the list.""" + first: Int + + """Returns the last n items from the list.""" + last: Int + walletIds: [WalletId] + ): TransactionConnection + walletById(walletId: WalletId!): Wallet! + wallets: [Wallet!]! +} + +""" +An alias name that a user can set for a wallet (with which they have transactions) +""" +scalar ContactAlias + +type Coordinates { + latitude: Float! + longitude: Float! +} + +type Country { + id: CountryCode! + supportedAuthChannels: [PhoneCodeChannelType!]! +} + +"""A CCA2 country code (ex US, FR, etc)""" +scalar CountryCode + +type Currency { + flag: String! + fractionDigits: Int! + id: ID! + name: String! + symbol: String! +} + +type DepositFeesInformation { + minBankFee: String! + + """below this amount minBankFee will be charged""" + minBankFeeThreshold: String! + + """ratio to charge as basis points above minBankFeeThreshold amount""" + ratio: String! +} + +input DeviceNotificationTokenCreateInput { + deviceToken: String! +} + +"""Display currency of an account""" +scalar DisplayCurrency + +type Email { + address: EmailAddress + verified: Boolean +} + +"""Email address""" +scalar EmailAddress + +""" +An id to be passed between registrationInitiate and registrationValidate for confirming email +""" +scalar EmailRegistrationId + +scalar EndpointId + +"""Url that will be fetched on events for the account""" +scalar EndpointUrl + +interface Error { + code: String + message: String! + path: [String] +} + +enum ExchangeCurrencyUnit { + BTCSAT + USDCENT +} + +"""Feedback shared with our user""" +scalar Feedback + +input FeedbackSubmitInput { + feedback: Feedback! +} + +type FeesInformation { + deposit: DepositFeesInformation! +} + +""" +Provides global settings for the application which might have an impact for the user. +""" +type Globals { + buildInformation: BuildInformation! + feesInformation: FeesInformation! + + """ + The domain name for lightning addresses accepted by this Galoy instance + """ + lightningAddressDomain: String! + lightningAddressDomainAliases: [String!]! + + """ + Which network (mainnet, testnet, regtest, signet) this instance is running on. + """ + network: Network! + + """ + A list of public keys for the running lightning nodes. + This can be used to know if an invoice belongs to one of our nodes. + """ + nodesIds: [String!]! + + """A list of countries and their supported auth channels""" + supportedCountries: [Country!]! +} + +type GraphQLApplicationError implements Error { + code: String + message: String! + path: [String] +} + +"""Hex-encoded string of 32 bytes""" +scalar Hex32Bytes + +union InitiationVia = InitiationViaIntraLedger | InitiationViaLn | InitiationViaOnChain + +type InitiationViaIntraLedger { + counterPartyUsername: Username + counterPartyWalletId: WalletId +} + +type InitiationViaLn { + paymentHash: PaymentHash! + + """Bolt11 invoice""" + paymentRequest: LnPaymentRequest! +} + +type InitiationViaOnChain { + address: OnChainAddress! +} + +input IntraLedgerPaymentSendInput { + """Amount in satoshis.""" + amount: SatAmount! + + """Optional memo to be attached to the payment.""" + memo: Memo + recipientWalletId: WalletId! + + """The wallet ID of the sender.""" + walletId: WalletId! +} + +type IntraLedgerUpdate { + amount: SatAmount! @deprecated(reason: "Deprecated in favor of transaction") + displayCurrencyPerSat: Float! @deprecated(reason: "Deprecated in favor of transaction") + transaction: Transaction! + txNotificationType: TxNotificationType! + usdPerSat: Float! @deprecated(reason: "updated over displayCurrencyPerSat") + walletId: WalletId! @deprecated(reason: "Deprecated in favor of transaction") +} + +input IntraLedgerUsdPaymentSendInput { + """Amount in cents.""" + amount: CentAmount! + + """Optional memo to be attached to the payment.""" + memo: Memo + recipientWalletId: WalletId! + + """The wallet ID of the sender.""" + walletId: WalletId! +} + +"""A lightning invoice.""" +interface Invoice { + createdAt: Timestamp! + + """The payment hash of the lightning invoice.""" + paymentHash: PaymentHash! + + """The bolt11 invoice to be paid.""" + paymentRequest: LnPaymentRequest! + + """ + The payment secret of the lightning invoice. This is not the preimage of the payment hash. + """ + paymentSecret: LnPaymentSecret! + + """The payment status of the invoice.""" + paymentStatus: InvoicePaymentStatus! +} + +"""A connection to a list of items.""" +type InvoiceConnection { + """A list of edges.""" + edges: [InvoiceEdge!] + + """Information to aid in pagination.""" + pageInfo: PageInfo! +} + +"""An edge in a connection.""" +type InvoiceEdge { + """A cursor for use in pagination""" + cursor: String! + + """The item at the end of the edge""" + node: Invoice! +} + +enum InvoicePaymentStatus { + EXPIRED + PAID + PENDING +} + +scalar Language + +input LnAddressPaymentSendInput { + """Amount in satoshis.""" + amount: SatAmount! + + """Lightning address to send to.""" + lnAddress: String! + + """Wallet ID to send bitcoin from.""" + walletId: WalletId! +} + +type LnInvoice implements Invoice { + createdAt: Timestamp! + paymentHash: PaymentHash! + paymentRequest: LnPaymentRequest! + paymentSecret: LnPaymentSecret! + paymentStatus: InvoicePaymentStatus! + satoshis: SatAmount! +} + +input LnInvoiceCreateInput { + """Amount in satoshis.""" + amount: SatAmount! + + """Optional invoice expiration time in minutes.""" + expiresIn: Minutes + + """Optional memo for the lightning invoice.""" + memo: Memo + + """Wallet ID for a BTC wallet belonging to the current account.""" + walletId: WalletId! +} + +input LnInvoiceCreateOnBehalfOfRecipientInput { + """Amount in satoshis.""" + amount: SatAmount! + descriptionHash: Hex32Bytes + + """Optional invoice expiration time in minutes.""" + expiresIn: Minutes + + """Optional memo for the lightning invoice.""" + memo: Memo + + """Wallet ID for a BTC wallet which belongs to any account.""" + recipientWalletId: WalletId! +} + +input LnInvoiceFeeProbeInput { + paymentRequest: LnPaymentRequest! + walletId: WalletId! +} + +type LnInvoicePayload { + errors: [Error!]! + invoice: LnInvoice +} + +input LnInvoicePaymentInput { + """Optional memo to associate with the lightning invoice.""" + memo: Memo + + """Payment request representing the invoice which is being paid.""" + paymentRequest: LnPaymentRequest! + + """ + Wallet ID with sufficient balance to cover amount of invoice. Must belong to the account of the current user. + """ + walletId: WalletId! +} + +input LnInvoicePaymentStatusInput { + paymentRequest: LnPaymentRequest! +} + +type LnInvoicePaymentStatusPayload { + errors: [Error!]! + status: InvoicePaymentStatus +} + +type LnNoAmountInvoice implements Invoice { + createdAt: Timestamp! + paymentHash: PaymentHash! + paymentRequest: LnPaymentRequest! + paymentSecret: LnPaymentSecret! + paymentStatus: InvoicePaymentStatus! +} + +input LnNoAmountInvoiceCreateInput { + """Optional invoice expiration time in minutes.""" + expiresIn: Minutes + + """Optional memo for the lightning invoice.""" + memo: Memo + + """ + ID for either a USD or BTC wallet belonging to the account of the current user. + """ + walletId: WalletId! +} + +input LnNoAmountInvoiceCreateOnBehalfOfRecipientInput { + """Optional invoice expiration time in minutes.""" + expiresIn: Minutes + + """Optional memo for the lightning invoice.""" + memo: Memo + + """ + ID for either a USD or BTC wallet which belongs to the account of any user. + """ + recipientWalletId: WalletId! +} + +input LnNoAmountInvoiceFeeProbeInput { + amount: SatAmount! + paymentRequest: LnPaymentRequest! + walletId: WalletId! +} + +type LnNoAmountInvoicePayload { + errors: [Error!]! + invoice: LnNoAmountInvoice +} + +input LnNoAmountInvoicePaymentInput { + """Amount to pay in satoshis.""" + amount: SatAmount! + + """Optional memo to associate with the lightning invoice.""" + memo: Memo + + """Payment request representing the invoice which is being paid.""" + paymentRequest: LnPaymentRequest! + + """ + Wallet ID with sufficient balance to cover amount defined in mutation request. Must belong to the account of the current user. + """ + walletId: WalletId! +} + +input LnNoAmountUsdInvoiceFeeProbeInput { + amount: CentAmount! + paymentRequest: LnPaymentRequest! + walletId: WalletId! +} + +input LnNoAmountUsdInvoicePaymentInput { + """Amount to pay in USD cents.""" + amount: CentAmount! + + """Optional memo to associate with the lightning invoice.""" + memo: Memo + + """Payment request representing the invoice which is being paid.""" + paymentRequest: LnPaymentRequest! + + """ + Wallet ID with sufficient balance to cover amount defined in mutation request. Must belong to the account of the current user. + """ + walletId: WalletId! +} + +scalar LnPaymentPreImage + +"""BOLT11 lightning invoice payment request with the amount included""" +scalar LnPaymentRequest + +scalar LnPaymentSecret + +type LnUpdate { + paymentHash: PaymentHash! @deprecated(reason: "Deprecated in favor of transaction") + status: InvoicePaymentStatus! + transaction: Transaction! + walletId: WalletId! @deprecated(reason: "Deprecated in favor of transaction") +} + +input LnUsdInvoiceBtcDenominatedCreateOnBehalfOfRecipientInput { + """Amount in satoshis.""" + amount: SatAmount! + descriptionHash: Hex32Bytes + + """Optional invoice expiration time in minutes.""" + expiresIn: Minutes + + """ + Optional memo for the lightning invoice. Acts as a note to the recipient. + """ + memo: Memo + + """Wallet ID for a USD wallet which belongs to the account of any user.""" + recipientWalletId: WalletId! +} + +input LnUsdInvoiceCreateInput { + """Amount in USD cents.""" + amount: CentAmount! + + """Optional invoice expiration time in minutes.""" + expiresIn: Minutes + + """Optional memo for the lightning invoice.""" + memo: Memo + + """Wallet ID for a USD wallet belonging to the current user.""" + walletId: WalletId! +} + +input LnUsdInvoiceCreateOnBehalfOfRecipientInput { + """Amount in USD cents.""" + amount: CentAmount! + descriptionHash: Hex32Bytes + + """Optional invoice expiration time in minutes.""" + expiresIn: Minutes + + """ + Optional memo for the lightning invoice. Acts as a note to the recipient. + """ + memo: Memo + + """Wallet ID for a USD wallet which belongs to the account of any user.""" + recipientWalletId: WalletId! +} + +input LnUsdInvoiceFeeProbeInput { + paymentRequest: LnPaymentRequest! + walletId: WalletId! +} + +input LnurlPaymentSendInput { + """Amount in satoshis.""" + amount: SatAmount! + + """Lnurl string to send to.""" + lnurl: String! + + """Wallet ID to send bitcoin from.""" + walletId: WalletId! +} + +type MapInfo { + coordinates: Coordinates! + title: String! +} + +type MapMarker { + mapInfo: MapInfo! + username: Username! +} + +"""Text field in a lightning payment transaction""" +scalar Memo + +"""(Positive) amount of minutes""" +scalar Minutes + +type MobileVersions { + currentSupported: Int! + minSupported: Int! + platform: String! +} + +type Mutation { + accountDelete: AccountDeletePayload! + accountDisableNotificationCategory(input: AccountDisableNotificationCategoryInput!): AccountUpdateNotificationSettingsPayload! + accountDisableNotificationChannel(input: AccountDisableNotificationChannelInput!): AccountUpdateNotificationSettingsPayload! + accountEnableNotificationCategory(input: AccountEnableNotificationCategoryInput!): AccountUpdateNotificationSettingsPayload! + accountEnableNotificationChannel(input: AccountEnableNotificationChannelInput!): AccountUpdateNotificationSettingsPayload! + accountUpdateDefaultWalletId(input: AccountUpdateDefaultWalletIdInput!): AccountUpdateDefaultWalletIdPayload! + accountUpdateDisplayCurrency(input: AccountUpdateDisplayCurrencyInput!): AccountUpdateDisplayCurrencyPayload! + callbackEndpointAdd(input: CallbackEndpointAddInput!): CallbackEndpointAddPayload! + callbackEndpointDelete(input: CallbackEndpointDeleteInput!): SuccessPayload! + captchaCreateChallenge: CaptchaCreateChallengePayload! + captchaRequestAuthCode(input: CaptchaRequestAuthCodeInput!): SuccessPayload! + deviceNotificationTokenCreate(input: DeviceNotificationTokenCreateInput!): SuccessPayload! + feedbackSubmit(input: FeedbackSubmitInput!): SuccessPayload! + + """ + Actions a payment which is internal to the ledger e.g. it does + not use onchain/lightning. Returns payment status (success, + failed, pending, already_paid). + """ + intraLedgerPaymentSend(input: IntraLedgerPaymentSendInput!): PaymentSendPayload! + + """ + Actions a payment which is internal to the ledger e.g. it does + not use onchain/lightning. Returns payment status (success, + failed, pending, already_paid). + """ + intraLedgerUsdPaymentSend(input: IntraLedgerUsdPaymentSendInput!): PaymentSendPayload! + + """Sends a payment to a lightning address.""" + lnAddressPaymentSend(input: LnAddressPaymentSendInput!): PaymentSendPayload! + + """ + Returns a lightning invoice for an associated wallet. + When invoice is paid the value will be credited to a BTC wallet. + Expires after 'expiresIn' or 24 hours. + """ + lnInvoiceCreate(input: LnInvoiceCreateInput!): LnInvoicePayload! + + """ + Returns a lightning invoice for an associated wallet. + When invoice is paid the value will be credited to a BTC wallet. + Expires after 'expiresIn' or 24 hours. + """ + lnInvoiceCreateOnBehalfOfRecipient(input: LnInvoiceCreateOnBehalfOfRecipientInput!): LnInvoicePayload! + lnInvoiceFeeProbe(input: LnInvoiceFeeProbeInput!): SatAmountPayload! + + """ + Pay a lightning invoice using a balance from a wallet which is owned by the account of the current user. + Provided wallet can be USD or BTC and must have sufficient balance to cover amount in lightning invoice. + Returns payment status (success, failed, pending, already_paid). + """ + lnInvoicePaymentSend(input: LnInvoicePaymentInput!): PaymentSendPayload! + + """ + Returns a lightning invoice for an associated wallet. + Can be used to receive any supported currency value (currently USD or BTC). + Expires after 'expiresIn' or 24 hours for BTC invoices or 5 minutes for USD invoices. + """ + lnNoAmountInvoiceCreate(input: LnNoAmountInvoiceCreateInput!): LnNoAmountInvoicePayload! + + """ + Returns a lightning invoice for an associated wallet. + Can be used to receive any supported currency value (currently USD or BTC). + Expires after 'expiresIn' or 24 hours for BTC invoices or 5 minutes for USD invoices. + """ + lnNoAmountInvoiceCreateOnBehalfOfRecipient(input: LnNoAmountInvoiceCreateOnBehalfOfRecipientInput!): LnNoAmountInvoicePayload! + lnNoAmountInvoiceFeeProbe(input: LnNoAmountInvoiceFeeProbeInput!): SatAmountPayload! + + """ + Pay a lightning invoice using a balance from a wallet which is owned by the account of the current user. + Provided wallet must be BTC and must have sufficient balance to cover amount specified in mutation request. + Returns payment status (success, failed, pending, already_paid). + """ + lnNoAmountInvoicePaymentSend(input: LnNoAmountInvoicePaymentInput!): PaymentSendPayload! + lnNoAmountUsdInvoiceFeeProbe(input: LnNoAmountUsdInvoiceFeeProbeInput!): CentAmountPayload! + + """ + Pay a lightning invoice using a balance from a wallet which is owned by the account of the current user. + Provided wallet must be USD and have sufficient balance to cover amount specified in mutation request. + Returns payment status (success, failed, pending, already_paid). + """ + lnNoAmountUsdInvoicePaymentSend(input: LnNoAmountUsdInvoicePaymentInput!): PaymentSendPayload! + + """ + Returns a lightning invoice denominated in satoshis for an associated wallet. + When invoice is paid the equivalent value at invoice creation will be credited to a USD wallet. + Expires after 'expiresIn' or 5 minutes (short expiry time because there is a USD/BTC exchange rate + associated with the amount). + """ + lnUsdInvoiceBtcDenominatedCreateOnBehalfOfRecipient(input: LnUsdInvoiceBtcDenominatedCreateOnBehalfOfRecipientInput!): LnInvoicePayload! + + """ + Returns a lightning invoice denominated in satoshis for an associated wallet. + When invoice is paid the equivalent value at invoice creation will be credited to a USD wallet. + Expires after 'expiresIn' or 5 minutes (short expiry time because there is a USD/BTC exchange rate + associated with the amount). + """ + lnUsdInvoiceCreate(input: LnUsdInvoiceCreateInput!): LnInvoicePayload! + + """ + Returns a lightning invoice denominated in satoshis for an associated wallet. + When invoice is paid the equivalent value at invoice creation will be credited to a USD wallet. + Expires after 'expiresIn' or 5 minutes (short expiry time because there is a USD/BTC exchange rate + associated with the amount). + """ + lnUsdInvoiceCreateOnBehalfOfRecipient(input: LnUsdInvoiceCreateOnBehalfOfRecipientInput!): LnInvoicePayload! + lnUsdInvoiceFeeProbe(input: LnUsdInvoiceFeeProbeInput!): SatAmountPayload! + + """Sends a payment to a lightning address.""" + lnurlPaymentSend(input: LnurlPaymentSendInput!): PaymentSendPayload! + onChainAddressCreate(input: OnChainAddressCreateInput!): OnChainAddressPayload! + onChainAddressCurrent(input: OnChainAddressCurrentInput!): OnChainAddressPayload! + onChainPaymentSend(input: OnChainPaymentSendInput!): PaymentSendPayload! + onChainPaymentSendAll(input: OnChainPaymentSendAllInput!): PaymentSendPayload! + onChainUsdPaymentSend(input: OnChainUsdPaymentSendInput!): PaymentSendPayload! + onChainUsdPaymentSendAsBtcDenominated(input: OnChainUsdPaymentSendAsBtcDenominatedInput!): PaymentSendPayload! + quizClaim(input: QuizClaimInput!): QuizClaimPayload! + quizCompleted(input: QuizCompletedInput!): QuizCompletedPayload! @deprecated(reason: "Use quizClaim instead") + userContactUpdateAlias(input: UserContactUpdateAliasInput!): UserContactUpdateAliasPayload! @deprecated(reason: "will be moved to AccountContact") + userEmailDelete: UserEmailDeletePayload! + userEmailRegistrationInitiate(input: UserEmailRegistrationInitiateInput!): UserEmailRegistrationInitiatePayload! + userEmailRegistrationValidate(input: UserEmailRegistrationValidateInput!): UserEmailRegistrationValidatePayload! + userLogin(input: UserLoginInput!): AuthTokenPayload! + userLoginUpgrade(input: UserLoginUpgradeInput!): UpgradePayload! + userLogout(input: UserLogoutInput): SuccessPayload! + userPhoneDelete: UserPhoneDeletePayload! + userPhoneRegistrationInitiate(input: UserPhoneRegistrationInitiateInput!): SuccessPayload! + userPhoneRegistrationValidate(input: UserPhoneRegistrationValidateInput!): UserPhoneRegistrationValidatePayload! + userTotpDelete: UserTotpDeletePayload! + userTotpRegistrationInitiate: UserTotpRegistrationInitiatePayload! + userTotpRegistrationValidate(input: UserTotpRegistrationValidateInput!): UserTotpRegistrationValidatePayload! + userUpdateLanguage(input: UserUpdateLanguageInput!): UserUpdateLanguagePayload! + userUpdateUsername(input: UserUpdateUsernameInput!): UserUpdateUsernamePayload! @deprecated(reason: "Username will be moved to @Handle in Accounts. Also SetUsername naming should be used instead of UpdateUsername to reflect the idempotency of Handles") +} + +type MyUpdatesPayload { + errors: [Error!]! + me: User + update: UserUpdate +} + +enum Network { + mainnet + regtest + signet + testnet +} + +scalar NotificationCategory + +enum NotificationChannel { + PUSH +} + +type NotificationChannelSettings { + disabledCategories: [NotificationCategory!]! + enabled: Boolean! +} + +type NotificationSettings { + push: NotificationChannelSettings! +} + +"""An address for an on-chain bitcoin destination""" +scalar OnChainAddress + +input OnChainAddressCreateInput { + walletId: WalletId! +} + +input OnChainAddressCurrentInput { + walletId: WalletId! +} + +type OnChainAddressPayload { + address: OnChainAddress + errors: [Error!]! +} + +input OnChainPaymentSendAllInput { + address: OnChainAddress! + memo: Memo + speed: PayoutSpeed! = FAST + walletId: WalletId! +} + +input OnChainPaymentSendInput { + address: OnChainAddress! + amount: SatAmount! + memo: Memo + speed: PayoutSpeed! = FAST + walletId: WalletId! +} + +type OnChainTxFee { + amount: SatAmount! +} + +scalar OnChainTxHash + +type OnChainUpdate { + amount: SatAmount! @deprecated(reason: "Deprecated in favor of transaction") + displayCurrencyPerSat: Float! @deprecated(reason: "Deprecated in favor of transaction") + transaction: Transaction! + txHash: OnChainTxHash! @deprecated(reason: "Deprecated in favor of transaction") + txNotificationType: TxNotificationType! + usdPerSat: Float! @deprecated(reason: "updated over displayCurrencyPerSat") + walletId: WalletId! @deprecated(reason: "Deprecated in favor of transaction") +} + +input OnChainUsdPaymentSendAsBtcDenominatedInput { + address: OnChainAddress! + amount: SatAmount! + memo: Memo + speed: PayoutSpeed! = FAST + walletId: WalletId! +} + +input OnChainUsdPaymentSendInput { + address: OnChainAddress! + amount: CentAmount! + memo: Memo + speed: PayoutSpeed! = FAST + walletId: WalletId! +} + +type OnChainUsdTxFee { + amount: CentAmount! +} + +type OneDayAccountLimit implements AccountLimit { + """ + The rolling time interval value in seconds for the current 24 hour period. + """ + interval: Seconds + + """ + The amount of cents remaining below the limit for the current 24 hour period. + """ + remainingLimit: CentAmount + + """The current maximum limit for a given 24 hour period.""" + totalLimit: CentAmount! +} + +"""An authentication code valid for a single use""" +scalar OneTimeAuthCode + +"""Information about pagination in a connection.""" +type PageInfo { + """When paginating forwards, the cursor to continue.""" + endCursor: String + + """When paginating forwards, are there more items?""" + hasNextPage: Boolean! + + """When paginating backwards, are there more items?""" + hasPreviousPage: Boolean! + + """When paginating backwards, the cursor to continue.""" + startCursor: String +} + +scalar PaymentHash + +type PaymentSendPayload { + errors: [Error!]! + status: PaymentSendResult + transaction: Transaction +} + +enum PaymentSendResult { + ALREADY_PAID + FAILURE + PENDING + SUCCESS +} + +enum PayoutSpeed { + FAST +} + +"""Phone number which includes country code""" +scalar Phone + +enum PhoneCodeChannelType { + SMS + WHATSAPP +} + +""" +Price amount expressed in base/offset. To calculate, use: `base / 10^offset` +""" +type Price { + base: SafeInt! + currencyUnit: String! + formattedAmount: String! + offset: Int! +} + +"""The range for the X axis in the BTC price graph""" +enum PriceGraphRange { + FIVE_YEARS + ONE_DAY + ONE_MONTH + ONE_WEEK + ONE_YEAR +} + +input PriceInput { + amount: SatAmount! + amountCurrencyUnit: ExchangeCurrencyUnit! + priceCurrencyUnit: ExchangeCurrencyUnit! +} + +interface PriceInterface { + base: SafeInt! + currencyUnit: String! @deprecated(reason: "Deprecated due to type renaming") + offset: Int! +} + +"""Price of 1 sat in base/offset. To calculate, use: `base / 10^offset`""" +type PriceOfOneSatInMinorUnit implements PriceInterface { + base: SafeInt! + currencyUnit: String! @deprecated(reason: "Deprecated due to type renaming") + offset: Int! +} + +""" +Price of 1 sat or 1 usd cent in base/offset. To calculate, use: `base / 10^offset` +""" +type PriceOfOneSettlementMinorUnitInDisplayMinorUnit implements PriceInterface { + base: SafeInt! + currencyUnit: String! @deprecated(reason: "Deprecated due to type renaming") + formattedAmount: String! @deprecated(reason: "Deprecated please use `base / 10^offset`") + offset: Int! +} + +""" +Price of 1 usd cent in base/offset. To calculate, use: `base / 10^offset` +""" +type PriceOfOneUsdCentInMinorUnit implements PriceInterface { + base: SafeInt! + currencyUnit: String! @deprecated(reason: "Deprecated due to type renaming") + offset: Int! +} + +type PricePayload { + errors: [Error!]! + price: Price +} + +type PricePoint { + price: Price! + + """ + Unix timestamp (number of seconds elapsed since January 1, 1970 00:00:00 UTC) + """ + timestamp: Timestamp! +} + +""" +A public view of a generic wallet which stores value in one of our supported currencies. +""" +type PublicWallet { + currency: WalletCurrency! + id: ID! + walletCurrency: WalletCurrency! @deprecated(reason: "Shifting property to 'currency'") +} + +type Query { + accountDefaultWallet(username: Username!, walletCurrency: WalletCurrency): PublicWallet! + btcPriceList(range: PriceGraphRange!): [PricePoint] + businessMapMarkers: [MapMarker!]! + currencyList: [Currency!]! + globals: Globals + lnInvoicePaymentStatus(input: LnInvoicePaymentStatusInput!): LnInvoicePaymentStatusPayload! + me: User + mobileVersions: [MobileVersions] + onChainTxFee(address: OnChainAddress!, amount: SatAmount!, speed: PayoutSpeed! = FAST, walletId: WalletId!): OnChainTxFee! + onChainUsdTxFee(address: OnChainAddress!, amount: CentAmount!, speed: PayoutSpeed! = FAST, walletId: WalletId!): OnChainUsdTxFee! + onChainUsdTxFeeAsBtcDenominated(address: OnChainAddress!, amount: SatAmount!, speed: PayoutSpeed! = FAST, walletId: WalletId!): OnChainUsdTxFee! + + """Returns 1 Sat and 1 Usd Cent price for the given currency""" + realtimePrice(currency: DisplayCurrency = "USD"): RealtimePrice! + userDefaultWalletId(username: Username!): WalletId! @deprecated(reason: "will be migrated to AccountDefaultWalletId") + usernameAvailable(username: Username!): Boolean +} + +type Quiz { + """The reward in Satoshis for the quiz question""" + amount: SatAmount! + completed: Boolean! + id: ID! + notBefore: Timestamp +} + +input QuizClaimInput { + id: ID! +} + +type QuizClaimPayload { + errors: [Error!]! + quizzes: [Quiz!]! +} + +input QuizCompletedInput { + id: ID! +} + +type QuizCompletedPayload { + errors: [Error!]! + quiz: Quiz +} + +type RealtimePrice { + btcSatPrice: PriceOfOneSatInMinorUnit! + denominatorCurrency: DisplayCurrency! + id: ID! + + """ + Unix timestamp (number of seconds elapsed since January 1, 1970 00:00:00 UTC) + """ + timestamp: Timestamp! + usdCentPrice: PriceOfOneUsdCentInMinorUnit! +} + +input RealtimePriceInput { + currency: DisplayCurrency = "USD" +} + +type RealtimePricePayload { + errors: [Error!]! + realtimePrice: RealtimePrice +} + +""" +Non-fractional signed whole numeric value between -(2^53) + 1 and 2^53 - 1 +""" +scalar SafeInt + +"""(Positive) Satoshi amount""" +scalar SatAmount + +type SatAmountPayload { + amount: SatAmount + errors: [Error!]! +} + +"""(Positive) amount of seconds""" +scalar Seconds + +union SettlementVia = SettlementViaIntraLedger | SettlementViaLn | SettlementViaOnChain + +type SettlementViaIntraLedger { + """ + Settlement destination: Could be null if the payee does not have a username + """ + counterPartyUsername: Username + counterPartyWalletId: WalletId + preImage: LnPaymentPreImage +} + +type SettlementViaLn { + paymentSecret: LnPaymentSecret @deprecated(reason: "Shifting property to 'preImage' to improve granularity of the LnPaymentSecret type") + preImage: LnPaymentPreImage +} + +type SettlementViaOnChain { + arrivalInMempoolEstimatedAt: Timestamp + transactionHash: OnChainTxHash + vout: Int +} + +"""An amount (of a currency) that can be negative (e.g. in a transaction)""" +scalar SignedAmount + +""" +A string amount (of a currency) that can be negative (e.g. in a transaction) +""" +scalar SignedDisplayMajorAmount + +type Subscription { + lnInvoicePaymentStatus(input: LnInvoicePaymentStatusInput!): LnInvoicePaymentStatusPayload! + myUpdates: MyUpdatesPayload! + price(input: PriceInput!): PricePayload! + + """Returns the price of 1 satoshi""" + realtimePrice(input: RealtimePriceInput!): RealtimePricePayload! +} + +type SuccessPayload { + errors: [Error!]! + success: Boolean +} + +""" +Timestamp field, serialized as Unix time (the number of seconds since the Unix epoch) +""" +scalar Timestamp + +"""A time-based one-time password""" +scalar TotpCode + +"""An id to be passed between set and verify for confirming totp""" +scalar TotpRegistrationId + +"""A secret to generate time-based one-time password""" +scalar TotpSecret + +""" +Give details about an individual transaction. +Galoy have a smart routing system which is automatically +settling intraledger when both the payer and payee use the same wallet +therefore it's possible the transactions is being initiated onchain +or with lightning but settled intraledger. +""" +type Transaction { + createdAt: Timestamp! + direction: TxDirection! + id: ID! + + """From which protocol the payment has been initiated.""" + initiationVia: InitiationVia! + memo: Memo + + """Amount of the settlement currency sent or received.""" + settlementAmount: SignedAmount! + + """Wallet currency for transaction.""" + settlementCurrency: WalletCurrency! + settlementDisplayAmount: SignedDisplayMajorAmount! + settlementDisplayCurrency: DisplayCurrency! + settlementDisplayFee: SignedDisplayMajorAmount! + settlementFee: SignedAmount! + + """Price in WALLETCURRENCY/SETTLEMENTUNIT at time of settlement.""" + settlementPrice: PriceOfOneSettlementMinorUnitInDisplayMinorUnit! + + """To which protocol the payment has settled on.""" + settlementVia: SettlementVia! + status: TxStatus! +} + +"""A connection to a list of items.""" +type TransactionConnection { + """A list of edges.""" + edges: [TransactionEdge!] + + """Information to aid in pagination.""" + pageInfo: PageInfo! +} + +"""An edge in a connection.""" +type TransactionEdge { + """A cursor for use in pagination""" + cursor: String! + + """The item at the end of the edge""" + node: Transaction! +} + +enum TxDirection { + RECEIVE + SEND +} + +enum TxNotificationType { + IntraLedgerPayment + IntraLedgerReceipt + LigtningReceipt + OnchainPayment + OnchainReceipt + OnchainReceiptPending +} + +enum TxStatus { + FAILURE + PENDING + SUCCESS +} + +type UpgradePayload { + authToken: AuthToken + errors: [Error!]! + success: Boolean! +} + +""" +A wallet belonging to an account which contains a USD balance and a list of transactions. +""" +type UsdWallet implements Wallet { + accountId: ID! + balance: SignedAmount! + id: ID! + invoiceByPaymentHash(paymentHash: PaymentHash!): Invoice! + + """A list of all invoices associated with walletIds optionally passed.""" + invoices( + """Returns the items in the list that come after the specified cursor.""" + after: String + + """Returns the items in the list that come before the specified cursor.""" + before: String + + """Returns the first n items from the list.""" + first: Int + + """Returns the last n items from the list.""" + last: Int + ): InvoiceConnection + + """An unconfirmed incoming onchain balance.""" + pendingIncomingBalance: SignedAmount! + pendingIncomingTransactions: [Transaction!]! + pendingIncomingTransactionsByAddress( + """Returns the items that include this address.""" + address: OnChainAddress! + ): [Transaction!]! + transactionById(transactionId: ID!): Transaction! + transactions( + """Returns the items in the list that come after the specified cursor.""" + after: String + + """Returns the items in the list that come before the specified cursor.""" + before: String + + """Returns the first n items from the list.""" + first: Int + + """Returns the last n items from the list.""" + last: Int + ): TransactionConnection + transactionsByAddress( + """Returns the items that include this address.""" + address: OnChainAddress! + + """Returns the items in the list that come after the specified cursor.""" + after: String + + """Returns the items in the list that come before the specified cursor.""" + before: String + + """Returns the first n items from the list.""" + first: Int + + """Returns the last n items from the list.""" + last: Int + ): TransactionConnection + transactionsByPaymentHash(paymentHash: PaymentHash!): [Transaction!]! + walletCurrency: WalletCurrency! +} + +type User { + """ + Get single contact details. + Can include the transactions associated with the contact. + """ + contactByUsername(username: Username!): UserContact! @deprecated(reason: "will be moved to Accounts") + + """ + Get full list of contacts. + Can include the transactions associated with each contact. + """ + contacts: [UserContact!]! @deprecated(reason: "will be moved to account") + createdAt: Timestamp! + defaultAccount: Account! + + """Email address""" + email: Email + id: ID! + + """ + Preferred language for user. + When value is 'default' the intent is to use preferred language from OS settings. + """ + language: Language! + + """Phone number with international calling code.""" + phone: Phone + + """Whether TOTP is enabled for this user.""" + totpEnabled: Boolean! + + """Optional immutable user friendly identifier.""" + username: Username @deprecated(reason: "will be moved to @Handle in Account and Wallet") +} + +type UserContact { + """ + Alias the user can set for this contact. + Only the user can see the alias attached to their contact. + """ + alias: ContactAlias + id: Username! + + """Paginated list of transactions sent to/from this contact.""" + transactions( + """Returns the items in the list that come after the specified cursor.""" + after: String + + """Returns the items in the list that come before the specified cursor.""" + before: String + + """Returns the first n items from the list.""" + first: Int + + """Returns the last n items from the list.""" + last: Int + ): TransactionConnection + transactionsCount: Int! + + """Actual identifier of the contact.""" + username: Username! +} + +input UserContactUpdateAliasInput { + alias: ContactAlias! + username: Username! +} + +type UserContactUpdateAliasPayload { + contact: UserContact + errors: [Error!]! +} + +type UserEmailDeletePayload { + errors: [Error!]! + me: User +} + +input UserEmailRegistrationInitiateInput { + email: EmailAddress! +} + +type UserEmailRegistrationInitiatePayload { + emailRegistrationId: EmailRegistrationId + errors: [Error!]! + me: User +} + +input UserEmailRegistrationValidateInput { + code: OneTimeAuthCode! + emailRegistrationId: EmailRegistrationId! +} + +type UserEmailRegistrationValidatePayload { + errors: [Error!]! + me: User +} + +input UserLoginInput { + code: OneTimeAuthCode! + phone: Phone! +} + +input UserLoginUpgradeInput { + code: OneTimeAuthCode! + phone: Phone! +} + +input UserLogoutInput { + deviceToken: String! +} + +type UserPhoneDeletePayload { + errors: [Error!]! + me: User +} + +input UserPhoneRegistrationInitiateInput { + channel: PhoneCodeChannelType + phone: Phone! +} + +input UserPhoneRegistrationValidateInput { + code: OneTimeAuthCode! + phone: Phone! +} + +type UserPhoneRegistrationValidatePayload { + errors: [Error!]! + me: User +} + +type UserTotpDeletePayload { + errors: [Error!]! + me: User +} + +type UserTotpRegistrationInitiatePayload { + errors: [Error!]! + totpRegistrationId: TotpRegistrationId + totpSecret: TotpSecret +} + +input UserTotpRegistrationValidateInput { + authToken: AuthToken + totpCode: TotpCode! + totpRegistrationId: TotpRegistrationId! +} + +type UserTotpRegistrationValidatePayload { + errors: [Error!]! + me: User +} + +union UserUpdate = IntraLedgerUpdate | LnUpdate | OnChainUpdate | Price | RealtimePrice + +input UserUpdateLanguageInput { + language: Language! +} + +type UserUpdateLanguagePayload { + errors: [Error!]! + user: User +} + +input UserUpdateUsernameInput { + username: Username! +} + +type UserUpdateUsernamePayload { + errors: [Error!]! + user: User +} + +"""Unique identifier of a user""" +scalar Username + +""" +A generic wallet which stores value in one of our supported currencies. +""" +interface Wallet { + accountId: ID! + balance: SignedAmount! + id: ID! + invoiceByPaymentHash( + """ + The lightning invoice with the matching paymentHash belonging to this wallet. + """ + paymentHash: PaymentHash! + ): Invoice! + invoices( + """Returns the items in the list that come after the specified cursor.""" + after: String + + """Returns the items in the list that come before the specified cursor.""" + before: String + + """Returns the first n items from the list.""" + first: Int + + """Returns the last n items from the list.""" + last: Int + ): InvoiceConnection + pendingIncomingBalance: SignedAmount! + + """ + Pending incoming OnChain transactions. When transactions + are confirmed they will receive a new id and be found in the transactions + list. Transactions are ordered anti-chronologically, + ie: the newest transaction will be first + """ + pendingIncomingTransactions: [Transaction!]! + + """ + Pending incoming OnChain transactions. When transactions + are confirmed they will receive a new id and be found in the transactions + list. Transactions are ordered anti-chronologically, + ie: the newest transaction will be first + """ + pendingIncomingTransactionsByAddress( + """Returns the items that include this address.""" + address: OnChainAddress! + ): [Transaction!]! + transactionById(transactionId: ID!): Transaction! + + """ + Transactions are ordered anti-chronologically, + ie: the newest transaction will be first + """ + transactions( + """Returns the items in the list that come after the specified cursor.""" + after: String + + """Returns the items in the list that come before the specified cursor.""" + before: String + + """Returns the first n items from the list.""" + first: Int + + """Returns the last n items from the list.""" + last: Int + ): TransactionConnection + + """ + Transactions are ordered anti-chronologically, + ie: the newest transaction will be first + """ + transactionsByAddress( + """Returns the items that include this address.""" + address: OnChainAddress! + + """Returns the items in the list that come after the specified cursor.""" + after: String + + """Returns the items in the list that come before the specified cursor.""" + before: String + + """Returns the first n items from the list.""" + first: Int + + """Returns the last n items from the list.""" + last: Int + ): TransactionConnection + + """ + Returns the transactions that include this paymentHash. This should be a list of size one for a received lightning payment. This can be more that one transaction for a sent lightning payment. + """ + transactionsByPaymentHash( + """The payment hash of the lightning invoice paid in this transaction.""" + paymentHash: PaymentHash! + ): [Transaction!]! + walletCurrency: WalletCurrency! +} + +enum WalletCurrency { + BTC + USD +} + +"""Unique identifier of a wallet""" +scalar WalletId diff --git a/flake.lock b/flake.lock new file mode 100644 index 0000000000..612204cb5e --- /dev/null +++ b/flake.lock @@ -0,0 +1,61 @@ +{ + "nodes": { + "flake-utils": { + "inputs": { + "systems": "systems" + }, + "locked": { + "lastModified": 1705309234, + "narHash": "sha256-uNRRNRKmJyCRC/8y1RqBkqWBLM034y4qN7EprSdmgyA=", + "owner": "numtide", + "repo": "flake-utils", + "rev": "1ef2e671c3b0c19053962c07dbda38332dcebf26", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "flake-utils", + "type": "github" + } + }, + "nixpkgs": { + "locked": { + "lastModified": 1707347730, + "narHash": "sha256-0etC/exQIaqC9vliKhc3eZE2Mm2wgLa0tj93ZF/egvM=", + "owner": "nixos", + "repo": "nixpkgs", + "rev": "6832d0d99649db3d65a0e15fa51471537b2c56a6", + "type": "github" + }, + "original": { + "owner": "nixos", + "ref": "nixos-23.11", + "repo": "nixpkgs", + "type": "github" + } + }, + "root": { + "inputs": { + "flake-utils": "flake-utils", + "nixpkgs": "nixpkgs" + } + }, + "systems": { + "locked": { + "lastModified": 1681028828, + "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", + "owner": "nix-systems", + "repo": "default", + "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", + "type": "github" + }, + "original": { + "owner": "nix-systems", + "repo": "default", + "type": "github" + } + } + }, + "root": "root", + "version": 7 +} diff --git a/flake.nix b/flake.nix new file mode 100644 index 0000000000..7ce81caf6d --- /dev/null +++ b/flake.nix @@ -0,0 +1,40 @@ +{ + description = "Galoy Mobile dev environment"; + + inputs = { + nixpkgs.url = "github:nixos/nixpkgs/nixos-23.11"; + flake-utils.url = "github:numtide/flake-utils"; + }; + + outputs = { + self, + nixpkgs, + flake-utils, + }: + flake-utils.lib.eachDefaultSystem (system: let + pkgs = import nixpkgs {inherit system;}; + nativeBuildInputs = with pkgs; + [ + tilt + alejandra + gnumake + docker-compose + shellcheck + shfmt + vendir + jq + ytt + ]; + in + with pkgs; { + devShells.default = mkShell { + inherit nativeBuildInputs; + shellHook = '' + export HOST_PROJECT_PATH="$(pwd)" + export COMPOSE_PROJECT_NAME=galoy-quickstart + ''; + }; + + formatter = alejandra; + }); +} diff --git a/typos.toml b/typos.toml index e57312b019..2d83f272da 100644 --- a/typos.toml +++ b/typos.toml @@ -6,4 +6,15 @@ hace = "hace" "Thier" = "Thier" [files] -extend-exclude = ["*.svg", "app/i18n/raw-i18n", "earns-utils.test.ts", "*.plist", "*.pbxproj", "Appfile", "google-services.json", "patches", "ci/tasks/*"] +extend-exclude = [ + "*.svg", + "app/i18n/raw-i18n", + "earns-utils.test.ts", + "*.plist", + "*.pbxproj", + "Appfile", + "google-services.json", + "patches", + "ci/tasks/*", + "dev/*", +]