From 8d4eea824d3f38fd4c1d11fa0cf424a2da68fc0f Mon Sep 17 00:00:00 2001 From: Skylar-Ray O'Quinn Date: Wed, 21 Dec 2022 18:37:33 +0000 Subject: [PATCH 1/5] Explain in detail running on Preview --- README.md | 55 +++- hydra-protocol-parameters.json.example | 386 +++++++++++++++++++++++++ 2 files changed, 437 insertions(+), 4 deletions(-) create mode 100644 hydra-protocol-parameters.json.example diff --git a/README.md b/README.md index 5fc73ae..ee42778 100644 --- a/README.md +++ b/README.md @@ -44,8 +44,6 @@ To use a custom configuration, mount a copy of the `config` directory from this docker run -p 127.0.0.1:8000:8000/tcp --volume /path/to/hydra-pay/config:/hydrapay/config obsidiansys/hydra-pay:latest ``` -There are command line options to run on your own Cardano network and Hydra Head parameters. These can be listed with the `--help` option and are similar to those of `cardano-node` and [`hydra-node`](https://hydra.family/head-protocol/docs/getting-started). - ### With Nix 1. [Install Nix](https://nixos.org/nix/). If you already have Nix installed, make sure you have version 2.0 or higher. To check your current version, run nix-env --version. @@ -83,6 +81,55 @@ cp -r config test-app Visit the live documentation and confirm your key and requests presented work as expected. +### Running on a Managed Devnet + +By default Hydra Pay will run a managed devnet, this devnet allows us to verify the API behavior of hydra pay in an efficient way, and is not for active development. + +When Hydra Pay launches, and you haven't configured it to utilize a cardano node that you are running, it will spawn a node, configure it as a local devnet, and seed 10 addresses with 10k ADA. + +These are made readily available to you via the API and the within the Live Docs to get your footing and start using and interacting with Hydra Pay. + +### Running on Preview + +You can configure Hydra Pay to use an existing node instead of creating a devnet node, and this allows you to interact with other cardano environments like Preview. + +To run on preview there is much more involved as Hydra Pay isn't managing address creation, key storage, and funding. To make things easier on developers the Live Documentation will detect it is connected to an external cardano node and adjust its instructions accordingly. + +#### Assumptions + +We assume you have a cardano node already running on Preview, and that it is running on the same machine you will be running Hydra Pay. As like other tools in the cardano ecosystem, the Hydra Nodes require access to a cardano node socket. Along with the socket you will need the shelley genesis file that was used to bootstrap your node, this should be in the directory your node is running in, and you can also find up to date versions of these genesis files [here](https://book.world.dev.cardano.org/environments.html). + +We also assume you have addresses to use in your testing and those addresses have funds, you can use the [Testnets Faucet](https://docs.cardano.org/cardano-testnet/tools/faucet) if you need funds (just remember to send them back when you are done!). + +#### Hydra Scripts on Preview + +Hydra in part works by using a Plutus smart contract on L1 and that contract must be deployed on the network you are using, here is the txid for the Hydra Scripts on Preview: +`4081fab39728fa3c05c0edc4dc7c0e8c45129ca6b2b70bf8600c1203a79d2c6d` + +#### Hydra Protocol Parameters + +Just like a Cardano Node, Hydra Nodes have a set of protocol parameters to control various aspects of the Node and the Network. However the Hydra Node doesn't need to (and usually shouldn't) use the same protocol parameters of the Cardano Node. If you don't know the exact protocol parameters you want, we recommend using the parameters found in hydra-protocol-parameters.json.example in this repo, the give a reasonable default to compliment the benefits of Hydra. + +#### Run configuration for Preview + +So with all that in mind, and the assumptions met, here is how you run Hydra Pay on Preview: + +```bash +hydra-pay \ + --testnet-magic 2 \ + --node-socket cardano-node.socket \ + --ledger-genesis cardano-node-byron-genesis.json \ + --hydra-scripts-tx-id 4081fab39728fa3c05c0edc4dc7c0e8c45129ca6b2b70bf8600c1203a79d2c6d \ + --hydra-ledger-protocol-parameters hydra-protocol-parameters.json \ + --hydra-ledger-genesis cardano-node-genesis-shelley.json +``` + +The testnet magic for `Preview` is `2`. The node socket is commonly found at `/run/cardano-node/node.socket` but this will depend on exactly how your cardano node is configured. + +As you can see you must provide some of the configuration files used for your node like the byron genesis file and the shelley genesis file. + +Once again we recommend using the Hydra parameters found in hydra-protocol-parameters.json.example unless you know exactly what you are doing. + ### API Key Your API Key should be provided in `config/backend/api-key` if no key is provided we generate a random one the aformentioned file. @@ -123,14 +170,14 @@ Foundational: - [x] Authentication support - [x] Tested on Preview - [x] Tested over https and wss -- [x] Live Documentation +- [x] Live Documentation: Devnet, Preview - [x] Full lifecycle guide - [x] Deployment Guide - [x] Docker Deployment Guide - [x] Best Practices - [x] TTL on add funds and fuel pre-built transactions - [x] Choice of network: Devnet, Preview -- [ ] How to Contribute +- [x] Default Hydra Node configuration ## 🗝 API diff --git a/hydra-protocol-parameters.json.example b/hydra-protocol-parameters.json.example new file mode 100644 index 0000000..1c16011 --- /dev/null +++ b/hydra-protocol-parameters.json.example @@ -0,0 +1,386 @@ +{ + "collateralPercentage": 150, + "costModels": { + "PlutusScriptV1": { + "addInteger-cpu-arguments-intercept": 197209, + "addInteger-cpu-arguments-slope": 0, + "addInteger-memory-arguments-intercept": 1, + "addInteger-memory-arguments-slope": 1, + "appendByteString-cpu-arguments-intercept": 396231, + "appendByteString-cpu-arguments-slope": 621, + "appendByteString-memory-arguments-intercept": 0, + "appendByteString-memory-arguments-slope": 1, + "appendString-cpu-arguments-intercept": 150000, + "appendString-cpu-arguments-slope": 1000, + "appendString-memory-arguments-intercept": 0, + "appendString-memory-arguments-slope": 1, + "bData-cpu-arguments": 150000, + "bData-memory-arguments": 32, + "blake2b_256-cpu-arguments-intercept": 2477736, + "blake2b_256-cpu-arguments-slope": 29175, + "blake2b_256-memory-arguments": 4, + "cekApplyCost-exBudgetCPU": 29773, + "cekApplyCost-exBudgetMemory": 100, + "cekBuiltinCost-exBudgetCPU": 29773, + "cekBuiltinCost-exBudgetMemory": 100, + "cekConstCost-exBudgetCPU": 29773, + "cekConstCost-exBudgetMemory": 100, + "cekDelayCost-exBudgetCPU": 29773, + "cekDelayCost-exBudgetMemory": 100, + "cekForceCost-exBudgetCPU": 29773, + "cekForceCost-exBudgetMemory": 100, + "cekLamCost-exBudgetCPU": 29773, + "cekLamCost-exBudgetMemory": 100, + "cekStartupCost-exBudgetCPU": 100, + "cekStartupCost-exBudgetMemory": 100, + "cekVarCost-exBudgetCPU": 29773, + "cekVarCost-exBudgetMemory": 100, + "chooseData-cpu-arguments": 150000, + "chooseData-memory-arguments": 32, + "chooseList-cpu-arguments": 150000, + "chooseList-memory-arguments": 32, + "chooseUnit-cpu-arguments": 150000, + "chooseUnit-memory-arguments": 32, + "consByteString-cpu-arguments-intercept": 150000, + "consByteString-cpu-arguments-slope": 1000, + "consByteString-memory-arguments-intercept": 0, + "consByteString-memory-arguments-slope": 1, + "constrData-cpu-arguments": 150000, + "constrData-memory-arguments": 32, + "decodeUtf8-cpu-arguments-intercept": 150000, + "decodeUtf8-cpu-arguments-slope": 1000, + "decodeUtf8-memory-arguments-intercept": 0, + "decodeUtf8-memory-arguments-slope": 8, + "divideInteger-cpu-arguments-constant": 148000, + "divideInteger-cpu-arguments-model-arguments-intercept": 425507, + "divideInteger-cpu-arguments-model-arguments-slope": 118, + "divideInteger-memory-arguments-intercept": 0, + "divideInteger-memory-arguments-minimum": 1, + "divideInteger-memory-arguments-slope": 1, + "encodeUtf8-cpu-arguments-intercept": 150000, + "encodeUtf8-cpu-arguments-slope": 1000, + "encodeUtf8-memory-arguments-intercept": 0, + "encodeUtf8-memory-arguments-slope": 8, + "equalsByteString-cpu-arguments-constant": 150000, + "equalsByteString-cpu-arguments-intercept": 112536, + "equalsByteString-cpu-arguments-slope": 247, + "equalsByteString-memory-arguments": 1, + "equalsData-cpu-arguments-intercept": 150000, + "equalsData-cpu-arguments-slope": 10000, + "equalsData-memory-arguments": 1, + "equalsInteger-cpu-arguments-intercept": 136542, + "equalsInteger-cpu-arguments-slope": 1326, + "equalsInteger-memory-arguments": 1, + "equalsString-cpu-arguments-constant": 1000, + "equalsString-cpu-arguments-intercept": 150000, + "equalsString-cpu-arguments-slope": 1000, + "equalsString-memory-arguments": 1, + "fstPair-cpu-arguments": 150000, + "fstPair-memory-arguments": 32, + "headList-cpu-arguments": 150000, + "headList-memory-arguments": 32, + "iData-cpu-arguments": 150000, + "iData-memory-arguments": 32, + "ifThenElse-cpu-arguments": 1, + "ifThenElse-memory-arguments": 1, + "indexByteString-cpu-arguments": 150000, + "indexByteString-memory-arguments": 1, + "lengthOfByteString-cpu-arguments": 150000, + "lengthOfByteString-memory-arguments": 4, + "lessThanByteString-cpu-arguments-intercept": 103599, + "lessThanByteString-cpu-arguments-slope": 248, + "lessThanByteString-memory-arguments": 1, + "lessThanEqualsByteString-cpu-arguments-intercept": 103599, + "lessThanEqualsByteString-cpu-arguments-slope": 248, + "lessThanEqualsByteString-memory-arguments": 1, + "lessThanEqualsInteger-cpu-arguments-intercept": 145276, + "lessThanEqualsInteger-cpu-arguments-slope": 1366, + "lessThanEqualsInteger-memory-arguments": 1, + "lessThanInteger-cpu-arguments-intercept": 179690, + "lessThanInteger-cpu-arguments-slope": 497, + "lessThanInteger-memory-arguments": 1, + "listData-cpu-arguments": 150000, + "listData-memory-arguments": 32, + "mapData-cpu-arguments": 150000, + "mapData-memory-arguments": 32, + "mkCons-cpu-arguments": 150000, + "mkCons-memory-arguments": 32, + "mkNilData-cpu-arguments": 150000, + "mkNilData-memory-arguments": 32, + "mkNilPairData-cpu-arguments": 150000, + "mkNilPairData-memory-arguments": 32, + "mkPairData-cpu-arguments": 150000, + "mkPairData-memory-arguments": 32, + "modInteger-cpu-arguments-constant": 148000, + "modInteger-cpu-arguments-model-arguments-intercept": 425507, + "modInteger-cpu-arguments-model-arguments-slope": 118, + "modInteger-memory-arguments-intercept": 0, + "modInteger-memory-arguments-minimum": 1, + "modInteger-memory-arguments-slope": 1, + "multiplyInteger-cpu-arguments-intercept": 61516, + "multiplyInteger-cpu-arguments-slope": 11218, + "multiplyInteger-memory-arguments-intercept": 0, + "multiplyInteger-memory-arguments-slope": 1, + "nullList-cpu-arguments": 150000, + "nullList-memory-arguments": 32, + "quotientInteger-cpu-arguments-constant": 148000, + "quotientInteger-cpu-arguments-model-arguments-intercept": 425507, + "quotientInteger-cpu-arguments-model-arguments-slope": 118, + "quotientInteger-memory-arguments-intercept": 0, + "quotientInteger-memory-arguments-minimum": 1, + "quotientInteger-memory-arguments-slope": 1, + "remainderInteger-cpu-arguments-constant": 148000, + "remainderInteger-cpu-arguments-model-arguments-intercept": 425507, + "remainderInteger-cpu-arguments-model-arguments-slope": 118, + "remainderInteger-memory-arguments-intercept": 0, + "remainderInteger-memory-arguments-minimum": 1, + "remainderInteger-memory-arguments-slope": 1, + "sha2_256-cpu-arguments-intercept": 2477736, + "sha2_256-cpu-arguments-slope": 29175, + "sha2_256-memory-arguments": 4, + "sha3_256-cpu-arguments-intercept": 0, + "sha3_256-cpu-arguments-slope": 82363, + "sha3_256-memory-arguments": 4, + "sliceByteString-cpu-arguments-intercept": 150000, + "sliceByteString-cpu-arguments-slope": 5000, + "sliceByteString-memory-arguments-intercept": 0, + "sliceByteString-memory-arguments-slope": 1, + "sndPair-cpu-arguments": 150000, + "sndPair-memory-arguments": 32, + "subtractInteger-cpu-arguments-intercept": 197209, + "subtractInteger-cpu-arguments-slope": 0, + "subtractInteger-memory-arguments-intercept": 1, + "subtractInteger-memory-arguments-slope": 1, + "tailList-cpu-arguments": 150000, + "tailList-memory-arguments": 32, + "trace-cpu-arguments": 150000, + "trace-memory-arguments": 32, + "unBData-cpu-arguments": 150000, + "unBData-memory-arguments": 32, + "unConstrData-cpu-arguments": 150000, + "unConstrData-memory-arguments": 32, + "unIData-cpu-arguments": 150000, + "unIData-memory-arguments": 32, + "unListData-cpu-arguments": 150000, + "unListData-memory-arguments": 32, + "unMapData-cpu-arguments": 150000, + "unMapData-memory-arguments": 32, + "verifyEd25519Signature-cpu-arguments-intercept": 3345831, + "verifyEd25519Signature-cpu-arguments-slope": 1, + "verifyEd25519Signature-memory-arguments": 1 + }, + "PlutusScriptV2": { + "addInteger-cpu-arguments-intercept": 205665, + "addInteger-cpu-arguments-slope": 812, + "addInteger-memory-arguments-intercept": 1, + "addInteger-memory-arguments-slope": 1, + "appendByteString-cpu-arguments-intercept": 1000, + "appendByteString-cpu-arguments-slope": 571, + "appendByteString-memory-arguments-intercept": 0, + "appendByteString-memory-arguments-slope": 1, + "appendString-cpu-arguments-intercept": 1000, + "appendString-cpu-arguments-slope": 24177, + "appendString-memory-arguments-intercept": 4, + "appendString-memory-arguments-slope": 1, + "bData-cpu-arguments": 1000, + "bData-memory-arguments": 32, + "blake2b_256-cpu-arguments-intercept": 117366, + "blake2b_256-cpu-arguments-slope": 10475, + "blake2b_256-memory-arguments": 4, + "cekApplyCost-exBudgetCPU": 23000, + "cekApplyCost-exBudgetMemory": 100, + "cekBuiltinCost-exBudgetCPU": 23000, + "cekBuiltinCost-exBudgetMemory": 100, + "cekConstCost-exBudgetCPU": 23000, + "cekConstCost-exBudgetMemory": 100, + "cekDelayCost-exBudgetCPU": 23000, + "cekDelayCost-exBudgetMemory": 100, + "cekForceCost-exBudgetCPU": 23000, + "cekForceCost-exBudgetMemory": 100, + "cekLamCost-exBudgetCPU": 23000, + "cekLamCost-exBudgetMemory": 100, + "cekStartupCost-exBudgetCPU": 100, + "cekStartupCost-exBudgetMemory": 100, + "cekVarCost-exBudgetCPU": 23000, + "cekVarCost-exBudgetMemory": 100, + "chooseData-cpu-arguments": 19537, + "chooseData-memory-arguments": 32, + "chooseList-cpu-arguments": 175354, + "chooseList-memory-arguments": 32, + "chooseUnit-cpu-arguments": 46417, + "chooseUnit-memory-arguments": 4, + "consByteString-cpu-arguments-intercept": 221973, + "consByteString-cpu-arguments-slope": 511, + "consByteString-memory-arguments-intercept": 0, + "consByteString-memory-arguments-slope": 1, + "constrData-cpu-arguments": 89141, + "constrData-memory-arguments": 32, + "decodeUtf8-cpu-arguments-intercept": 497525, + "decodeUtf8-cpu-arguments-slope": 14068, + "decodeUtf8-memory-arguments-intercept": 4, + "decodeUtf8-memory-arguments-slope": 2, + "divideInteger-cpu-arguments-constant": 196500, + "divideInteger-cpu-arguments-model-arguments-intercept": 453240, + "divideInteger-cpu-arguments-model-arguments-slope": 220, + "divideInteger-memory-arguments-intercept": 0, + "divideInteger-memory-arguments-minimum": 1, + "divideInteger-memory-arguments-slope": 1, + "encodeUtf8-cpu-arguments-intercept": 1000, + "encodeUtf8-cpu-arguments-slope": 28662, + "encodeUtf8-memory-arguments-intercept": 4, + "encodeUtf8-memory-arguments-slope": 2, + "equalsByteString-cpu-arguments-constant": 245000, + "equalsByteString-cpu-arguments-intercept": 216773, + "equalsByteString-cpu-arguments-slope": 62, + "equalsByteString-memory-arguments": 1, + "equalsData-cpu-arguments-intercept": 1060367, + "equalsData-cpu-arguments-slope": 12586, + "equalsData-memory-arguments": 1, + "equalsInteger-cpu-arguments-intercept": 208512, + "equalsInteger-cpu-arguments-slope": 421, + "equalsInteger-memory-arguments": 1, + "equalsString-cpu-arguments-constant": 187000, + "equalsString-cpu-arguments-intercept": 1000, + "equalsString-cpu-arguments-slope": 52998, + "equalsString-memory-arguments": 1, + "fstPair-cpu-arguments": 80436, + "fstPair-memory-arguments": 32, + "headList-cpu-arguments": 43249, + "headList-memory-arguments": 32, + "iData-cpu-arguments": 1000, + "iData-memory-arguments": 32, + "ifThenElse-cpu-arguments": 80556, + "ifThenElse-memory-arguments": 1, + "indexByteString-cpu-arguments": 57667, + "indexByteString-memory-arguments": 4, + "lengthOfByteString-cpu-arguments": 1000, + "lengthOfByteString-memory-arguments": 10, + "lessThanByteString-cpu-arguments-intercept": 197145, + "lessThanByteString-cpu-arguments-slope": 156, + "lessThanByteString-memory-arguments": 1, + "lessThanEqualsByteString-cpu-arguments-intercept": 197145, + "lessThanEqualsByteString-cpu-arguments-slope": 156, + "lessThanEqualsByteString-memory-arguments": 1, + "lessThanEqualsInteger-cpu-arguments-intercept": 204924, + "lessThanEqualsInteger-cpu-arguments-slope": 473, + "lessThanEqualsInteger-memory-arguments": 1, + "lessThanInteger-cpu-arguments-intercept": 208896, + "lessThanInteger-cpu-arguments-slope": 511, + "lessThanInteger-memory-arguments": 1, + "listData-cpu-arguments": 52467, + "listData-memory-arguments": 32, + "mapData-cpu-arguments": 64832, + "mapData-memory-arguments": 32, + "mkCons-cpu-arguments": 65493, + "mkCons-memory-arguments": 32, + "mkNilData-cpu-arguments": 22558, + "mkNilData-memory-arguments": 32, + "mkNilPairData-cpu-arguments": 16563, + "mkNilPairData-memory-arguments": 32, + "mkPairData-cpu-arguments": 76511, + "mkPairData-memory-arguments": 32, + "modInteger-cpu-arguments-constant": 196500, + "modInteger-cpu-arguments-model-arguments-intercept": 453240, + "modInteger-cpu-arguments-model-arguments-slope": 220, + "modInteger-memory-arguments-intercept": 0, + "modInteger-memory-arguments-minimum": 1, + "modInteger-memory-arguments-slope": 1, + "multiplyInteger-cpu-arguments-intercept": 69522, + "multiplyInteger-cpu-arguments-slope": 11687, + "multiplyInteger-memory-arguments-intercept": 0, + "multiplyInteger-memory-arguments-slope": 1, + "nullList-cpu-arguments": 60091, + "nullList-memory-arguments": 32, + "quotientInteger-cpu-arguments-constant": 196500, + "quotientInteger-cpu-arguments-model-arguments-intercept": 453240, + "quotientInteger-cpu-arguments-model-arguments-slope": 220, + "quotientInteger-memory-arguments-intercept": 0, + "quotientInteger-memory-arguments-minimum": 1, + "quotientInteger-memory-arguments-slope": 1, + "remainderInteger-cpu-arguments-constant": 196500, + "remainderInteger-cpu-arguments-model-arguments-intercept": 453240, + "remainderInteger-cpu-arguments-model-arguments-slope": 220, + "remainderInteger-memory-arguments-intercept": 0, + "remainderInteger-memory-arguments-minimum": 1, + "remainderInteger-memory-arguments-slope": 1, + "serialiseData-cpu-arguments-intercept": 1159724, + "serialiseData-cpu-arguments-slope": 392670, + "serialiseData-memory-arguments-intercept": 0, + "serialiseData-memory-arguments-slope": 2, + "sha2_256-cpu-arguments-intercept": 806990, + "sha2_256-cpu-arguments-slope": 30482, + "sha2_256-memory-arguments": 4, + "sha3_256-cpu-arguments-intercept": 1927926, + "sha3_256-cpu-arguments-slope": 82523, + "sha3_256-memory-arguments": 4, + "sliceByteString-cpu-arguments-intercept": 265318, + "sliceByteString-cpu-arguments-slope": 0, + "sliceByteString-memory-arguments-intercept": 4, + "sliceByteString-memory-arguments-slope": 0, + "sndPair-cpu-arguments": 85931, + "sndPair-memory-arguments": 32, + "subtractInteger-cpu-arguments-intercept": 205665, + "subtractInteger-cpu-arguments-slope": 812, + "subtractInteger-memory-arguments-intercept": 1, + "subtractInteger-memory-arguments-slope": 1, + "tailList-cpu-arguments": 41182, + "tailList-memory-arguments": 32, + "trace-cpu-arguments": 212342, + "trace-memory-arguments": 32, + "unBData-cpu-arguments": 31220, + "unBData-memory-arguments": 32, + "unConstrData-cpu-arguments": 32696, + "unConstrData-memory-arguments": 32, + "unIData-cpu-arguments": 43357, + "unIData-memory-arguments": 32, + "unListData-cpu-arguments": 32247, + "unListData-memory-arguments": 32, + "unMapData-cpu-arguments": 38314, + "unMapData-memory-arguments": 32, + "verifyEcdsaSecp256k1Signature-cpu-arguments": 35892428, + "verifyEcdsaSecp256k1Signature-memory-arguments": 10, + "verifyEd25519Signature-cpu-arguments-intercept": 9462713, + "verifyEd25519Signature-cpu-arguments-slope": 1021, + "verifyEd25519Signature-memory-arguments": 10, + "verifySchnorrSecp256k1Signature-cpu-arguments-intercept": 38887044, + "verifySchnorrSecp256k1Signature-cpu-arguments-slope": 32947, + "verifySchnorrSecp256k1Signature-memory-arguments": 10 + } + }, + "decentralization": null, + "executionUnitPrices": { + "priceMemory": 5.77e-2, + "priceSteps": 7.21e-5 + }, + "extraPraosEntropy": null, + "maxBlockBodySize": 65536, + "maxBlockExecutionUnits": { + "memory": 80000000, + "steps": 40000000000 + }, + "maxBlockHeaderSize": 1100, + "maxCollateralInputs": 3, + "maxTxExecutionUnits": { + "memory": 16000000, + "steps": 10000000000 + }, + "maxTxSize": 16384, + "maxValueSize": 5000, + "minPoolCost": 0, + "minUTxOValue": null, + "monetaryExpansion": 1.78650067e-3, + "poolPledgeInfluence": 0.1, + "poolRetireMaxEpoch": 18, + "protocolVersion": { + "major": 7, + "minor": 0 + }, + "stakeAddressDeposit": 400000, + "stakePoolDeposit": 500000000, + "stakePoolTargetNum": 50, + "treasuryCut": 0.1, + "txFeeFixed": 0, + "txFeePerByte": 0, + "utxoCostPerWord": 34488, + "utxoCostPerByte": 4310 +} From bb7d5800719580d89fd4b465d4dcc9419ed15178 Mon Sep 17 00:00:00 2001 From: Skylar-Ray O'Quinn Date: Wed, 21 Dec 2022 19:05:12 +0000 Subject: [PATCH 2/5] Update API in README --- README.md | 144 +++++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 110 insertions(+), 34 deletions(-) diff --git a/README.md b/README.md index ee42778..f1c801d 100644 --- a/README.md +++ b/README.md @@ -17,6 +17,8 @@ This will cover: * Fanout * A real-world example application +We assume at this time you are knowledgeable about Hydra and the basic Hydra Head lifecycle. If not take some time to familiarize yourself with [here](https://hydra.family/head-protocol/core-concepts/). + ## 👷🏾‍♂️ Running Hydra Pay Hydra Pay can be ran via Docker or Nix. @@ -226,7 +228,6 @@ Information might include a Head changing state, an error or failure, a restart This allows Light Wallet and DApp developers to have their implementation react and respond to these issues in a timely and automatic way. Example Subscription: - ``` json { "contents": "test", @@ -237,19 +238,32 @@ Example Subscription: Example Response: ``` json { - "contents": "test", - "tag": "SubscriptionStarted" + "tag": "SubscriptionStarted", + "contents": { + "headStatus_name": "test", + "headStatus_balances": [], + "headStatus_running": true, + "headStatus_status": "Status_Pending" + } } ``` - ### Authentication When you launch or deploy a Hydra Pay instance you will need to provide an API Key to authenticate against, this is a secret that should be only known to your DApp/LightWallet and your Hydra Pay instance. Upon opening a websocket connection to your HydraPay instance, you should immediately Authenticate by sending a Tagged `Authenticate` request (see below). -### Request and Response Payloads +### Errors and Error Messages + +Hydra Pay manages state and does its best to communicate when you issue API requests that are not at appropriate times, or would have no meaning in the current state. When this happens you are likely to get responses like the following: + +``` json +{ "tag": "ApiError", "contents": ""Head is closing, please wait for the contestation period to be over and the fanout to complete." } +``` +This error message was generated when trying to remove/terminate a head while the nodes are fanning out funds. + +### Request and Response API Here is a list of request/response payloads. Remember that you must Tag (see above), these payloads when communicating with the Server. @@ -275,7 +289,7 @@ This will use the API Key you set up when you deployed the Server. { "tag": "Authenticate", "contents": "KbYei/+ymqAeqgXCiS+pfn88xMkkfXHhe8d/YHU3kGM=" } ``` -Example Response: +Expected Response: ``` json { "tag": "AuthResult", "contents": true } ``` @@ -288,11 +302,11 @@ Creating the head starts the Hydra network. Example payload: ``` json { + "tag": "CreateHead", "contents": { - "headCreate_participants": ["addr_test1thisaddressisobviouslyinvaliddonotusethisaddressplease"], - "headCreate_name": "test" - }, - "tag": "CreateHead" + "headCreate_name": "test", + "headCreate_participants": ["addr_test1thisaddressisobviouslyinvaliddonotusethisaddressplease"] + } } ``` @@ -303,23 +317,48 @@ Expected Response: } ``` +#### Subscribing to State Changes + +A lot of the time the logic for your DApp or Light Wallet will include waiting for certain state changes to take place. To be convenient for developers and to avoid unecessary complications and resource usage of polling, you can subscribe to state changes of certain heads. If you create a head you should subscribe to it as well. + +Example payload: + +``` json +{ + "tag": "SubscribeTo", + "contents": "test" +} +``` + +Example response: +``` json +{ + "tag": "SubscriptionStarted", + "contents": { + "headStatus_name": "test", + "headStatus_balances": [], + "headStatus_running": true, + "headStatus_status": "Status_Pending" + } +} +``` + #### Head Init -Post the inital state of your Head on chain, and start waiting for Commitments from the participants. +This creates an L1 transaction (using fuel given to a Proxy Address) that places the initial head state on chain. Example Payload: ``` json { + "tag": "InitHead", "contents": { "headInit_name": "test", "headInit_contestation": 3 - }, - "tag": "InitHead" + } } ``` Expected Response: - ``` json { "tag": "OperationSuccess" @@ -364,16 +403,44 @@ Expected Response: ``` -#### Add Funds +#### Proxy Address Information -Get a CIP-30 compatible CBOR transaction that will fund your Proxy Address. +Sometimes you want to inspect or be aware of the Proxy Address' funds and fuel, maybe to automate filling those up in your business logic. The Proxy Info includes the address of the proxy address, and the balance and fuel of that proxy address. + +Example payload: +``` json +{ + "tag": "GetProxyInfo", + "contents": "addr_test1thisaddressisobviouslyinvaliddonotusethisaddressplease" +} +``` + +Example response: +``` json +{ + "tag": "ProxyAddressInfo", + "contents": { + "proxyInfo_address": "addr_test1thisaddressisobviouslyinvaliddonotusethisaddressplease", + "proxyInfo_proxyAddress": "addr_test1thisaddressisobviouslyinvaliddonotusethisaddressplease", + "proxyInfo_fuel": 50000000, + "proxyInfo_balance": 50000000 + } +} +``` + +#### Funding Proxy Addresses | Funds & Fuel +To participate in a Hydra Pay managed Head you need to transfer funds from your address to your Proxy Address. You must transfer both regular Ada and a specially tagged Fuel transaction yourself. + +For your convenience Hydra Pay provides endpoints which return draft transactions for both types of funds. However, you yourself must sign and submit these transactions with the signing key for your address. + +To get a CIP-30 compatible CBOR transaction that will fund your Proxy Address: Example Payload: ``` json { "contents": [ "Funds", - "", + "addr_test1thisaddressisobviouslyinvaliddonotusethisaddressplease", 100000000 ], "tag": "GetAddTx" @@ -383,16 +450,16 @@ Example Payload: Example Response: ``` json { + "tag": "FundsTx", "contents": { - "type": "Unwitnessed Tx BabbageEra", "cborHex": "Ledger Cddl Format", + "type": "Unwitnessed Tx BabbageEra", "description": "84a3008182582005bbe2c33e4bd787a8778b63bfbf007fae7b47b8153e75586df0ab59936d6c3c000182a300581d60e04a63ce5112f1b75c66a13375daf937e5ed9177caa8e9536392119f011a002dc6c00282005820a654fb60d21c1fed48db2c320aa6df9737ec0204c0ba53b9b94a09fb40e757f3a200581d60d31a9209c0da931b7e72f45bc612dc85fae49249619f5f80639d2f50011b0000000253db8f8b021a00028db5a0f5f6" - }, - "tag": "FundsTx" + } } ``` -#### Add Fuel +#### Adding Fuel to a Proxy Addresses | Funds & Fuel Get a CIP-30 compatible CBOR transaction that will create a Fuel UTXO at your Proxy Address. @@ -401,29 +468,28 @@ Example Payload: { "contents": [ "Fuel", - "", + "addr_test1thisaddressisobviouslyinvaliddonotusethisaddressplease", 100000000 ], "tag": "GetAddTx" } ``` - -Example Response: +Example response: ``` json { + "tag": "FundsTx", "contents": { - "type": "Unwitnessed Tx BabbageEra", "cborHex": "Ledger Cddl Format", + "type": "Unwitnessed Tx BabbageEra", "description": "84a3008182582005bbe2c33e4bd787a8778b63bfbf007fae7b47b8153e75586df0ab59936d6c3c000182a300581d60e04a63ce5112f1b75c66a13375daf937e5ed9177caa8e9536392119f011a002dc6c00282005820a654fb60d21c1fed48db2c320aa6df9737ec0204c0ba53b9b94a09fb40e757f3a200581d60d31a9209c0da931b7e72f45bc612dc85fae49249619f5f80639d2f50011b0000000253db8f8b021a00028db5a0f5f6" - }, - "tag": "FundsTx" + } } ``` -#### Send funds on Head +#### Transaction in a Hydra Head -Send funds from your Proxy Address to another participant identified by their L1 Address. +Once a Head is Open (all participants have commited UTxOs), you are free to move funds around within the head by creating transactions. Example Payload: ``` json @@ -432,7 +498,7 @@ Example Payload: "", { "headSubmitTx_name": "test", - "headSubmitTx_toAddr": "", + "headSubmitTx_toAddr": "addr_test1thisaddressisobviouslyinvaliddonotusethisaddressplease", "amount": 3000000 } ], @@ -440,9 +506,17 @@ Example Payload: } ``` -#### Close +``` json +{ + "tag": "TxConfirmed", + "contents": 1.0e-3 +} +``` +The contents are an amount in seconds that it took to complete the transaction (full roundtrip). + +#### Closing a Head -Close the head. +After you have done all the transactions you needed to in the Hydra Head, you can close it and when Hydra Pay detects the Fanout period has occurred, it will Fanout your Head for you Automatically. Example Payload: ``` json @@ -460,7 +534,7 @@ Example Response: ``` -#### Withdraw +#### Withdraw from a Proxy Address Withdraw funds from your Proxy Address to your main address. Takes the Proxy Address and a boolean determining whether to withdraw fuel as well. @@ -479,9 +553,11 @@ Example Payload: Example Response: ``` json { - "tag": "OperationSuccess" + "tag": "WithdrawSubmitted", + "contents": "e174c1033009de66ccc577743ae4542c9d5e6c8220acfcd55c1c4cf330b7ca04" } ``` +The contents are a txid you can track on a block explorer like cardanoscan. ## 🤔 FAQ From 34c45cbdcac235fe979510bfe75d2f7d95fd6a2a Mon Sep 17 00:00:00 2001 From: Skylar-Ray O'Quinn Date: Wed, 21 Dec 2022 19:21:01 +0000 Subject: [PATCH 3/5] Add ChangeLog --- ChangeLog.md | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) create mode 100644 ChangeLog.md diff --git a/ChangeLog.md b/ChangeLog.md new file mode 100644 index 0000000..674a5b2 --- /dev/null +++ b/ChangeLog.md @@ -0,0 +1,22 @@ +# Revision History for Hydra Pay + +This project's release branch is `master`. This log is written from the perspective of the release branch: when changes hit `master`, they are considered released. + +## Unreleased + +* Automated spin-up and shut down of Hydra Node networks +* Proxy addresses to streamline fund managment and enforce security invariants +* Static nix binaries for deployment +* Docker image for alternative deployment +* Request/Response Websocket API for Head management +* Live Documentation for education and testing of all Hydra Pay API requests +* Mutliplexed Websocket realtime status information +* Manged devnet creation and funding, with automatic transaction submitting +* Capability for running on Preview (tested) +* CIP-30 compatible Transaction generation for use in Light Wallets +* Proxy address key management +* Automatic Proxy Address generation and mapping +* Script to automate Docker Deployment +* Head transaction speed measurements +* Deep error propagation: From internal nodes and processes out to API messages + From 4eb84c39a7b1469d4e5e96cc886384871758e46e Mon Sep 17 00:00:00 2001 From: Skylar-Ray O'Quinn Date: Thu, 22 Dec 2022 02:51:35 +0000 Subject: [PATCH 4/5] Fix typos --- ChangeLog.md | 2 +- README.md | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/ChangeLog.md b/ChangeLog.md index 674a5b2..a8b13c1 100644 --- a/ChangeLog.md +++ b/ChangeLog.md @@ -11,7 +11,7 @@ This project's release branch is `master`. This log is written from the perspect * Request/Response Websocket API for Head management * Live Documentation for education and testing of all Hydra Pay API requests * Mutliplexed Websocket realtime status information -* Manged devnet creation and funding, with automatic transaction submitting +* Managed devnet creation and funding, with automatic transaction submitting * Capability for running on Preview (tested) * CIP-30 compatible Transaction generation for use in Light Wallets * Proxy address key management diff --git a/README.md b/README.md index f1c801d..070b638 100644 --- a/README.md +++ b/README.md @@ -110,7 +110,7 @@ Hydra in part works by using a Plutus smart contract on L1 and that contract mus #### Hydra Protocol Parameters -Just like a Cardano Node, Hydra Nodes have a set of protocol parameters to control various aspects of the Node and the Network. However the Hydra Node doesn't need to (and usually shouldn't) use the same protocol parameters of the Cardano Node. If you don't know the exact protocol parameters you want, we recommend using the parameters found in hydra-protocol-parameters.json.example in this repo, the give a reasonable default to compliment the benefits of Hydra. +Just like a Cardano Node, Hydra Nodes have a set of protocol parameters to control various aspects of the Node and the Network. However the Hydra Node doesn't need to (and usually shouldn't) use the same protocol parameters of the Cardano Node. If you don't know the exact protocol parameters you want, we recommend using the parameters found in hydra-protocol-parameters.json.example in this repo, they give a reasonable default to compliment the benefits of Hydra. #### Run configuration for Preview @@ -319,7 +319,7 @@ Expected Response: #### Subscribing to State Changes -A lot of the time the logic for your DApp or Light Wallet will include waiting for certain state changes to take place. To be convenient for developers and to avoid unecessary complications and resource usage of polling, you can subscribe to state changes of certain heads. If you create a head you should subscribe to it as well. +A lot of the time the logic for your DApp or Light Wallet will include waiting for certain state changes to take place. To be convenient for developers and to avoid unnecessary complications and resource usage of polling, you can subscribe to state changes of certain heads. If you create a head you should subscribe to it as well. Example payload: From 9b5d627f69e729060105c16bde4781307d087089 Mon Sep 17 00:00:00 2001 From: Skylar-Ray O'Quinn Date: Fri, 23 Dec 2022 19:05:55 +0000 Subject: [PATCH 5/5] Fix incorrect quoting --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 070b638..3ba1954 100644 --- a/README.md +++ b/README.md @@ -259,7 +259,7 @@ Upon opening a websocket connection to your HydraPay instance, you should immedi Hydra Pay manages state and does its best to communicate when you issue API requests that are not at appropriate times, or would have no meaning in the current state. When this happens you are likely to get responses like the following: ``` json -{ "tag": "ApiError", "contents": ""Head is closing, please wait for the contestation period to be over and the fanout to complete." } +{ "tag": "ApiError", "contents": "Head is closing, please wait for the contestation period to be over and the fanout to complete." } ``` This error message was generated when trying to remove/terminate a head while the nodes are fanning out funds.