From 7840715559376820c09491e5073b1dfd1fb17b68 Mon Sep 17 00:00:00 2001 From: Jerry Date: Sat, 27 Jul 2024 16:30:27 -0700 Subject: [PATCH 01/44] Chang initial commit --- integration-test/bootstrap.sh | 2 +- .../configs/local-chang/alonzo-genesis.json | 365 ++++++++++++++++++ .../configs/local-chang/byron-genesis.json | 40 ++ .../configs/local-chang/byron/delegate.cert | 8 + .../configs/local-chang/byron/delegate.key | Bin 0 -> 130 bytes .../configs/local-chang/config.json | 106 +++++ .../configs/local-chang/conway-genesis.json | 298 ++++++++++++++ .../configs/local-chang/shelley-genesis.json | 50 +++ .../configs/local-chang/shelley/kes.skey | 5 + .../configs/local-chang/shelley/kes.vkey | 5 + .../configs/local-chang/shelley/node.cert | 5 + .../local-chang/shelley/operator.counter | 5 + .../configs/local-chang/shelley/operator.skey | 5 + .../configs/local-chang/shelley/operator.vkey | 5 + .../shelley/utxo-keys/payment.addr | 1 + .../local-chang/shelley/utxo-keys/utxo1.skey | 5 + .../local-chang/shelley/utxo-keys/utxo1.vkey | 5 + .../configs/local-chang/shelley/vrf.skey | 5 + .../configs/local-chang/shelley/vrf.vkey | 5 + .../configs/local-chang/topology.json | 9 + integration-test/docker-compose-chang.yml | 103 +++++ integration-test/docker-compose.yml | 4 + .../plutus_scripts/helloworldV3.plutus | 1 + integration-test/run_node.sh | 2 +- integration-test/run_pool.sh | 6 +- integration-test/run_tests.sh | 78 ++-- integration-test/test/base.py | 54 ++- integration-test/test/test_cardano_cli.py | 2 + integration-test/test/test_plutus.py | 75 +++- pycardano/backend/base.py | 6 +- pycardano/metadata.py | 9 +- pycardano/plutus.py | 9 + pycardano/txbuilder.py | 48 ++- pycardano/utils.py | 49 ++- pycardano/witness.py | 20 +- pyproject.toml | 3 +- test/pycardano/test_metadata.py | 9 +- test/pycardano/util.py | 2 + 38 files changed, 1350 insertions(+), 59 deletions(-) create mode 100644 integration-test/configs/local-chang/alonzo-genesis.json create mode 100644 integration-test/configs/local-chang/byron-genesis.json create mode 100644 integration-test/configs/local-chang/byron/delegate.cert create mode 100644 integration-test/configs/local-chang/byron/delegate.key create mode 100644 integration-test/configs/local-chang/config.json create mode 100644 integration-test/configs/local-chang/conway-genesis.json create mode 100644 integration-test/configs/local-chang/shelley-genesis.json create mode 100644 integration-test/configs/local-chang/shelley/kes.skey create mode 100644 integration-test/configs/local-chang/shelley/kes.vkey create mode 100644 integration-test/configs/local-chang/shelley/node.cert create mode 100644 integration-test/configs/local-chang/shelley/operator.counter create mode 100644 integration-test/configs/local-chang/shelley/operator.skey create mode 100644 integration-test/configs/local-chang/shelley/operator.vkey create mode 100644 integration-test/configs/local-chang/shelley/utxo-keys/payment.addr create mode 100644 integration-test/configs/local-chang/shelley/utxo-keys/utxo1.skey create mode 100644 integration-test/configs/local-chang/shelley/utxo-keys/utxo1.vkey create mode 100644 integration-test/configs/local-chang/shelley/vrf.skey create mode 100644 integration-test/configs/local-chang/shelley/vrf.vkey create mode 100644 integration-test/configs/local-chang/topology.json create mode 100644 integration-test/docker-compose-chang.yml create mode 100644 integration-test/plutus_scripts/helloworldV3.plutus diff --git a/integration-test/bootstrap.sh b/integration-test/bootstrap.sh index 5f7ac89c..be5f865f 100755 --- a/integration-test/bootstrap.sh +++ b/integration-test/bootstrap.sh @@ -20,7 +20,7 @@ NETWORK=$1 echo "Bootstrapping network: $NETWORK" -if [ "$NETWORK" = "local-alonzo" ] || [ "$NETWORK" = "local-vasil" ]; then +if [ "$NETWORK" = "local-alonzo" ] || [ "$NETWORK" = "local-vasil" ] || [ "$NETWORK" = "local-chang" ]; then echo "Updating byron startTime to present in local mode, $NETWORK era" jq -M ".startTime = ""$(date +%s)" configs/"$NETWORK"/byron-genesis.json > \ tmp_configs/"$NETWORK"/byron-genesis.json diff --git a/integration-test/configs/local-chang/alonzo-genesis.json b/integration-test/configs/local-chang/alonzo-genesis.json new file mode 100644 index 00000000..643a7810 --- /dev/null +++ b/integration-test/configs/local-chang/alonzo-genesis.json @@ -0,0 +1,365 @@ +{ + "collateralPercentage": 150, + "costModels": { + "PlutusV1": [ + 197209, + 0, + 1, + 1, + 396231, + 621, + 0, + 1, + 150000, + 1000, + 0, + 1, + 150000, + 32, + 2477736, + 29175, + 4, + 29773, + 100, + 29773, + 100, + 29773, + 100, + 29773, + 100, + 29773, + 100, + 29773, + 100, + 100, + 100, + 29773, + 100, + 150000, + 32, + 150000, + 32, + 150000, + 32, + 150000, + 1000, + 0, + 1, + 150000, + 32, + 150000, + 1000, + 0, + 8, + 148000, + 425507, + 118, + 0, + 1, + 1, + 150000, + 1000, + 0, + 8, + 150000, + 112536, + 247, + 1, + 150000, + 10000, + 1, + 136542, + 1326, + 1, + 1000, + 150000, + 1000, + 1, + 150000, + 32, + 150000, + 32, + 150000, + 32, + 1, + 1, + 150000, + 1, + 150000, + 4, + 103599, + 248, + 1, + 103599, + 248, + 1, + 145276, + 1366, + 1, + 179690, + 497, + 1, + 150000, + 32, + 150000, + 32, + 150000, + 32, + 150000, + 32, + 150000, + 32, + 150000, + 32, + 148000, + 425507, + 118, + 0, + 1, + 1, + 61516, + 11218, + 0, + 1, + 150000, + 32, + 148000, + 425507, + 118, + 0, + 1, + 1, + 148000, + 425507, + 118, + 0, + 1, + 1, + 2477736, + 29175, + 4, + 0, + 82363, + 4, + 150000, + 5000, + 0, + 1, + 150000, + 32, + 197209, + 0, + 1, + 1, + 150000, + 32, + 150000, + 32, + 150000, + 32, + 150000, + 32, + 150000, + 32, + 150000, + 32, + 150000, + 32, + 3345831, + 1, + 1 + ], + "PlutusV2": { + "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": 20000000000, + "verifyEcdsaSecp256k1Signature-memory-arguments": 20000000000, + "verifyEd25519Signature-cpu-arguments-intercept": 9462713, + "verifyEd25519Signature-cpu-arguments-slope": 1021, + "verifyEd25519Signature-memory-arguments": 10, + "verifySchnorrSecp256k1Signature-cpu-arguments-intercept": 20000000000, + "verifySchnorrSecp256k1Signature-cpu-arguments-slope": 0, + "verifySchnorrSecp256k1Signature-memory-arguments": 20000000000 + } + }, + "executionPrices": { + "prMem": 0.0577, + "prSteps": 0.0000721 + }, + "lovelacePerUTxOWord": 34482, + "maxBlockExUnits": { + "exUnitsMem": 50000000, + "exUnitsSteps": 40000000000 + }, + "maxCollateralInputs": 3, + "maxTxExUnits": { + "exUnitsMem": 10000000, + "exUnitsSteps": 10000000000 + }, + "maxValueSize": 5000 +} \ No newline at end of file diff --git a/integration-test/configs/local-chang/byron-genesis.json b/integration-test/configs/local-chang/byron-genesis.json new file mode 100644 index 00000000..6eaa8b49 --- /dev/null +++ b/integration-test/configs/local-chang/byron-genesis.json @@ -0,0 +1,40 @@ +{ "bootStakeholders": + { "b733bf8070781d30a0c8d5ca66392188f78c6604b631629cd055f402": 1 } +, "heavyDelegation": + { "b733bf8070781d30a0c8d5ca66392188f78c6604b631629cd055f402": + { "omega": 0 + , "issuerPk": + "ckPV1Ypq8uRkxwoDj93p7cCm4G+uB9R8SGGOKyc6KyIR8NDVVwu1FS3AwSoUjra02uiF5AlAUXUvVqZvnT8nCw==" + , "delegatePk": + "MYL9xuLMepgsQxRtqOu57nJw16pMWel79j0APRV1NSqH3ZUeBu+p7XaNoVCzw7yemMb4vwLiRDcMnnqHXztFVA==" + , "cert": + "643985a3022fedf3d9aaee8ab18d35e0cdc894beb5edb502ca47c37cce678741dd502fba0c2b8ee38513e0a75f6ee2dcc0f05d5b3c1d7ce72cc1c22a8a910909" + } } +, "startTime": 1640212228 +, "nonAvvmBalances": + { "2657WMsDfac6ef4bngGRU7FmksmW8QRfAifshdj4XyDxPeVT4DbPeoiUgzRdKjYYF": + "10020000000" } +, "blockVersionData": + { "scriptVersion": 0 + , "slotDuration": "1000" + , "maxBlockSize": "2000000" + , "maxHeaderSize": "2000000" + , "maxTxSize": "4096" + , "maxProposalSize": "700" + , "mpcThd": "20000000000000" + , "heavyDelThd": "300000000000" + , "updateVoteThd": "1000000000000" + , "updateProposalThd": "100000000000000" + , "updateImplicit": "10000" + , "softforkRule": + { "initThd": "900000000000000" + , "minThd": "600000000000000" + , "thdDecrement": "50000000000000" + } + , "txFeePolicy": + { "summand": "155381000000000" , "multiplier": "43946000000" } + , "unlockStakeEpoch": "18446744073709551615" + } +, "protocolConsts": { "k": 10 , "protocolMagic": 42 } +, "avvmDistr": {} +} \ No newline at end of file diff --git a/integration-test/configs/local-chang/byron/delegate.cert b/integration-test/configs/local-chang/byron/delegate.cert new file mode 100644 index 00000000..dcdd366a --- /dev/null +++ b/integration-test/configs/local-chang/byron/delegate.cert @@ -0,0 +1,8 @@ +{ "omega": 0 +, "issuerPk": + "ckPV1Ypq8uRkxwoDj93p7cCm4G+uB9R8SGGOKyc6KyIR8NDVVwu1FS3AwSoUjra02uiF5AlAUXUvVqZvnT8nCw==" +, "delegatePk": + "MYL9xuLMepgsQxRtqOu57nJw16pMWel79j0APRV1NSqH3ZUeBu+p7XaNoVCzw7yemMb4vwLiRDcMnnqHXztFVA==" +, "cert": + "643985a3022fedf3d9aaee8ab18d35e0cdc894beb5edb502ca47c37cce678741dd502fba0c2b8ee38513e0a75f6ee2dcc0f05d5b3c1d7ce72cc1c22a8a910909" +} \ No newline at end of file diff --git a/integration-test/configs/local-chang/byron/delegate.key b/integration-test/configs/local-chang/byron/delegate.key new file mode 100644 index 0000000000000000000000000000000000000000..87e9c504c50013813414d19668726670cf17ffd8 GIT binary patch literal 130 zcmV-|0Db>hfSBn9`|!X8rQx69kXQzMKn-B0mNyC_3$K`i5n-QYN!}uv7;b9tQ8J?RJf!P_x6lo|wk?zXIY!Hw>P7hhIBIRR7&SN&o-= literal 0 HcmV?d00001 diff --git a/integration-test/configs/local-chang/config.json b/integration-test/configs/local-chang/config.json new file mode 100644 index 00000000..d5f44b21 --- /dev/null +++ b/integration-test/configs/local-chang/config.json @@ -0,0 +1,106 @@ +{ + "ByronGenesisFile": "./byron-genesis.json", + "ShelleyGenesisFile": "./shelley-genesis.json", + "AlonzoGenesisFile": "./alonzo-genesis.json", + "ConwayGenesisFile": "./conway-genesis.json", + "SocketPath": "db/node.socket", + "Protocol": "Cardano", + "PBftSignatureThreshold": 0.6, + "RequiresNetworkMagic": "RequiresMagic", + "LastKnownBlockVersion-Alt": 0, + "LastKnownBlockVersion-Major": 3, + "LastKnownBlockVersion-Minor": 1, + "ApplicationName": "cardano-sl", + "MinNodeVersion": "9.0", + "ApplicationVersion": 1, + "TurnOnLogging": true, + "TurnOnLogMetrics": true, + "minSeverity": "Debug", + "TracingVerbosity": "NormalVerbosity", + "setupBackends": [ + "KatipBK" + ], + "defaultBackends": [ + "KatipBK" + ], + "setupScribes": [ + { + "scKind": "FileSK", + "scName": "logs/mainnet.log", + "scFormat": "ScText" + }, + { + "scKind": "StdoutSK", + "scName": "stdout", + "scFormat": "ScText" + } + ], + "defaultScribes": [ + [ + "FileSK", + "logs/mainnet.log" + ], + [ + "StdoutSK", + "stdout" + ] + ], + "rotation": { + "rpLogLimitBytes": 5000000, + "rpKeepFilesNum": 3, + "rpMaxAgeHours": 24 + }, + "TraceBlockFetchClient": false, + "TraceBlockFetchDecisions": false, + "TraceBlockFetchProtocol": false, + "TraceBlockFetchProtocolSerialised": false, + "TraceBlockFetchServer": false, + "TraceBlockchainTime": false, + "TraceChainDb": true, + "TraceChainSyncClient": false, + "TraceChainSyncBlockServer": false, + "TraceChainSyncHeaderServer": false, + "TraceChainSyncProtocol": false, + "TraceDNSResolver": true, + "TraceDNSSubscription": true, + "TraceErrorPolicy": true, + "TraceLocalErrorPolicy": true, + "TraceForge": true, + "TraceHandshake": false, + "TraceIpSubscription": true, + "TraceLocalChainSyncProtocol": false, + "TraceLocalHandshake": false, + "TraceLocalTxSubmissionProtocol": false, + "TraceLocalTxSubmissionServer": false, + "TraceMempool": true, + "TraceMux": false, + "TraceTxInbound": false, + "TraceTxOutbound": false, + "TraceTxSubmissionProtocol": false, + "options": { + "mapBackends": { + "cardano.node.metrics": [ + "EKGViewBK" + ] + }, + "mapScribes": { + "cardano.node.metrics": [ + "FileSK::logs/mainnet.log" + ] + }, + "mapSeverity": { + "cardano.node.ChainDB": "Notice", + "cardano.node.DnsSubscription": "Debug" + } + }, + "EnableLogMetrics": false, + "EnableLogging": true, + "TestShelleyHardForkAtEpoch": 0, + "TestAllegraHardForkAtEpoch": 0, + "TestMaryHardForkAtEpoch": 0, + "TestAlonzoHardForkAtEpoch": 0, + "TestBabbageHardForkAtEpoch": 10, + "TestConwayHardForkAtEpoch": 11, + "EnableDevelopmentHardForkEras": true, + "ExperimentalProtocolsEnabled": true +} \ No newline at end of file diff --git a/integration-test/configs/local-chang/conway-genesis.json b/integration-test/configs/local-chang/conway-genesis.json new file mode 100644 index 00000000..61598cba --- /dev/null +++ b/integration-test/configs/local-chang/conway-genesis.json @@ -0,0 +1,298 @@ +{ + "poolVotingThresholds": { + "committeeNormal": 0.65, + "committeeNoConfidence": 0.65, + "hardForkInitiation": 0.51, + "motionNoConfidence": 0.6, + "ppSecurityGroup": 0.6 + }, + "dRepVotingThresholds": { + "motionNoConfidence": 0.67, + "committeeNormal": 0.67, + "committeeNoConfidence": 0.65, + "updateToConstitution": 0.75, + "hardForkInitiation": 0.6, + "ppNetworkGroup": 0.67, + "ppEconomicGroup": 0.67, + "ppTechnicalGroup": 0.67, + "ppGovGroup": 0.75, + "treasuryWithdrawal": 0.67 + }, + "committeeMinSize": 5, + "committeeMaxTermLength": 146, + "govActionLifetime": 14, + "govActionDeposit": 100000000000, + "dRepDeposit": 500000000, + "dRepActivity": 20, + "minFeeRefScriptCostPerByte": 15, + "plutusV3CostModel": [ + 100788, + 420, + 1, + 1, + 1000, + 173, + 0, + 1, + 1000, + 59957, + 4, + 1, + 11183, + 32, + 201305, + 8356, + 4, + 16000, + 100, + 16000, + 100, + 16000, + 100, + 16000, + 100, + 16000, + 100, + 16000, + 100, + 100, + 100, + 16000, + 100, + 94375, + 32, + 132994, + 32, + 61462, + 4, + 72010, + 178, + 0, + 1, + 22151, + 32, + 91189, + 769, + 4, + 2, + 85848, + 123203, + 7305, + -900, + 1716, + 549, + 57, + 85848, + 0, + 1, + 1, + 1000, + 42921, + 4, + 2, + 24548, + 29498, + 38, + 1, + 898148, + 27279, + 1, + 51775, + 558, + 1, + 39184, + 1000, + 60594, + 1, + 141895, + 32, + 83150, + 32, + 15299, + 32, + 76049, + 1, + 13169, + 4, + 22100, + 10, + 28999, + 74, + 1, + 28999, + 74, + 1, + 43285, + 552, + 1, + 44749, + 541, + 1, + 33852, + 32, + 68246, + 32, + 72362, + 32, + 7243, + 32, + 7391, + 32, + 11546, + 32, + 85848, + 123203, + 7305, + -900, + 1716, + 549, + 57, + 85848, + 0, + 1, + 90434, + 519, + 0, + 1, + 74433, + 32, + 85848, + 123203, + 7305, + -900, + 1716, + 549, + 57, + 85848, + 0, + 1, + 1, + 85848, + 123203, + 7305, + -900, + 1716, + 549, + 57, + 85848, + 0, + 1, + 955506, + 213312, + 0, + 2, + 270652, + 22588, + 4, + 1457325, + 64566, + 4, + 20467, + 1, + 4, + 0, + 141992, + 32, + 100788, + 420, + 1, + 1, + 81663, + 32, + 59498, + 32, + 20142, + 32, + 24588, + 32, + 20744, + 32, + 25933, + 32, + 24623, + 32, + 43053543, + 10, + 53384111, + 14333, + 10, + 43574283, + 26308, + 10, + 16000, + 100, + 16000, + 100, + 962335, + 18, + 2780678, + 6, + 442008, + 1, + 52538055, + 3756, + 18, + 267929, + 18, + 76433006, + 8868, + 18, + 52948122, + 18, + 1995836, + 36, + 3227919, + 12, + 901022, + 1, + 166917843, + 4307, + 36, + 284546, + 36, + 158221314, + 26549, + 36, + 74698472, + 36, + 333849714, + 1, + 254006273, + 72, + 2174038, + 72, + 2261318, + 64571, + 4, + 207616, + 8310, + 4, + 1293828, + 28716, + 63, + 0, + 1, + 1006041, + 43623, + 251, + 0, + 1 + ], + "constitution": { + "anchor": { + "url": "ipfs://QmQq5hWDNzvDR1ForEktAHrdCQmfSL2u5yctNpzDwoSBu4", + "dataHash": "23b43bebac48a4acc39e578715aa06635d6d900fa3ea7441dfffd6e43b914f7b" + }, + "script": "edcd84c10e36ae810dc50847477083069db796219b39ccde790484e0" + }, + "committee": { + "members": { + "scriptHash-7ceede7d6a89e006408e6b7c6acb3dd094b3f6817e43b4a36d01535b": 500, + "scriptHash-6095e643ea6f1cccb6e463ec34349026b3a48621aac5d512655ab1bf": 500, + "scriptHash-27999ed757d6dac217471ae61d69b1b067b8b240d9e3ff36eb66b5d0": 500, + "scriptHash-87f867a31c0f81360d4d7dcddb6b025ba8383db9bf77a2af7797799d": 500, + "scriptHash-a19a7ba1caede8f3ab3e5e2a928b3798d7d011af18fbd577f7aeb0ec": 500 + }, + "threshold": 0.67 + } +} \ No newline at end of file diff --git a/integration-test/configs/local-chang/shelley-genesis.json b/integration-test/configs/local-chang/shelley-genesis.json new file mode 100644 index 00000000..63aa1093 --- /dev/null +++ b/integration-test/configs/local-chang/shelley-genesis.json @@ -0,0 +1,50 @@ +{ + "maxLovelaceSupply": 1000000000000, + "securityParam": 1000000000, + "slotsPerKESPeriod": 1000000000, + "updateQuorum": 2, + "activeSlotsCoeff": 0.5, + "protocolParams": { + "minUTxOValue": 1000000, + "eMax": 18, + "extraEntropy": { + "tag": "NeutralNonce" + }, + "minFeeB": 155381, + "tau": 0.1, + "maxBlockBodySize": 65536, + "minPoolCost": 0, + "minFeeA": 44, + "maxTxSize": 16384, + "nOpt": 100, + "maxBlockHeaderSize": 1100, + "keyDeposit": 1000000, + "protocolVersion": { + "minor": 0, + "major": 7 + }, + "poolDeposit": 1000000, + "a0": 0.0, + "rho": 0.1, + "decentralisationParam": 0.1 + }, + "networkMagic": 42, + "initialFunds": { + "60d413c1745d306023e49589e658a7b7a4b4dda165ff5c97d8c8b979bf": 900000000000 + }, + "maxKESEvolutions": 60000000, + "networkId": "Testnet", + "genDelegs": { + "37c2ef3cfb83c1004fcc21c75f42fee8013ac994afde92c1af419d1c": { + "delegate": "5bd3a54bf30412243d4616c145c79467322164b81aa577814b74a520", + "vrf": "fb66920eb17f426d4f513535be0eed59859a0e83963860090bb6db571f8a5b55" + } + }, + "slotLength": 1, + "systemStart": "2021-12-21T03:17:14.803874404Z", + "staking": { + "pools": {}, + "stake": {} + }, + "epochLength": 4 +} \ No newline at end of file diff --git a/integration-test/configs/local-chang/shelley/kes.skey b/integration-test/configs/local-chang/shelley/kes.skey new file mode 100644 index 00000000..a9bfc0ca --- /dev/null +++ b/integration-test/configs/local-chang/shelley/kes.skey @@ -0,0 +1,5 @@ +{ + "type": "KesSigningKey_ed25519_kes_2^6", + "description": "KES Signing Key", + "cborHex": "59026051c2b5536d23bbd7ff92aa8b58a011fb57b669183b7083961ae979a7b2ad1fbcbf1ee580c9e39567b88562b370cdccd27cababc4812a2ce1a7a0c7369274cf5f18f3e4796482babf0ea8d4e97157d6221bb6448da0cf3f173bbc1b13e708e40c25559347cc225b6d916bf611bc133d265482d0c503e94493456bb607ce34fd7b51a13e8908d9d85582edbed89e0fd2a0fb34d45480cef5b277dbb46b23322ea191760cafdf5c2f3bc5307f2128c121e5f8f54fdf6ca2925c034fc11dcc933855b595493e629e717a1b2ced715dfac5bf42838928edd19c287d55c1ef04ecf31070fe52ab805cf813e752f001353ac637f8f3f76db4b8c0e12f8552335182af76683b819debaa623a730e12f2f7d9f63190c835e8211bdf86d2bf244e8ad114328621535a63fd1a1497389356220e818e5d2f530f50494401b7ee027172ca72093645465b2c83e0dcd1d9c4a81b6871849601a8706d95e3c58a4c0841fdfb214b0bb82ec1e18ba7bea9e4f3eb9a0abbb39e57a9ab96799379ca8cadeb2e1a8df84b3e0e7ca0af3d6665a12029f6cefe4d309c5b3fad5bec4ca7812d5bede426b6fff6f37da99a286cd837b327b35b645ca5bfabf0935ea87cbd29b3ce2b7b80f83f386a474c69f86f553e35069f40b04f9a6bb6a13b583c0a911126c8aed1301b4014e0ea8229d5dcce81a56836f5bb286bd28c1ee5c69fd358c16a4fdbd5b6e9b0ed1ef766dcf6c56c7a845104309c92a2013bd5a7c8354fb8a866b61b23e014a07a78ed5b69469f4121c97bce50864d8555b91e3c2d812f4760a6318750c7b71fccbc8bab1c54c0be28f60c97cc8e33cbd8da235e4ca9344c48f13d81a37459" +} diff --git a/integration-test/configs/local-chang/shelley/kes.vkey b/integration-test/configs/local-chang/shelley/kes.vkey new file mode 100644 index 00000000..8841f971 --- /dev/null +++ b/integration-test/configs/local-chang/shelley/kes.vkey @@ -0,0 +1,5 @@ +{ + "type": "KesVerificationKey_ed25519_kes_2^6", + "description": "KES Verification Key", + "cborHex": "58206e59b21f538b5fdbe50df62f793488f8783e19d261d3fd59a700d2c41963cec2" +} diff --git a/integration-test/configs/local-chang/shelley/node.cert b/integration-test/configs/local-chang/shelley/node.cert new file mode 100644 index 00000000..15c52608 --- /dev/null +++ b/integration-test/configs/local-chang/shelley/node.cert @@ -0,0 +1,5 @@ +{ + "type": "NodeOperationalCertificate", + "description": "", + "cborHex": "828458206e59b21f538b5fdbe50df62f793488f8783e19d261d3fd59a700d2c41963cec201005840853403f4d2e63e027b26f59c45ce81c74b1dfd708dc561b5ede5204262253451b7560f1c75425d3ee08fd4d933392f7fe3f1017efb3c8ee565a5493a061a270d582091934010118a86e2628e8188413cfa3eeac1237f3f699ebe16892f41671ccf3f" +} diff --git a/integration-test/configs/local-chang/shelley/operator.counter b/integration-test/configs/local-chang/shelley/operator.counter new file mode 100644 index 00000000..aae820c3 --- /dev/null +++ b/integration-test/configs/local-chang/shelley/operator.counter @@ -0,0 +1,5 @@ +{ + "type": "NodeOperationalCertificateIssueCounter", + "description": "Next certificate issue number: 2", + "cborHex": "8202582091934010118a86e2628e8188413cfa3eeac1237f3f699ebe16892f41671ccf3f" +} diff --git a/integration-test/configs/local-chang/shelley/operator.skey b/integration-test/configs/local-chang/shelley/operator.skey new file mode 100644 index 00000000..87464ad4 --- /dev/null +++ b/integration-test/configs/local-chang/shelley/operator.skey @@ -0,0 +1,5 @@ +{ + "type": "GenesisDelegateSigningKey_ed25519", + "description": "Genesis delegate operator key", + "cborHex": "5820351111fb3058c30c976b57f1b13e0e333243126768eae52133294cfe1481e943" +} diff --git a/integration-test/configs/local-chang/shelley/operator.vkey b/integration-test/configs/local-chang/shelley/operator.vkey new file mode 100644 index 00000000..6bd011f3 --- /dev/null +++ b/integration-test/configs/local-chang/shelley/operator.vkey @@ -0,0 +1,5 @@ +{ + "type": "GenesisDelegateVerificationKey_ed25519", + "description": "Genesis delegate operator key", + "cborHex": "582091934010118a86e2628e8188413cfa3eeac1237f3f699ebe16892f41671ccf3f" +} diff --git a/integration-test/configs/local-chang/shelley/utxo-keys/payment.addr b/integration-test/configs/local-chang/shelley/utxo-keys/payment.addr new file mode 100644 index 00000000..4d3d2e10 --- /dev/null +++ b/integration-test/configs/local-chang/shelley/utxo-keys/payment.addr @@ -0,0 +1 @@ +addr_test1vr2p8st5t5cxqglyjky7vk98k7jtfhdpvhl4e97cezuhn0cqcexl7 \ No newline at end of file diff --git a/integration-test/configs/local-chang/shelley/utxo-keys/utxo1.skey b/integration-test/configs/local-chang/shelley/utxo-keys/utxo1.skey new file mode 100644 index 00000000..896420b5 --- /dev/null +++ b/integration-test/configs/local-chang/shelley/utxo-keys/utxo1.skey @@ -0,0 +1,5 @@ +{ + "type": "GenesisUTxOSigningKey_ed25519", + "description": "Genesis Initial UTxO Signing Key", + "cborHex": "5820093be5cd3987d0c9fd8854ef908f7746b69e2d73320db6dc0f780d81585b84c2" +} diff --git a/integration-test/configs/local-chang/shelley/utxo-keys/utxo1.vkey b/integration-test/configs/local-chang/shelley/utxo-keys/utxo1.vkey new file mode 100644 index 00000000..157a8fd3 --- /dev/null +++ b/integration-test/configs/local-chang/shelley/utxo-keys/utxo1.vkey @@ -0,0 +1,5 @@ +{ + "type": "GenesisUTxOVerificationKey_ed25519", + "description": "Genesis Initial UTxO Verification Key", + "cborHex": "58208be8339e9f3addfa6810d59e2f072f85e64d4c024c087e0d24f8317c6544f62f" +} diff --git a/integration-test/configs/local-chang/shelley/vrf.skey b/integration-test/configs/local-chang/shelley/vrf.skey new file mode 100644 index 00000000..a5ff9e28 --- /dev/null +++ b/integration-test/configs/local-chang/shelley/vrf.skey @@ -0,0 +1,5 @@ +{ + "type": "VrfSigningKey_PraosVRF", + "description": "VRF Signing Key", + "cborHex": "5840b504af084d200455b08e72f0d278cf23bd9f2acddf834755d007e87536e19d1158cc502328977455f71db641249286ce07c11de5cb1f7429db0584eca3cabb7e" +} diff --git a/integration-test/configs/local-chang/shelley/vrf.vkey b/integration-test/configs/local-chang/shelley/vrf.vkey new file mode 100644 index 00000000..65c9592d --- /dev/null +++ b/integration-test/configs/local-chang/shelley/vrf.vkey @@ -0,0 +1,5 @@ +{ + "type": "VrfVerificationKey_PraosVRF", + "description": "VRF Verification Key", + "cborHex": "582058cc502328977455f71db641249286ce07c11de5cb1f7429db0584eca3cabb7e" +} diff --git a/integration-test/configs/local-chang/topology.json b/integration-test/configs/local-chang/topology.json new file mode 100644 index 00000000..dc92f2e8 --- /dev/null +++ b/integration-test/configs/local-chang/topology.json @@ -0,0 +1,9 @@ +{ + "Producers": [ + { + "addr": "172.20.0.102", + "port": 3000, + "valency": 1 + } + ] +} diff --git a/integration-test/docker-compose-chang.yml b/integration-test/docker-compose-chang.yml new file mode 100644 index 00000000..73866f83 --- /dev/null +++ b/integration-test/docker-compose-chang.yml @@ -0,0 +1,103 @@ +version: "3.5" + +networks: + cluster: + ipam: + config: + - subnet: 172.20.0.0/24 + +services: + + cardano-node: + image: ghcr.io/intersectmbo/cardano-node:${CARDANO_NODE_VERSION:-9.1.0} + platform: linux/amd64 + entrypoint: bash + environment: + NETWORK: "${NETWORK:-local-alonzo}" + CARDANO_NODE_SOCKET_PATH: "/ipc/node.socket" + command: /code/run_node.sh + + networks: + cluster: + ipv4_address: 172.20.0.101 + + volumes: + - .:/code + - /tmp:/tmp + - node-db:/data/db + - node-ipc:/ipc + ports: + - ${BFT_NODE_PORT:-3000}:3000 + logging: + driver: "json-file" + options: + max-size: "200k" + max-file: "10" + + cardano-pool: + image: ghcr.io/intersectmbo/cardano-node:${CARDANO_NODE_VERSION:-9.1.0} + platform: linux/amd64 + entrypoint: bash + environment: + NETWORK: "${NETWORK:-local-alonzo}" + command: /code/run_pool.sh + + networks: + cluster: + ipv4_address: 172.20.0.102 + + volumes: + - .:/code + - node-ipc:/ipc + logging: + driver: "json-file" + options: + max-size: "200k" + max-file: "10" + + ogmios: + image: cardanosolutions/ogmios:v6.5.0 + platform: linux/amd64 + environment: + NETWORK: "${NETWORK:-local-alonzo}" + + command: [ + "--host", "0.0.0.0", + "--node-socket", "/ipc/node.socket", + "--node-config", "/code/configs/${NETWORK:-local-alonzo}/config.json", + "--log-level-websocket", "Debug" + ] + volumes: + - .:/code + - node-ipc:/ipc + ports: + - ${OGMIOS_PORT:-1337}:1337 + logging: + driver: "json-file" + options: + max-size: "200k" + max-file: "10" + + kupo: + image: cardanosolutions/kupo:v2.4.0 + platform: linux/amd64 + environment: + NETWORK: "${NETWORK:-local}" + + command: [ + "--node-socket", "/ipc/node.socket", + "--node-config", "/code/configs/${NETWORK:-local-alonzo}/config.json", + "--host", "0.0.0.0", + "--since", "origin", + "--match", "*", + "--in-memory" + ] + volumes: + - .:/code + - node-ipc:/ipc + ports: + - ${KUPO_PORT:-1442}:1442 + +volumes: + node-db: + node-ipc: diff --git a/integration-test/docker-compose.yml b/integration-test/docker-compose.yml index 58d45fa2..b6cd3eb0 100644 --- a/integration-test/docker-compose.yml +++ b/integration-test/docker-compose.yml @@ -10,6 +10,7 @@ services: cardano-node: image: ghcr.io/intersectmbo/cardano-node:${CARDANO_NODE_VERSION:-8.9.2} + platform: linux/amd64 entrypoint: bash environment: NETWORK: "${NETWORK:-local-alonzo}" @@ -35,6 +36,7 @@ services: cardano-pool: image: ghcr.io/intersectmbo/cardano-node:${CARDANO_NODE_VERSION:-8.9.2} + platform: linux/amd64 entrypoint: bash environment: NETWORK: "${NETWORK:-local-alonzo}" @@ -55,6 +57,7 @@ services: ogmios: image: cardanosolutions/ogmios:v6.2.0 + platform: linux/amd64 environment: NETWORK: "${NETWORK:-local-alonzo}" @@ -76,6 +79,7 @@ services: kupo: image: cardanosolutions/kupo:v2.4.0 + platform: linux/amd64 environment: NETWORK: "${NETWORK:-local}" diff --git a/integration-test/plutus_scripts/helloworldV3.plutus b/integration-test/plutus_scripts/helloworldV3.plutus new file mode 100644 index 00000000..a2aa60c0 --- /dev/null +++ b/integration-test/plutus_scripts/helloworldV3.plutus @@ -0,0 +1 @@ +58e901010032323232323223223225333006323253330083371e6eb8c008c028dd5002a4410d48656c6c6f2c20576f726c642100100114a06644646600200200644a66601c00229404c94ccc030cdc79bae301000200414a226600600600260200026eb0c02cc030c030c030c030c030c030c030c030c024dd5180098049baa002375c600260126ea80188c02c0045261365653330043370e900018029baa001132325333009300b002149858dd7180480098031baa0011653330023370e900018019baa0011323253330073009002149858dd7180380098021baa001165734aae7555cf2ab9f5742ae881 \ No newline at end of file diff --git a/integration-test/run_node.sh b/integration-test/run_node.sh index 1069ded0..62b72168 100755 --- a/integration-test/run_node.sh +++ b/integration-test/run_node.sh @@ -1,6 +1,6 @@ #!/bin/bash -if [ "$NETWORK" = "local-alonzo" ] || [ "$NETWORK" = "local-vasil" ] +if [ "$NETWORK" = "local-alonzo" ] || [ "$NETWORK" = "local-vasil" ] || [ "$NETWORK" = "local-chang" ] then chmod 400 /code/tmp_configs/"$NETWORK"/shelley/*.skey chmod 400 /code/tmp_configs/"$NETWORK"/shelley/*.vkey diff --git a/integration-test/run_pool.sh b/integration-test/run_pool.sh index c49bf62d..d27bfc83 100644 --- a/integration-test/run_pool.sh +++ b/integration-test/run_pool.sh @@ -1,7 +1,7 @@ #!/bin/bash echo "$NETWORK" -if [ "$NETWORK" = "local-alonzo" ] || [ "$NETWORK" = "local-vasil" ] +if [ "$NETWORK" = "local-alonzo" ] || [ "$NETWORK" = "local-vasil" ] || [ "$NETWORK" = "local-chang" ] then # Waiting for BFT node to be ready @@ -15,7 +15,7 @@ done cardano-cli transaction build \ --tx-in 732bfd67e66be8e8288349fcaaa2294973ef6271cc189a239bb431275401b8e5#0 \ --tx-out "$(cat /code/keys/pool/full.addr)"+450000000000 \ - --change-address "$(cat /code/tmp_configs/local-alonzo/shelley/utxo-keys/payment.addr)" \ + --change-address "$(cat /code/tmp_configs/"$NETWORK"/shelley/utxo-keys/payment.addr)" \ --out-file tx.raw \ --testnet-magic 42 \ --certificate-file /code/keys/pool/stake.cert \ @@ -29,7 +29,7 @@ done cardano-cli transaction sign \ --tx-body-file tx.raw \ - --signing-key-file /code/tmp_configs/local-alonzo/shelley/utxo-keys/utxo1.skey \ + --signing-key-file /code/tmp_configs/"$NETWORK"/shelley/utxo-keys/utxo1.skey \ --signing-key-file /code/keys/pool/stake.skey \ --signing-key-file /code/keys/pool/cold.skey \ --testnet-magic 42 \ diff --git a/integration-test/run_tests.sh b/integration-test/run_tests.sh index 45670042..a561860c 100755 --- a/integration-test/run_tests.sh +++ b/integration-test/run_tests.sh @@ -11,47 +11,73 @@ poetry run pip install ogmios ########## # Alonzo # ########## +# +## Cleanup containers and volumes in case there is any running +#docker-compose down --volumes --remove-orphans +# +## Run alonzo integration tests +#./bootstrap.sh local-alonzo +# +## Launch containers +#docker-compose up -d +# +#export PAYMENT_KEY="$ROOT"/configs/local-alonzo/shelley/utxo-keys/utxo1.skey +#export EXTENDED_PAYMENT_KEY="$ROOT"/keys/extended.skey +#export POOL_ID=$(cat "$ROOT"/keys/pool/pool.id) +# +## Wait for stake pool to start producing blocks +#sleep 10 +# +## Cleanup +#docker-compose down --volumes --remove-orphans +# +########## +## Vasil # +########## +# +## Cleanup containers and volumes in case there is any running +#docker-compose down --volumes --remove-orphans +# +## Run integration tests +#./bootstrap.sh local-vasil +# +## Launch containers +#docker-compose up -d +# +#export PAYMENT_KEY="$ROOT"/configs/local-vasil/shelley/utxo-keys/utxo1.skey +#export EXTENDED_PAYMENT_KEY="$ROOT"/keys/extended.skey +#export POOL_ID=$(cat "$ROOT"/keys/pool/pool.id) +# +## Wait for stake pool to start producing blocks +#sleep 30 +# +#poetry run pytest -s -vv -n 4 "$ROOT"/test +# +## Cleanup +#docker-compose down --volumes --remove-orphans -# Cleanup containers and volumes in case there is any running -docker-compose down --volumes --remove-orphans - -# Run alonzo integration tests -./bootstrap.sh local-alonzo - -# Launch containers -docker-compose up -d - -export PAYMENT_KEY="$ROOT"/configs/local-alonzo/shelley/utxo-keys/utxo1.skey -export EXTENDED_PAYMENT_KEY="$ROOT"/keys/extended.skey -export POOL_ID=$(cat "$ROOT"/keys/pool/pool.id) - -# Wait for stake pool to start producing blocks -sleep 10 - -# Cleanup -docker-compose down --volumes --remove-orphans ######### -# Vasil # +# Chang # ######### # Cleanup containers and volumes in case there is any running -docker-compose down --volumes --remove-orphans +docker-compose -f docker-compose-chang.yml down --volumes --remove-orphans # Run integration tests -./bootstrap.sh local-vasil +./bootstrap.sh local-chang # Launch containers -docker-compose up -d +docker-compose -f docker-compose-chang.yml up -d -export PAYMENT_KEY="$ROOT"/configs/local-vasil/shelley/utxo-keys/utxo1.skey +export PAYMENT_KEY="$ROOT"/configs/local-chang/shelley/utxo-keys/utxo1.skey export EXTENDED_PAYMENT_KEY="$ROOT"/keys/extended.skey export POOL_ID=$(cat "$ROOT"/keys/pool/pool.id) # Wait for stake pool to start producing blocks -sleep 30 +#sleep 30 -poetry run pytest -s -vv "$ROOT"/test +poetry run pytest -m "not (CardanoCLI)" -s -vv -n 4 "$ROOT"/test # Cleanup -docker-compose down --volumes --remove-orphans \ No newline at end of file +docker-compose -f docker-compose-chang.yml down --volumes --remove-orphans \ No newline at end of file diff --git a/integration-test/test/base.py b/integration-test/test/base.py index 2491c4b2..c8fe88f6 100644 --- a/integration-test/test/base.py +++ b/integration-test/test/base.py @@ -10,6 +10,54 @@ TEST_RETRIES = 6 +def _fetch_protocol_param(self) -> ProtocolParameters: + with python_ogmios.Client(self.host, self.port, self.secure) as client: + protocol_parameters, _ = client.query_protocol_parameters.execute() + pyc_protocol_params = ProtocolParameters( + min_fee_constant=protocol_parameters.min_fee_constant.lovelace, + min_fee_coefficient=protocol_parameters.min_fee_coefficient, + min_pool_cost=protocol_parameters.min_stake_pool_cost.lovelace, + max_block_size=protocol_parameters.max_block_body_size.get("bytes"), + max_tx_size=protocol_parameters.max_transaction_size.get("bytes"), + max_block_header_size=protocol_parameters.max_block_header_size.get( + "bytes" + ), + key_deposit=protocol_parameters.stake_credential_deposit.lovelace, + pool_deposit=protocol_parameters.stake_pool_deposit.lovelace, + pool_influence=eval(protocol_parameters.stake_pool_pledge_influence), + monetary_expansion=eval(protocol_parameters.monetary_expansion), + treasury_expansion=eval(protocol_parameters.treasury_expansion), + decentralization_param=None, # TODO + extra_entropy=protocol_parameters.extra_entropy, + protocol_major_version=protocol_parameters.version.get("major"), + protocol_minor_version=protocol_parameters.version.get("minor"), + min_utxo=None, + price_mem=eval(protocol_parameters.script_execution_prices.get("memory")), + price_step=eval(protocol_parameters.script_execution_prices.get("cpu")), + max_tx_ex_mem=protocol_parameters.max_execution_units_per_transaction.get( + "memory" + ), + max_tx_ex_steps=protocol_parameters.max_execution_units_per_transaction.get( + "cpu" + ), + max_block_ex_mem=protocol_parameters.max_execution_units_per_block.get( + "memory" + ), + max_block_ex_steps=protocol_parameters.max_execution_units_per_block.get( + "cpu" + ), + max_val_size=protocol_parameters.max_value_size.get("bytes"), + collateral_percent=protocol_parameters.collateral_percentage, + max_collateral_inputs=protocol_parameters.max_collateral_inputs, + coins_per_utxo_word=ALONZO_COINS_PER_UTXO_WORD, + coins_per_utxo_byte=protocol_parameters.min_utxo_deposit_coefficient, + maximum_reference_scripts_size=protocol_parameters.max_ref_script_size, + min_fee_reference_scripts=protocol_parameters.min_fee_ref_scripts, + cost_models=self._parse_cost_models(protocol_parameters.plutus_cost_models), + ) + return pyc_protocol_params + + @retry(tries=10, delay=4) def check_chain_context(chain_context): print(f"Current chain tip: {chain_context.last_block_slot}") @@ -22,8 +70,12 @@ class TestBase: # TODO: Bring back kupo test KUPO_URL = "http://localhost:1442" + python_ogmios.OgmiosChainContext._fetch_protocol_param = _fetch_protocol_param chain_context = python_ogmios.OgmiosChainContext( - host="localhost", port=1337, network=Network.TESTNET + host="localhost", + port=1337, + network=Network.TESTNET, + refetch_chain_tip_interval=1, ) check_chain_context(chain_context) diff --git a/integration-test/test/test_cardano_cli.py b/integration-test/test/test_cardano_cli.py index 8a1d875c..1b484a8d 100644 --- a/integration-test/test/test_cardano_cli.py +++ b/integration-test/test/test_cardano_cli.py @@ -1,6 +1,7 @@ import os from pathlib import Path +import pytest from retry import retry from pycardano import ( @@ -15,6 +16,7 @@ from .base import TEST_RETRIES +@pytest.mark.CardanoCLI class TestCardanoCli: network_env = os.getenv("NETWORK", "local-alonzo") host_socket = os.getenv("DOCKER_HOST", None) diff --git a/integration-test/test/test_plutus.py b/integration-test/test/test_plutus.py index 93acf491..62abf8f4 100644 --- a/integration-test/test/test_plutus.py +++ b/integration-test/test/test_plutus.py @@ -1,5 +1,6 @@ import collections import time +from dataclasses import dataclass from typing import Dict, Union import cbor2 @@ -12,6 +13,18 @@ from .test_cardano_cli import TestCardanoCli +@dataclass +class HelloWorldDatum(PlutusData): + CONSTR_ID = 0 + owner: bytes + + +@dataclass +class HelloWorldRedeemer(PlutusData): + CONSTR_ID = 0 + msg: bytes + + class TestPlutus(TestBase): @retry(tries=TEST_RETRIES, backoff=1.5, delay=6, jitter=(0, 4)) def test_plutus_v1(self): @@ -263,7 +276,7 @@ def test_plutus_v2_ref_script(self): print(signed_tx.to_cbor_hex()) print("############### Submitting transaction ###############") self.chain_context.submit_tx(signed_tx) - time.sleep(3) + time.sleep(6) # ----------- Send ADA to the same script address without datum or script --------------- @@ -280,7 +293,7 @@ def test_plutus_v2_ref_script(self): print(signed_tx.to_cbor_hex()) print("############### Submitting transaction ###############") self.chain_context.submit_tx(signed_tx) - time.sleep(3) + time.sleep(6) # ----------- Taker take --------------- @@ -369,6 +382,63 @@ def test_get_plutus_script(self): assert utxos[0].output.script == forty_two_script + @retry(tries=TEST_RETRIES, backoff=1.5, delay=6, jitter=(0, 4)) + @pytest.mark.post_chang + def test_plutus_v3(self): + # ----------- Giver give --------------- + + with open("./plutus_scripts/helloworldV3.plutus", "r") as f: + script_hex = f.read() + hello_world_script = cbor2.loads(bytes.fromhex(script_hex)) + + script_hash = plutus_script_hash(PlutusV3Script(hello_world_script)) + + script_address = Address(script_hash, network=self.NETWORK) + + giver_address = Address(self.payment_vkey.hash(), network=self.NETWORK) + + builder = TransactionBuilder(self.chain_context) + builder.add_input_address(giver_address) + datum = HelloWorldDatum(owner=self.payment_vkey.hash().to_primitive()) + builder.add_output(TransactionOutput(script_address, 50000000, datum=datum)) + + signed_tx = builder.build_and_sign([self.payment_skey], giver_address) + + print("############### Transaction created ###############") + print(signed_tx) + print(signed_tx.to_cbor_hex()) + print("############### Submitting transaction ###############") + self.chain_context.submit_tx(signed_tx) + time.sleep(3) + + # ----------- Taker take --------------- + + redeemer = Redeemer(data=HelloWorldRedeemer(msg=b"Hello, World!")) + + utxo_to_spend = self.chain_context.utxos(script_address)[0] + + taker_address = Address(self.extended_payment_vkey.hash(), network=self.NETWORK) + + builder = TransactionBuilder(self.chain_context) + + builder.add_script_input( + utxo_to_spend, PlutusV3Script(hello_world_script), redeemer=redeemer + ) + take_output = TransactionOutput(taker_address, 25123456) + builder.add_output(take_output) + + builder.required_signers = [self.payment_vkey.hash()] + + signed_tx = builder.build_and_sign([self.payment_skey], taker_address) + + print("############### Transaction created ###############") + print(signed_tx) + print(signed_tx.to_cbor_hex()) + print("############### Submitting transaction ###############") + self.chain_context.submit_tx(signed_tx) + + self.assert_output(taker_address, take_output) + # class TestPlutusOgmiosOnly(TestPlutus): # @classmethod @@ -388,6 +458,7 @@ def evaluate_tx(tx: Transaction) -> Dict[str, ExecutionUnits]: return execution_units +@pytest.mark.CardanoCLI class TestPlutusCardanoCLI(TestPlutus): @classmethod def setup_class(cls): diff --git a/pycardano/backend/base.py b/pycardano/backend/base.py index aec6948a..7e3fb145 100644 --- a/pycardano/backend/base.py +++ b/pycardano/backend/base.py @@ -2,7 +2,7 @@ from dataclasses import dataclass from fractions import Fraction -from typing import Dict, List, Union +from typing import Dict, List, Optional, Union from pycardano.address import Address from pycardano.exception import InvalidArgumentException @@ -109,6 +109,10 @@ class ProtocolParameters: """A dict contains cost models for Plutus. The key will be "PlutusV1", "PlutusV2", etc. The value will be a dict of cost model parameters.""" + maximum_reference_scripts_size: Optional[Dict[str, int]] = None + + min_fee_reference_scripts: Optional[Dict[str, float]] = None + @typechecked class ChainContext: diff --git a/pycardano/metadata.py b/pycardano/metadata.py index 6ddfa708..17bb4a08 100644 --- a/pycardano/metadata.py +++ b/pycardano/metadata.py @@ -10,6 +10,7 @@ from pycardano.exception import DeserializeException, InvalidArgumentException from pycardano.hash import AUXILIARY_DATA_HASH_SIZE, AuxiliaryDataHash from pycardano.nativescript import NativeScript +from pycardano.plutus import PlutusV1Script, PlutusV2Script, PlutusV3Script from pycardano.serialization import ( ArrayCBORSerializable, CBORSerializable, @@ -87,9 +88,15 @@ class AlonzoMetadata(MapCBORSerializable): default=None, metadata={"optional": True, "key": 1, "object_hook": list_hook(NativeScript)}, ) - plutus_scripts: Optional[List[bytes]] = field( + plutus_v1_scripts: Optional[List[PlutusV1Script]] = field( default=None, metadata={"optional": True, "key": 2} ) + plutus_v2_scripts: Optional[List[PlutusV2Script]] = field( + default=None, metadata={"optional": True, "key": 3} + ) + plutus_v3_scripts: Optional[List[PlutusV3Script]] = field( + default=None, metadata={"optional": True, "key": 4} + ) def to_primitive(self) -> Primitive: return CBORTag(AlonzoMetadata.TAG, super(AlonzoMetadata, self).to_primitive()) diff --git a/pycardano/plutus.py b/pycardano/plutus.py index b1ee6e81..700b49d5 100644 --- a/pycardano/plutus.py +++ b/pycardano/plutus.py @@ -41,6 +41,7 @@ "ExecutionUnits", "PlutusV1Script", "PlutusV2Script", + "PlutusV3Script", "RawPlutusData", "Redeemer", "ScriptType", @@ -1014,6 +1015,10 @@ class PlutusV2Script(bytes): pass +class PlutusV3Script(bytes): + pass + + ScriptType = Union[bytes, NativeScript, PlutusV1Script, PlutusV2Script] """Script type. A Union type that contains all valid script types.""" @@ -1037,6 +1042,10 @@ def script_hash(script: ScriptType) -> ScriptHash: return ScriptHash( blake2b(bytes.fromhex("02") + script, SCRIPT_HASH_SIZE, encoder=RawEncoder) ) + elif isinstance(script, PlutusV3Script): + return ScriptHash( + blake2b(bytes.fromhex("03") + script, SCRIPT_HASH_SIZE, encoder=RawEncoder) + ) else: raise TypeError(f"Unexpected script type: {type(script)}") diff --git a/pycardano/txbuilder.py b/pycardano/txbuilder.py index 63ea93cc..62a0b5ad 100644 --- a/pycardano/txbuilder.py +++ b/pycardano/txbuilder.py @@ -40,6 +40,7 @@ ExecutionUnits, PlutusV1Script, PlutusV2Script, + PlutusV3Script, Redeemer, RedeemerTag, ScriptType, @@ -155,9 +156,9 @@ class TransactionBuilder: init=False, default_factory=lambda: {} ) - _reference_scripts: List[Union[NativeScript, PlutusV1Script, PlutusV2Script]] = ( - field(init=False, default_factory=lambda: []) - ) + _reference_scripts: List[ + Union[NativeScript, PlutusV1Script, PlutusV2Script, PlutusV3Script] + ] = field(init=False, default_factory=lambda: []) _should_estimate_execution_units: Optional[bool] = field(init=False, default=None) @@ -203,7 +204,7 @@ def add_script_input( self, utxo: UTxO, script: Optional[ - Union[UTxO, NativeScript, PlutusV1Script, PlutusV2Script] + Union[UTxO, NativeScript, PlutusV1Script, PlutusV2Script, PlutusV3Script] ] = None, datum: Optional[Datum] = None, redeemer: Optional[Redeemer] = None, @@ -212,7 +213,8 @@ def add_script_input( Args: utxo (UTxO): Script UTxO to be added. - script (Optional[Union[UTxO, NativeScript, PlutusV1Script, PlutusV2Script]]): A plutus script. + script (Optional[Union[UTxO, NativeScript, PlutusV1Script, PlutusV2Script, PlutusV3Script]]): + A plutus script. If not provided, the script will be inferred from the input UTxO (first arg of this method). The script can also be a specific UTxO whose output contains an inline script. datum (Optional[Datum]): A plutus datum to unlock the UTxO. @@ -263,7 +265,10 @@ def add_script_input( # collect potential scripts to fulfill the input candidate_scripts: List[ - Tuple[Union[NativeScript, PlutusV1Script, PlutusV2Script], Optional[UTxO]] + Tuple[ + Union[NativeScript, PlutusV1Script, PlutusV2Script, PlutusV3Script], + Optional[UTxO], + ] ] = [] if utxo.output.script: candidate_scripts.append((utxo.output.script, utxo)) @@ -290,6 +295,7 @@ def add_script_input( if candidate_utxo is not None: self.reference_inputs.add(candidate_utxo) self._reference_scripts.append(candidate_script) + break if not found_valid_script: raise InvalidArgumentException( f"Cannot find a valid script to fulfill the input UTxO: {utxo.input}." @@ -301,13 +307,15 @@ def add_script_input( def add_minting_script( self, - script: Union[UTxO, NativeScript, PlutusV1Script, PlutusV2Script], + script: Union[ + UTxO, NativeScript, PlutusV1Script, PlutusV2Script, PlutusV3Script + ], redeemer: Optional[Redeemer] = None, ) -> TransactionBuilder: """Add a minting script along with its datum and redeemer to this transaction. Args: - script (Union[UTxO, PlutusV1Script, PlutusV2Script]): A plutus script. + script (Union[UTxO, PlutusV1Script, PlutusV2Script, PlutusV3Script]): A plutus script. redeemer (Optional[Redeemer]): A plutus redeemer to unlock the UTxO. Returns: @@ -333,13 +341,15 @@ def add_minting_script( def add_withdrawal_script( self, - script: Union[UTxO, NativeScript, PlutusV1Script, PlutusV2Script], + script: Union[ + UTxO, NativeScript, PlutusV1Script, PlutusV2Script, PlutusV3Script + ], redeemer: Optional[Redeemer] = None, ) -> TransactionBuilder: """Add a withdrawal script along with its redeemer to this transaction. Args: - script (Union[UTxO, PlutusV1Script, PlutusV2Script]): A plutus script. + script (Union[UTxO, PlutusV1Script, PlutusV2Script, PlutusV3Script]): A plutus script. redeemer (Optional[Redeemer]): A plutus redeemer to unlock the UTxO. Returns: @@ -495,6 +505,10 @@ def script_data_hash(self) -> Optional[ScriptDataHash]: self.context.protocol_param.cost_models.get("PlutusV2") or PLUTUS_V2_COST_MODEL ) + if isinstance(s, PlutusV3Script): + cost_models[1] = self.context.protocol_param.cost_models.get( + "PlutusV3", {} + ) return script_data_hash( self.redeemers, list(self.datums.values()), CostModels(cost_models) ) @@ -875,7 +889,7 @@ def _build_tx_body(self) -> TransactionBody: self.auxiliary_data.hash() if self.auxiliary_data else None ), script_data_hash=self.script_data_hash, - required_signers=self.required_signers, + required_signers=self.required_signers if self.required_signers else None, validity_start=self.validity_start, collateral=( [c.input for c in self.collaterals] if self.collaterals else None @@ -941,6 +955,7 @@ def build_witness_set(self) -> TransactionWitnessSet: native_scripts: List[NativeScript] = [] plutus_v1_scripts: List[PlutusV1Script] = [] plutus_v2_scripts: List[PlutusV2Script] = [] + plutus_v3_scripts: List[PlutusV3Script] = [] for script in self.scripts: if isinstance(script, NativeScript): @@ -951,6 +966,8 @@ def build_witness_set(self) -> TransactionWitnessSet: plutus_v1_scripts.append(PlutusV1Script(script)) elif isinstance(script, PlutusV2Script): plutus_v2_scripts.append(script) + elif isinstance(script, PlutusV3Script): + plutus_v3_scripts.append(script) else: raise InvalidArgumentException( f"Unsupported script type: {type(script)}" @@ -960,6 +977,7 @@ def build_witness_set(self) -> TransactionWitnessSet: native_scripts=native_scripts if native_scripts else None, plutus_v1_script=plutus_v1_scripts if plutus_v1_scripts else None, plutus_v2_script=plutus_v2_scripts if plutus_v2_scripts else None, + plutus_v3_script=plutus_v3_scripts if plutus_v3_scripts else None, redeemer=self.redeemers if self.redeemers else None, plutus_data=list(self.datums.values()) if self.datums else None, ) @@ -977,11 +995,19 @@ def _estimate_fee(self): for redeemer in self.redeemers: plutus_execution_units += redeemer.ex_units + ref_script_size = 0 + for s in self._reference_scripts: + if isinstance(s, NativeScript): + ref_script_size += len(s.to_cbor()) + else: + ref_script_size += len(s) + estimated_fee = fee( self.context, len(self._build_full_fake_tx().to_cbor()), plutus_execution_units.steps, plutus_execution_units.mem, + ref_script_size, ) if self.fee_buffer is not None: estimated_fee += self.fee_buffer diff --git a/pycardano/utils.py b/pycardano/utils.py index af3a215a..23a6dda1 100644 --- a/pycardano/utils.py +++ b/pycardano/utils.py @@ -23,14 +23,57 @@ "min_lovelace_pre_alonzo", "min_lovelace_post_alonzo", "script_data_hash", + "tiered_reference_script_fee", ] +def tiered_reference_script_fee(context: ChainContext, scripts_size: int) -> int: + """Calculate fee for reference scripts. + + Args: + context (ChainContext): A chain context. + scripts_size (int): Size of reference scripts in bytes. + + Returns: + int: Fee for reference scripts. + + Raises: + ValueError: If scripts size exceeds maximum allowed size + """ + if ( + context.protocol_param.maximum_reference_scripts_size is None + or context.protocol_param.min_fee_reference_scripts is None + ): + return 0 + + max_size = context.protocol_param.maximum_reference_scripts_size["bytes"] + if scripts_size > max_size: + raise ValueError( + f"Reference scripts size: {scripts_size} exceeds maximum allowed size ({max_size})." + ) + + total = 0 + if scripts_size: + b = context.protocol_param.min_fee_reference_scripts["base"] + r = context.protocol_param.min_fee_reference_scripts["range"] + m = context.protocol_param.min_fee_reference_scripts["multiplier"] + + while scripts_size > r: + total += math.ceil(b * r) + scripts_size = math.ceil(scripts_size - r) + b = math.ceil(b * m) + + total += math.ceil(b * scripts_size) + + return total + + def fee( context: ChainContext, length: int, exec_steps: int = 0, max_mem_unit: int = 0, + ref_script_size: int = 0, ) -> int: """Calculate fee based on the length of a transaction's CBOR bytes and script execution. @@ -38,8 +81,9 @@ def fee( context (ChainConext): A chain context. length (int): The length of CBOR bytes, which could usually be derived by `len(tx.to_cbor())`. - exec_steps (Optional[int]): Number of execution steps run by plutus scripts in the transaction. - max_mem_unit (Optional[int]): Max numer of memory units run by plutus scripts in the transaction. + exec_steps (int): Number of execution steps run by plutus scripts in the transaction. + max_mem_unit (int): Max numer of memory units run by plutus scripts in the transaction. + ref_script_size (int): Size of referenced scripts in the transaction. Return: int: Minimum acceptable transaction fee. @@ -49,6 +93,7 @@ def fee( + math.ceil(context.protocol_param.min_fee_constant) + math.ceil(exec_steps * context.protocol_param.price_step) + math.ceil(max_mem_unit * context.protocol_param.price_mem) + + tiered_reference_script_fee(context, ref_script_size) ) diff --git a/pycardano/witness.py b/pycardano/witness.py index 9a62923d..3a38f757 100644 --- a/pycardano/witness.py +++ b/pycardano/witness.py @@ -7,7 +7,13 @@ from pycardano.key import ExtendedVerificationKey, VerificationKey from pycardano.nativescript import NativeScript -from pycardano.plutus import PlutusV1Script, PlutusV2Script, RawPlutusData, Redeemer +from pycardano.plutus import ( + PlutusV1Script, + PlutusV2Script, + PlutusV3Script, + RawPlutusData, + Redeemer, +) from pycardano.serialization import ( ArrayCBORSerializable, MapCBORSerializable, @@ -65,10 +71,6 @@ class TransactionWitnessSet(MapCBORSerializable): default=None, metadata={"optional": True, "key": 3} ) - plutus_v2_script: Optional[List[PlutusV2Script]] = field( - default=None, metadata={"optional": True, "key": 6} - ) - plutus_data: Optional[List[Any]] = field( default=None, metadata={"optional": True, "key": 4, "object_hook": list_hook(RawPlutusData)}, @@ -79,6 +81,14 @@ class TransactionWitnessSet(MapCBORSerializable): metadata={"optional": True, "key": 5, "object_hook": list_hook(Redeemer)}, ) + plutus_v2_script: Optional[List[PlutusV2Script]] = field( + default=None, metadata={"optional": True, "key": 6} + ) + + plutus_v3_script: Optional[List[PlutusV3Script]] = field( + default=None, metadata={"optional": True, "key": 7} + ) + @classmethod @limit_primitive_type(dict, list) def from_primitive( diff --git a/pyproject.toml b/pyproject.toml index 69ae861c..be4a1500 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -64,7 +64,8 @@ addopts = "--doctest-modules --ignore=examples --ignore=integration-test --ignor minversion = "6.0" markers = [ "post_alonzo", - "single" + "single", + "CardanoCLI", ] diff --git a/test/pycardano/test_metadata.py b/test/pycardano/test_metadata.py index 8a7379d3..f8d43af4 100644 --- a/test/pycardano/test_metadata.py +++ b/test/pycardano/test_metadata.py @@ -17,6 +17,7 @@ ScriptAll, ScriptPubkey, ) +from pycardano.plutus import PlutusV1Script M_PRIMITIVE = {123: {"test": b"123", 2: 3, 3: [1, 2, {(1, 2, 3): "token"}]}} @@ -56,9 +57,9 @@ def test_shelley_marry_metadata(): def test_alonzo_metadata(): script = generate_script() m = Metadata(M_PRIMITIVE) - plutus_scripts = [b"fake_script"] + plutus_scripts = [PlutusV1Script(b"fake_script")] - alonzo_m = AlonzoMetadata(m, [script], plutus_scripts) + alonzo_m = AlonzoMetadata(m, [script], plutus_v1_scripts=plutus_scripts) check_two_way_cbor(alonzo_m) @@ -73,11 +74,11 @@ def test_alonzo_metadata(): def test_auxiliary_data(): script = generate_script() - plutus_scripts = [b"fake_script"] + plutus_scripts = [PlutusV1Script(b"fake_script")] m = Metadata(M_PRIMITIVE) shelley_marry_m = ShelleyMarryMetadata(m, [script]) - alonzo_m = AlonzoMetadata(m, [script], plutus_scripts) + alonzo_m = AlonzoMetadata(m, [script], plutus_v1_scripts=plutus_scripts) check_two_way_cbor(AuxiliaryData(m)) check_two_way_cbor(AuxiliaryData(shelley_marry_m)) diff --git a/test/pycardano/util.py b/test/pycardano/util.py index 892b16eb..5f965ac3 100644 --- a/test/pycardano/util.py +++ b/test/pycardano/util.py @@ -46,6 +46,8 @@ class FixedChainContext(ChainContext): coins_per_utxo_word=34482, coins_per_utxo_byte=4310, cost_models={}, + min_fee_reference_scripts={"base": 25600, "range": 44, "multiplier": 1.2}, + maximum_reference_scripts_size={"bytes": 200_000}, ) _genesis_param = GenesisParameters( From 213899fb49a4383429d31f2cacc1b8dce1bdd243 Mon Sep 17 00:00:00 2001 From: Jerry Date: Sat, 3 Aug 2024 17:40:33 -0700 Subject: [PATCH 02/44] Fix docker compose --- integration-test/run_tests.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/integration-test/run_tests.sh b/integration-test/run_tests.sh index a561860c..77b4a755 100755 --- a/integration-test/run_tests.sh +++ b/integration-test/run_tests.sh @@ -62,13 +62,13 @@ poetry run pip install ogmios ######### # Cleanup containers and volumes in case there is any running -docker-compose -f docker-compose-chang.yml down --volumes --remove-orphans +docker compose -f docker-compose-chang.yml down --volumes --remove-orphans # Run integration tests ./bootstrap.sh local-chang # Launch containers -docker-compose -f docker-compose-chang.yml up -d +docker compose -f docker-compose-chang.yml up -d export PAYMENT_KEY="$ROOT"/configs/local-chang/shelley/utxo-keys/utxo1.skey export EXTENDED_PAYMENT_KEY="$ROOT"/keys/extended.skey @@ -80,4 +80,4 @@ export POOL_ID=$(cat "$ROOT"/keys/pool/pool.id) poetry run pytest -m "not (CardanoCLI)" -s -vv -n 4 "$ROOT"/test # Cleanup -docker-compose -f docker-compose-chang.yml down --volumes --remove-orphans \ No newline at end of file +docker compose -f docker-compose-chang.yml down --volumes --remove-orphans \ No newline at end of file From 3e3c5913ae34d6d52c9b4fc66747f95b6bfb3576 Mon Sep 17 00:00:00 2001 From: Jerry Date: Sun, 11 Aug 2024 14:02:49 -0700 Subject: [PATCH 03/44] Minor fixes --- .github/workflows/main.yml | 2 +- integration-test/run_tests.sh | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index bb8ace29..3846c8a6 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -66,7 +66,7 @@ jobs: - name: Dump docker logs if: failure() run: | - cd integration-test && docker-compose logs --no-color > integration-test.log + cd integration-test && docker compose logs --no-color > integration-test.log - name: Upload integration-test.log if: failure() diff --git a/integration-test/run_tests.sh b/integration-test/run_tests.sh index 77b4a755..b86dcfab 100755 --- a/integration-test/run_tests.sh +++ b/integration-test/run_tests.sh @@ -75,7 +75,7 @@ export EXTENDED_PAYMENT_KEY="$ROOT"/keys/extended.skey export POOL_ID=$(cat "$ROOT"/keys/pool/pool.id) # Wait for stake pool to start producing blocks -#sleep 30 +sleep 30 poetry run pytest -m "not (CardanoCLI)" -s -vv -n 4 "$ROOT"/test From 157f23e230d3579b03526bdc981e97e11e1de4b5 Mon Sep 17 00:00:00 2001 From: Jerry Date: Sun, 11 Aug 2024 17:19:31 -0700 Subject: [PATCH 04/44] Add 60s of delay to startTime of genesis --- integration-test/bootstrap.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/integration-test/bootstrap.sh b/integration-test/bootstrap.sh index be5f865f..60ad8640 100755 --- a/integration-test/bootstrap.sh +++ b/integration-test/bootstrap.sh @@ -22,7 +22,7 @@ echo "Bootstrapping network: $NETWORK" if [ "$NETWORK" = "local-alonzo" ] || [ "$NETWORK" = "local-vasil" ] || [ "$NETWORK" = "local-chang" ]; then echo "Updating byron startTime to present in local mode, $NETWORK era" - jq -M ".startTime = ""$(date +%s)" configs/"$NETWORK"/byron-genesis.json > \ + jq -M ".startTime = ($(date +%s) + 60)" configs/"$NETWORK"/byron-genesis.json > \ tmp_configs/"$NETWORK"/byron-genesis.json fi From f6a89c57c3bfe11723d9993906dfb00163544950 Mon Sep 17 00:00:00 2001 From: Niels Date: Wed, 21 Aug 2024 09:34:41 +0200 Subject: [PATCH 05/44] Add an OgmiosV6 backend based on ogmios-python This requires bumping the python version to 3.10+, because ogmios-python requires this. I also refactored the chain backend to not have built-in kupo support but just provide it as an extension using kupo-wrappers. This way, both OgmiosV5 and OgmiosV6 directly have support for kupo. --- integration-test/test/base.py | 2 +- poetry.lock | 1047 +++++++++++------ pycardano/backend/__init__.py | 2 +- pycardano/backend/kupo.py | 230 ++++ pycardano/backend/{ogmios.py => ogmios_v5.py} | 149 +-- pycardano/backend/ogmios_v6.py | 366 ++++++ pyproject.toml | 5 +- test/pycardano/backend/test_ogmios.py | 4 +- 8 files changed, 1346 insertions(+), 459 deletions(-) create mode 100644 pycardano/backend/kupo.py rename pycardano/backend/{ogmios.py => ogmios_v5.py} (77%) create mode 100644 pycardano/backend/ogmios_v6.py diff --git a/integration-test/test/base.py b/integration-test/test/base.py index 2491c4b2..24e56c36 100644 --- a/integration-test/test/base.py +++ b/integration-test/test/base.py @@ -22,7 +22,7 @@ class TestBase: # TODO: Bring back kupo test KUPO_URL = "http://localhost:1442" - chain_context = python_ogmios.OgmiosChainContext( + chain_context = python_ogmios.OgmiosV5ChainContext( host="localhost", port=1337, network=Network.TESTNET ) diff --git a/poetry.lock b/poetry.lock index 7d8d4ff3..a46af1d2 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1,14 +1,25 @@ -# This file is automatically @generated by Poetry 1.8.2 and should not be changed by hand. +# This file is automatically @generated by Poetry 1.8.3 and should not be changed by hand. [[package]] name = "alabaster" -version = "0.7.13" -description = "A configurable sidebar-enabled Sphinx theme" +version = "0.7.16" +description = "A light, configurable Sphinx theme" optional = false -python-versions = ">=3.6" +python-versions = ">=3.9" files = [ - {file = "alabaster-0.7.13-py3-none-any.whl", hash = "sha256:1ee19aca801bbabb5ba3f5f258e4422dfa86f82f3e9cefb0859b283cdd7f62a3"}, - {file = "alabaster-0.7.13.tar.gz", hash = "sha256:a27a4a084d5e690e16e01e03ad2b2e552c61a65469419b907243193de1a84ae2"}, + {file = "alabaster-0.7.16-py3-none-any.whl", hash = "sha256:b46733c07dce03ae4e150330b975c75737fa60f0a7c591b6c8bf4928a28e2c92"}, + {file = "alabaster-0.7.16.tar.gz", hash = "sha256:75a8b99c28a5dad50dd7f8ccdd447a121ddb3892da9e53d1ca5cca3106d58d65"}, +] + +[[package]] +name = "annotated-types" +version = "0.7.0" +description = "Reusable constraint types to use with typing.Annotated" +optional = false +python-versions = ">=3.8" +files = [ + {file = "annotated_types-0.7.0-py3-none-any.whl", hash = "sha256:1f02e8b43a8fbbc3f3e0d4f0f4bfc8131bcb4eebe8849b8e5c773f3a1c582a53"}, + {file = "annotated_types-0.7.0.tar.gz", hash = "sha256:aff07c09a53a08bc8cfccb9c85b05f1aa9a2a6f23728d790723543408344ce89"}, ] [[package]] @@ -24,69 +35,66 @@ files = [ [[package]] name = "attrs" -version = "23.2.0" +version = "24.2.0" description = "Classes Without Boilerplate" optional = false python-versions = ">=3.7" files = [ - {file = "attrs-23.2.0-py3-none-any.whl", hash = "sha256:99b87a485a5820b23b879f04c2305b44b951b502fd64be915879d77a7e8fc6f1"}, - {file = "attrs-23.2.0.tar.gz", hash = "sha256:935dc3b529c262f6cf76e50877d35a4bd3c1de194fd41f47a2b7ae8f19971f30"}, + {file = "attrs-24.2.0-py3-none-any.whl", hash = "sha256:81921eb96de3191c8258c199618104dd27ac608d9366f5e35d011eae1867ede2"}, + {file = "attrs-24.2.0.tar.gz", hash = "sha256:5cfb1b9148b5b086569baec03f20d7b6bf3bcacc9a42bebf87ffaaca362f6346"}, ] [package.extras] -cov = ["attrs[tests]", "coverage[toml] (>=5.3)"] -dev = ["attrs[tests]", "pre-commit"] -docs = ["furo", "myst-parser", "sphinx", "sphinx-notfound-page", "sphinxcontrib-towncrier", "towncrier", "zope-interface"] -tests = ["attrs[tests-no-zope]", "zope-interface"] -tests-mypy = ["mypy (>=1.6)", "pytest-mypy-plugins"] -tests-no-zope = ["attrs[tests-mypy]", "cloudpickle", "hypothesis", "pympler", "pytest (>=4.3.0)", "pytest-xdist[psutil]"] +benchmark = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-codspeed", "pytest-mypy-plugins", "pytest-xdist[psutil]"] +cov = ["cloudpickle", "coverage[toml] (>=5.3)", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] +dev = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pre-commit", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] +docs = ["cogapp", "furo", "myst-parser", "sphinx", "sphinx-notfound-page", "sphinxcontrib-towncrier", "towncrier (<24.7)"] +tests = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] +tests-mypy = ["mypy (>=1.11.1)", "pytest-mypy-plugins"] [[package]] name = "babel" -version = "2.15.0" +version = "2.16.0" description = "Internationalization utilities" optional = false python-versions = ">=3.8" files = [ - {file = "Babel-2.15.0-py3-none-any.whl", hash = "sha256:08706bdad8d0a3413266ab61bd6c34d0c28d6e1e7badf40a2cebe67644e2e1fb"}, - {file = "babel-2.15.0.tar.gz", hash = "sha256:8daf0e265d05768bc6c7a314cf1321e9a123afc328cc635c18622a2f30a04413"}, + {file = "babel-2.16.0-py3-none-any.whl", hash = "sha256:368b5b98b37c06b7daf6696391c3240c938b37767d4584413e8438c5c435fa8b"}, + {file = "babel-2.16.0.tar.gz", hash = "sha256:d1f3554ca26605fe173f3de0c65f750f5a42f924499bf134de6423582298e316"}, ] -[package.dependencies] -pytz = {version = ">=2015.7", markers = "python_version < \"3.9\""} - [package.extras] dev = ["freezegun (>=1.0,<2.0)", "pytest (>=6.0)", "pytest-cov"] [[package]] name = "black" -version = "24.4.2" +version = "24.8.0" description = "The uncompromising code formatter." optional = false python-versions = ">=3.8" files = [ - {file = "black-24.4.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:dd1b5a14e417189db4c7b64a6540f31730713d173f0b63e55fabd52d61d8fdce"}, - {file = "black-24.4.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:8e537d281831ad0e71007dcdcbe50a71470b978c453fa41ce77186bbe0ed6021"}, - {file = "black-24.4.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:eaea3008c281f1038edb473c1aa8ed8143a5535ff18f978a318f10302b254063"}, - {file = "black-24.4.2-cp310-cp310-win_amd64.whl", hash = "sha256:7768a0dbf16a39aa5e9a3ded568bb545c8c2727396d063bbaf847df05b08cd96"}, - {file = "black-24.4.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:257d724c2c9b1660f353b36c802ccece186a30accc7742c176d29c146df6e474"}, - {file = "black-24.4.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:bdde6f877a18f24844e381d45e9947a49e97933573ac9d4345399be37621e26c"}, - {file = "black-24.4.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e151054aa00bad1f4e1f04919542885f89f5f7d086b8a59e5000e6c616896ffb"}, - {file = "black-24.4.2-cp311-cp311-win_amd64.whl", hash = "sha256:7e122b1c4fb252fd85df3ca93578732b4749d9be076593076ef4d07a0233c3e1"}, - {file = "black-24.4.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:accf49e151c8ed2c0cdc528691838afd217c50412534e876a19270fea1e28e2d"}, - {file = "black-24.4.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:88c57dc656038f1ab9f92b3eb5335ee9b021412feaa46330d5eba4e51fe49b04"}, - {file = "black-24.4.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:be8bef99eb46d5021bf053114442914baeb3649a89dc5f3a555c88737e5e98fc"}, - {file = "black-24.4.2-cp312-cp312-win_amd64.whl", hash = "sha256:415e686e87dbbe6f4cd5ef0fbf764af7b89f9057b97c908742b6008cc554b9c0"}, - {file = "black-24.4.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:bf10f7310db693bb62692609b397e8d67257c55f949abde4c67f9cc574492cc7"}, - {file = "black-24.4.2-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:98e123f1d5cfd42f886624d84464f7756f60ff6eab89ae845210631714f6db94"}, - {file = "black-24.4.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:48a85f2cb5e6799a9ef05347b476cce6c182d6c71ee36925a6c194d074336ef8"}, - {file = "black-24.4.2-cp38-cp38-win_amd64.whl", hash = "sha256:b1530ae42e9d6d5b670a34db49a94115a64596bc77710b1d05e9801e62ca0a7c"}, - {file = "black-24.4.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:37aae07b029fa0174d39daf02748b379399b909652a806e5708199bd93899da1"}, - {file = "black-24.4.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:da33a1a5e49c4122ccdfd56cd021ff1ebc4a1ec4e2d01594fef9b6f267a9e741"}, - {file = "black-24.4.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ef703f83fc32e131e9bcc0a5094cfe85599e7109f896fe8bc96cc402f3eb4b6e"}, - {file = "black-24.4.2-cp39-cp39-win_amd64.whl", hash = "sha256:b9176b9832e84308818a99a561e90aa479e73c523b3f77afd07913380ae2eab7"}, - {file = "black-24.4.2-py3-none-any.whl", hash = "sha256:d36ed1124bb81b32f8614555b34cc4259c3fbc7eec17870e8ff8ded335b58d8c"}, - {file = "black-24.4.2.tar.gz", hash = "sha256:c872b53057f000085da66a19c55d68f6f8ddcac2642392ad3a355878406fbd4d"}, + {file = "black-24.8.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:09cdeb74d494ec023ded657f7092ba518e8cf78fa8386155e4a03fdcc44679e6"}, + {file = "black-24.8.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:81c6742da39f33b08e791da38410f32e27d632260e599df7245cccee2064afeb"}, + {file = "black-24.8.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:707a1ca89221bc8a1a64fb5e15ef39cd755633daa672a9db7498d1c19de66a42"}, + {file = "black-24.8.0-cp310-cp310-win_amd64.whl", hash = "sha256:d6417535d99c37cee4091a2f24eb2b6d5ec42b144d50f1f2e436d9fe1916fe1a"}, + {file = "black-24.8.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:fb6e2c0b86bbd43dee042e48059c9ad7830abd5c94b0bc518c0eeec57c3eddc1"}, + {file = "black-24.8.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:837fd281f1908d0076844bc2b801ad2d369c78c45cf800cad7b61686051041af"}, + {file = "black-24.8.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:62e8730977f0b77998029da7971fa896ceefa2c4c4933fcd593fa599ecbf97a4"}, + {file = "black-24.8.0-cp311-cp311-win_amd64.whl", hash = "sha256:72901b4913cbac8972ad911dc4098d5753704d1f3c56e44ae8dce99eecb0e3af"}, + {file = "black-24.8.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:7c046c1d1eeb7aea9335da62472481d3bbf3fd986e093cffd35f4385c94ae368"}, + {file = "black-24.8.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:649f6d84ccbae73ab767e206772cc2d7a393a001070a4c814a546afd0d423aed"}, + {file = "black-24.8.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:2b59b250fdba5f9a9cd9d0ece6e6d993d91ce877d121d161e4698af3eb9c1018"}, + {file = "black-24.8.0-cp312-cp312-win_amd64.whl", hash = "sha256:6e55d30d44bed36593c3163b9bc63bf58b3b30e4611e4d88a0c3c239930ed5b2"}, + {file = "black-24.8.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:505289f17ceda596658ae81b61ebbe2d9b25aa78067035184ed0a9d855d18afd"}, + {file = "black-24.8.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:b19c9ad992c7883ad84c9b22aaa73562a16b819c1d8db7a1a1a49fb7ec13c7d2"}, + {file = "black-24.8.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:1f13f7f386f86f8121d76599114bb8c17b69d962137fc70efe56137727c7047e"}, + {file = "black-24.8.0-cp38-cp38-win_amd64.whl", hash = "sha256:f490dbd59680d809ca31efdae20e634f3fae27fba3ce0ba3208333b713bc3920"}, + {file = "black-24.8.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:eab4dd44ce80dea27dc69db40dab62d4ca96112f87996bca68cd75639aeb2e4c"}, + {file = "black-24.8.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:3c4285573d4897a7610054af5a890bde7c65cb466040c5f0c8b732812d7f0e5e"}, + {file = "black-24.8.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:9e84e33b37be070ba135176c123ae52a51f82306def9f7d063ee302ecab2cf47"}, + {file = "black-24.8.0-cp39-cp39-win_amd64.whl", hash = "sha256:73bbf84ed136e45d451a260c6b73ed674652f90a2b3211d6a35e78054563a9bb"}, + {file = "black-24.8.0-py3-none-any.whl", hash = "sha256:972085c618ee94f402da1af548a4f218c754ea7e5dc70acb168bfaca4c2542ed"}, + {file = "black-24.8.0.tar.gz", hash = "sha256:2500945420b6784c38b9ee885af039f5e7471ef284ab03fa35ecdde4688cd83f"}, ] [package.dependencies] @@ -131,59 +139,74 @@ requests = "*" [[package]] name = "cachetools" -version = "5.3.3" +version = "5.5.0" description = "Extensible memoizing collections and decorators" optional = false python-versions = ">=3.7" files = [ - {file = "cachetools-5.3.3-py3-none-any.whl", hash = "sha256:0abad1021d3f8325b2fc1d2e9c8b9c9d57b04c3932657a72465447332c24d945"}, - {file = "cachetools-5.3.3.tar.gz", hash = "sha256:ba29e2dfa0b8b556606f097407ed1aa62080ee108ab0dc5ec9d6a723a007d105"}, + {file = "cachetools-5.5.0-py3-none-any.whl", hash = "sha256:02134e8439cdc2ffb62023ce1debca2944c3f289d66bb17ead3ab3dede74b292"}, + {file = "cachetools-5.5.0.tar.gz", hash = "sha256:2cc24fb4cbe39633fb7badd9db9ca6295d766d9c2995f245725a46715d050f2a"}, +] + +[[package]] +name = "cardano-tools" +version = "2.1.0" +description = "A collection of tools to enable development in the Cardano ecosystem using the Python programming language." +optional = false +python-versions = ">=3.8,<4.0" +files = [ + {file = "cardano_tools-2.1.0-py3-none-any.whl", hash = "sha256:c562c234b3d9a51540d41432f88aeae9a68c9441e0ea363c675dd712380ca06c"}, + {file = "cardano_tools-2.1.0.tar.gz", hash = "sha256:445c8a5c769f57e5e04494ac4e3012082c3d0f1bd9a9eaed7f834d37ad7a069e"}, ] +[package.dependencies] +pexpect = ">=4.8.0,<5.0.0" +requests = ">=2.28.0,<3.0.0" + [[package]] name = "cbor2" -version = "5.6.3" +version = "5.6.4" description = "CBOR (de)serializer with extensive tag support" optional = false python-versions = ">=3.8" files = [ - {file = "cbor2-5.6.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0201d5e8d9ad1557aeb50d35b907c0f170de0ae9ebb484b2894bcee3b2e13b80"}, - {file = "cbor2-5.6.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:eda6965cca276d4c2cebdbee14572dec65b991c5359fc32a793f03f052e35985"}, - {file = "cbor2-5.6.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:14561038b8eaab3fd5e867f09bc43f7525a1405e41ade14066925ea3d42513a8"}, - {file = "cbor2-5.6.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9a3cf6b339a005031e4b8c79b9541856e3b0077ea4c33d7bb6a019885136f53a"}, - {file = "cbor2-5.6.3-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:4b7636d39de203ee30ac13575ed3e9a0510e993fa1671022b84b9e35e369825f"}, - {file = "cbor2-5.6.3-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:23847075ce1bcda871c7698e5db0635685995ae470098a5e4c9a26c00f65f21a"}, - {file = "cbor2-5.6.3-cp310-cp310-win_amd64.whl", hash = "sha256:ca15be7142e861fb9f918e0248620b4d4153b9ff14ef6034f7204db5db2924a1"}, - {file = "cbor2-5.6.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:b07ee755ae5b0dfad608dab37364b35895cab5d1222653da1fea32a10330c4b0"}, - {file = "cbor2-5.6.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:9fc063843c14e9e95181faf8d807a53c958d77bb9d360eb4f2344d075ecfed36"}, - {file = "cbor2-5.6.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c66d4c227c2ed6c63ec5c2d50eb8ec0e1c41c07b452a867544e48ca41d4f0b64"}, - {file = "cbor2-5.6.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3af60ac82a733bfdfb2b1079c850fefea2621bdb8c8f87f4c5d12802d48a8c55"}, - {file = "cbor2-5.6.3-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:acb93292843aa72768f089a135bfeec4c9b745132e8dc22f1b149490fc77cb0a"}, - {file = "cbor2-5.6.3-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:193d1abdffd52893710d39389daa5c03e1569421cdf53585a28033689aef7aec"}, - {file = "cbor2-5.6.3-cp311-cp311-win_amd64.whl", hash = "sha256:d0c915db92b441f505f8a14a521c9461439ac8e5d959454845eb92f93db0bb3b"}, - {file = "cbor2-5.6.3-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:9eaec8c04618124a6b597fe4471035cb7cb0d5114f43aaf2062821ad480ef57c"}, - {file = "cbor2-5.6.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:d1e5181d4f858237ab4e1a28e21bdcaf31dab2657ab60a8d4a0701a078fe5926"}, - {file = "cbor2-5.6.3-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:277997127402710a3abdf4372ac75e8f8bb2e75a303cd789312e515c8ef657dd"}, - {file = "cbor2-5.6.3-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:add01e4b4663199940d10f8c8e1d926e70823d1b2f3f981cc097a4764125f110"}, - {file = "cbor2-5.6.3-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:adc87485ffd7a4dad481e08e6819eebfcfbafc0918fffcca47aee4cdf8c6de04"}, - {file = "cbor2-5.6.3-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:ea4a0412426155c3b78763449db56cf5c72c48788a37d7e60bd66c844b9c8634"}, - {file = "cbor2-5.6.3-cp312-cp312-win_amd64.whl", hash = "sha256:18b3dee4eddde9761c60298ce21c0cd4e770237978034c5ee1d4242e255683ec"}, - {file = "cbor2-5.6.3-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:ff6fd1c54b97ee322c0b7180092305ca3b012ff78fddadad97b33490f5f8881f"}, - {file = "cbor2-5.6.3-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:ac6f10b9d25f2d61c036f86238bf23e3ea0253f98faa8ab00f67228bf3c0ce2a"}, - {file = "cbor2-5.6.3-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7be74f2cbda547fdd57c83ee5b3470804f02c660db28efcf9d4016f001b66f40"}, - {file = "cbor2-5.6.3-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:64ea120206f82492a4385bbc5e2639f9b67c8bc7bdc57bffcbe9a8fee8cd6342"}, - {file = "cbor2-5.6.3-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:c3d2902e1aed155d56cdcae99cd4a9dae843e3fff6978148d2d5d5f9a0b986cd"}, - {file = "cbor2-5.6.3-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:2d4f95a567e26d8d9d62db234cd089525c52f19e7fdd59152629d9f03bd94b4f"}, - {file = "cbor2-5.6.3-cp38-cp38-win_amd64.whl", hash = "sha256:33efbe7103bac090430d291fca2fe1c444b0ec55c4716e8051b72a81377e8b79"}, - {file = "cbor2-5.6.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:81e619a2a59ae966cedb5fd3ea8a9487a3d4430824bbeacdcf5f74ad6112cc57"}, - {file = "cbor2-5.6.3-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:2b7755b93d32638f4d79a0fa0744b423787f6faa3c96ccccac68b6dbf1848368"}, - {file = "cbor2-5.6.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0f0e95011ae8460265ef348fe380664fa22c51015fd52344ebd781579fa9552a"}, - {file = "cbor2-5.6.3-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7693e53c3ba0b2ad4e46b610f8d69159ffdbcb6ebe75ea1c1f5f40c3283639ca"}, - {file = "cbor2-5.6.3-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:e3ec251db32516d383fc587874b15f4b5fb4e9049d9436b8696f5767b11c149b"}, - {file = "cbor2-5.6.3-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:6081c1ab9791d5973a40b95ecb8b04b0fbf9fc04be170d89a3ad77d5964f52d5"}, - {file = "cbor2-5.6.3-cp39-cp39-win_amd64.whl", hash = "sha256:2aba8b75e36c9f84a42a7026271da8fd759035a871c1b799028439059527276b"}, - {file = "cbor2-5.6.3-py3-none-any.whl", hash = "sha256:8a4b7404af6da719092a4ee5953d1930d095b93b684bf99e1ab74512be1910a4"}, - {file = "cbor2-5.6.3.tar.gz", hash = "sha256:e6f0ae2751c2d333a960e0807c0611494eb1245631a167965acbc100509455d3"}, + {file = "cbor2-5.6.4-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:c40c68779a363f47a11ded7b189ba16767391d5eae27fac289e7f62b730ae1fc"}, + {file = "cbor2-5.6.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:c0625c8d3c487e509458459de99bf052f62eb5d773cc9fc141c6a6ea9367726d"}, + {file = "cbor2-5.6.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:de7137622204168c3a57882f15dd09b5135bda2bcb1cf8b56b58d26b5150dfca"}, + {file = "cbor2-5.6.4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e3545e1e62ec48944b81da2c0e0a736ca98b9e4653c2365cae2f10ae871e9113"}, + {file = "cbor2-5.6.4-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:d6749913cd00a24eba17406a0bfc872044036c30a37eb2fcde7acfd975317e8a"}, + {file = "cbor2-5.6.4-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:57db966ab08443ee54b6f154f72021a41bfecd4ba897fe108728183ad8784a2a"}, + {file = "cbor2-5.6.4-cp310-cp310-win_amd64.whl", hash = "sha256:380e0c7f4db574dcd86e6eee1b0041863b0aae7efd449d49b0b784cf9a481b9b"}, + {file = "cbor2-5.6.4-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:5c763d50a1714e0356b90ad39194fc8ef319356b89fb001667a2e836bfde88e3"}, + {file = "cbor2-5.6.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:58a7ac8861857a9f9b0de320a4808a2a5f68a2599b4c14863e2748d5a4686c99"}, + {file = "cbor2-5.6.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7d715b2f101730335e84a25fe0893e2b6adf049d6d44da123bf243b8c875ffd8"}, + {file = "cbor2-5.6.4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3f53a67600038cb9668720b309fdfafa8c16d1a02570b96d2144d58d66774318"}, + {file = "cbor2-5.6.4-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:f898bab20c4f42dca3688c673ff97c2f719b1811090430173c94452603fbcf13"}, + {file = "cbor2-5.6.4-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:5e5d50fb9f47d295c1b7f55592111350424283aff4cc88766c656aad0300f11f"}, + {file = "cbor2-5.6.4-cp311-cp311-win_amd64.whl", hash = "sha256:7f9d867dcd814ab8383ad132eb4063e2b69f6a9f688797b7a8ca34a4eadb3944"}, + {file = "cbor2-5.6.4-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:e0860ca88edf8aaec5461ce0e498eb5318f1bcc70d93f90091b7a1f1d351a167"}, + {file = "cbor2-5.6.4-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:c38a0ed495a63a8bef6400158746a9cb03c36f89aeed699be7ffebf82720bf86"}, + {file = "cbor2-5.6.4-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0c8d8c2f208c223a61bed48dfd0661694b891e423094ed30bac2ed75032142aa"}, + {file = "cbor2-5.6.4-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:24cd2ce6136e1985da989e5ba572521023a320dcefad5d1fff57fba261de80ca"}, + {file = "cbor2-5.6.4-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:7facce04aed2bf69ef43bdffb725446fe243594c2451921e89cc305bede16f02"}, + {file = "cbor2-5.6.4-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:f9c8ee0d89411e5e039a4f3419befe8b43c0dd8746eedc979e73f4c06fe0ef97"}, + {file = "cbor2-5.6.4-cp312-cp312-win_amd64.whl", hash = "sha256:9b45d554daa540e2f29f1747df9f08f8d98ade65a67b1911791bc193d33a5923"}, + {file = "cbor2-5.6.4-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:0a5cb2c16687ccd76b38cfbfdb34468ab7d5635fb92c9dc5e07831c1816bd0a9"}, + {file = "cbor2-5.6.4-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:6f985f531f7495527153c4f66c8c143e4cf8a658ec9e87b14bc5438e0a8d0911"}, + {file = "cbor2-5.6.4-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a9d9c7b4bd7c3ea7e5587d4f1bbe073b81719530ddadb999b184074f064896e2"}, + {file = "cbor2-5.6.4-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:64d06184dcdc275c389fee3cd0ea80b5e1769763df15f93ecd0bf4c281817365"}, + {file = "cbor2-5.6.4-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:e9ba7116f201860fb4c3e80ef36be63851ec7e4a18af70fea22d09cab0b000bf"}, + {file = "cbor2-5.6.4-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:341468ae58bdedaa05c907ab16e90dd0d5c54d7d1e66698dfacdbc16a31e815b"}, + {file = "cbor2-5.6.4-cp38-cp38-win_amd64.whl", hash = "sha256:bcb4994be1afcc81f9167c220645d878b608cae92e19f6706e770f9bc7bbff6c"}, + {file = "cbor2-5.6.4-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:41c43abffe217dce70ae51c7086530687670a0995dfc90cc35f32f2cf4d86392"}, + {file = "cbor2-5.6.4-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:227a7e68ba378fe53741ed892b5b03fe472b5bd23ef26230a71964accebf50a2"}, + {file = "cbor2-5.6.4-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:13521b7c9a0551fcc812d36afd03fc554fa4e1b193659bb5d4d521889aa81154"}, + {file = "cbor2-5.6.4-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6f4816d290535d20c7b7e2663b76da5b0deb4237b90275c202c26343d8852b8a"}, + {file = "cbor2-5.6.4-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:1e98d370106821335efcc8fbe4136ea26b4747bf29ca0e66512b6c4f6f5cc59f"}, + {file = "cbor2-5.6.4-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:68743a18e16167ff37654a29321f64f0441801dba68359c82dc48173cc6c87e1"}, + {file = "cbor2-5.6.4-cp39-cp39-win_amd64.whl", hash = "sha256:7ba5e9c6ed17526d266a1116c045c0941f710860c5f2495758df2e0d848c1b6d"}, + {file = "cbor2-5.6.4-py3-none-any.whl", hash = "sha256:fe411c4bf464f5976605103ebcd0f60b893ac3e4c7c8d8bc8f4a0cb456e33c60"}, + {file = "cbor2-5.6.4.tar.gz", hash = "sha256:1c533c50dde86bef1c6950602054a0ffa3c376e8b0e20c7b8f5b108793f6983e"}, ] [package.extras] @@ -193,13 +216,13 @@ test = ["coverage (>=7)", "hypothesis", "pytest"] [[package]] name = "certifi" -version = "2024.2.2" +version = "2024.7.4" description = "Python package for providing Mozilla's CA Bundle." optional = false python-versions = ">=3.6" files = [ - {file = "certifi-2024.2.2-py3-none-any.whl", hash = "sha256:dc383c07b76109f368f6106eee2b593b04a011ea4d55f652c6ca24a754d1cdd1"}, - {file = "certifi-2024.2.2.tar.gz", hash = "sha256:0569859f95fc761b18b45ef421b1290a0f65f147e92a1e5eb3e635f9a5e4e66f"}, + {file = "certifi-2024.7.4-py3-none-any.whl", hash = "sha256:c198e21b1289c2ab85ee4e67bb4b4ef3ead0892059901a8d5b622f24a1101e90"}, + {file = "certifi-2024.7.4.tar.gz", hash = "sha256:5a1e7645bc0ec61a09e26c36f6106dd4cf40c6db3a1fb6352b0244e7fb057c7b"}, ] [[package]] @@ -219,63 +242,78 @@ oscrypto = ">=0.16.1" [[package]] name = "cffi" -version = "1.16.0" +version = "1.17.0" description = "Foreign Function Interface for Python calling C code." optional = false python-versions = ">=3.8" files = [ - {file = "cffi-1.16.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:6b3d6606d369fc1da4fd8c357d026317fbb9c9b75d36dc16e90e84c26854b088"}, - {file = "cffi-1.16.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:ac0f5edd2360eea2f1daa9e26a41db02dd4b0451b48f7c318e217ee092a213e9"}, - {file = "cffi-1.16.0-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7e61e3e4fa664a8588aa25c883eab612a188c725755afff6289454d6362b9673"}, - {file = "cffi-1.16.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a72e8961a86d19bdb45851d8f1f08b041ea37d2bd8d4fd19903bc3083d80c896"}, - {file = "cffi-1.16.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5b50bf3f55561dac5438f8e70bfcdfd74543fd60df5fa5f62d94e5867deca684"}, - {file = "cffi-1.16.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7651c50c8c5ef7bdb41108b7b8c5a83013bfaa8a935590c5d74627c047a583c7"}, - {file = "cffi-1.16.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e4108df7fe9b707191e55f33efbcb2d81928e10cea45527879a4749cbe472614"}, - {file = "cffi-1.16.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:32c68ef735dbe5857c810328cb2481e24722a59a2003018885514d4c09af9743"}, - {file = "cffi-1.16.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:673739cb539f8cdaa07d92d02efa93c9ccf87e345b9a0b556e3ecc666718468d"}, - {file = "cffi-1.16.0-cp310-cp310-win32.whl", hash = "sha256:9f90389693731ff1f659e55c7d1640e2ec43ff725cc61b04b2f9c6d8d017df6a"}, - {file = "cffi-1.16.0-cp310-cp310-win_amd64.whl", hash = "sha256:e6024675e67af929088fda399b2094574609396b1decb609c55fa58b028a32a1"}, - {file = "cffi-1.16.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:b84834d0cf97e7d27dd5b7f3aca7b6e9263c56308ab9dc8aae9784abb774d404"}, - {file = "cffi-1.16.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:1b8ebc27c014c59692bb2664c7d13ce7a6e9a629be20e54e7271fa696ff2b417"}, - {file = "cffi-1.16.0-cp311-cp311-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ee07e47c12890ef248766a6e55bd38ebfb2bb8edd4142d56db91b21ea68b7627"}, - {file = "cffi-1.16.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d8a9d3ebe49f084ad71f9269834ceccbf398253c9fac910c4fd7053ff1386936"}, - {file = "cffi-1.16.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e70f54f1796669ef691ca07d046cd81a29cb4deb1e5f942003f401c0c4a2695d"}, - {file = "cffi-1.16.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5bf44d66cdf9e893637896c7faa22298baebcd18d1ddb6d2626a6e39793a1d56"}, - {file = "cffi-1.16.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7b78010e7b97fef4bee1e896df8a4bbb6712b7f05b7ef630f9d1da00f6444d2e"}, - {file = "cffi-1.16.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:c6a164aa47843fb1b01e941d385aab7215563bb8816d80ff3a363a9f8448a8dc"}, - {file = "cffi-1.16.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:e09f3ff613345df5e8c3667da1d918f9149bd623cd9070c983c013792a9a62eb"}, - {file = "cffi-1.16.0-cp311-cp311-win32.whl", hash = "sha256:2c56b361916f390cd758a57f2e16233eb4f64bcbeee88a4881ea90fca14dc6ab"}, - {file = "cffi-1.16.0-cp311-cp311-win_amd64.whl", hash = "sha256:db8e577c19c0fda0beb7e0d4e09e0ba74b1e4c092e0e40bfa12fe05b6f6d75ba"}, - {file = "cffi-1.16.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:fa3a0128b152627161ce47201262d3140edb5a5c3da88d73a1b790a959126956"}, - {file = "cffi-1.16.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:68e7c44931cc171c54ccb702482e9fc723192e88d25a0e133edd7aff8fcd1f6e"}, - {file = "cffi-1.16.0-cp312-cp312-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:abd808f9c129ba2beda4cfc53bde801e5bcf9d6e0f22f095e45327c038bfe68e"}, - {file = "cffi-1.16.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:88e2b3c14bdb32e440be531ade29d3c50a1a59cd4e51b1dd8b0865c54ea5d2e2"}, - {file = "cffi-1.16.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:fcc8eb6d5902bb1cf6dc4f187ee3ea80a1eba0a89aba40a5cb20a5087d961357"}, - {file = "cffi-1.16.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b7be2d771cdba2942e13215c4e340bfd76398e9227ad10402a8767ab1865d2e6"}, - {file = "cffi-1.16.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e715596e683d2ce000574bae5d07bd522c781a822866c20495e52520564f0969"}, - {file = "cffi-1.16.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:2d92b25dbf6cae33f65005baf472d2c245c050b1ce709cc4588cdcdd5495b520"}, - {file = "cffi-1.16.0-cp312-cp312-win32.whl", hash = "sha256:b2ca4e77f9f47c55c194982e10f058db063937845bb2b7a86c84a6cfe0aefa8b"}, - {file = "cffi-1.16.0-cp312-cp312-win_amd64.whl", hash = "sha256:68678abf380b42ce21a5f2abde8efee05c114c2fdb2e9eef2efdb0257fba1235"}, - {file = "cffi-1.16.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:0c9ef6ff37e974b73c25eecc13952c55bceed9112be2d9d938ded8e856138bcc"}, - {file = "cffi-1.16.0-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a09582f178759ee8128d9270cd1344154fd473bb77d94ce0aeb2a93ebf0feaf0"}, - {file = "cffi-1.16.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e760191dd42581e023a68b758769e2da259b5d52e3103c6060ddc02c9edb8d7b"}, - {file = "cffi-1.16.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:80876338e19c951fdfed6198e70bc88f1c9758b94578d5a7c4c91a87af3cf31c"}, - {file = "cffi-1.16.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a6a14b17d7e17fa0d207ac08642c8820f84f25ce17a442fd15e27ea18d67c59b"}, - {file = "cffi-1.16.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6602bc8dc6f3a9e02b6c22c4fc1e47aa50f8f8e6d3f78a5e16ac33ef5fefa324"}, - {file = "cffi-1.16.0-cp38-cp38-win32.whl", hash = "sha256:131fd094d1065b19540c3d72594260f118b231090295d8c34e19a7bbcf2e860a"}, - {file = "cffi-1.16.0-cp38-cp38-win_amd64.whl", hash = "sha256:31d13b0f99e0836b7ff893d37af07366ebc90b678b6664c955b54561fc36ef36"}, - {file = "cffi-1.16.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:582215a0e9adbe0e379761260553ba11c58943e4bbe9c36430c4ca6ac74b15ed"}, - {file = "cffi-1.16.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:b29ebffcf550f9da55bec9e02ad430c992a87e5f512cd63388abb76f1036d8d2"}, - {file = "cffi-1.16.0-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:dc9b18bf40cc75f66f40a7379f6a9513244fe33c0e8aa72e2d56b0196a7ef872"}, - {file = "cffi-1.16.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9cb4a35b3642fc5c005a6755a5d17c6c8b6bcb6981baf81cea8bfbc8903e8ba8"}, - {file = "cffi-1.16.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b86851a328eedc692acf81fb05444bdf1891747c25af7529e39ddafaf68a4f3f"}, - {file = "cffi-1.16.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c0f31130ebc2d37cdd8e44605fb5fa7ad59049298b3f745c74fa74c62fbfcfc4"}, - {file = "cffi-1.16.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8f8e709127c6c77446a8c0a8c8bf3c8ee706a06cd44b1e827c3e6a2ee6b8c098"}, - {file = "cffi-1.16.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:748dcd1e3d3d7cd5443ef03ce8685043294ad6bd7c02a38d1bd367cfd968e000"}, - {file = "cffi-1.16.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:8895613bcc094d4a1b2dbe179d88d7fb4a15cee43c052e8885783fac397d91fe"}, - {file = "cffi-1.16.0-cp39-cp39-win32.whl", hash = "sha256:ed86a35631f7bfbb28e108dd96773b9d5a6ce4811cf6ea468bb6a359b256b1e4"}, - {file = "cffi-1.16.0-cp39-cp39-win_amd64.whl", hash = "sha256:3686dffb02459559c74dd3d81748269ffb0eb027c39a6fc99502de37d501faa8"}, - {file = "cffi-1.16.0.tar.gz", hash = "sha256:bcb3ef43e58665bbda2fb198698fcae6776483e0c4a631aa5647806c25e02cc0"}, + {file = "cffi-1.17.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:f9338cc05451f1942d0d8203ec2c346c830f8e86469903d5126c1f0a13a2bcbb"}, + {file = "cffi-1.17.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:a0ce71725cacc9ebf839630772b07eeec220cbb5f03be1399e0457a1464f8e1a"}, + {file = "cffi-1.17.0-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c815270206f983309915a6844fe994b2fa47e5d05c4c4cef267c3b30e34dbe42"}, + {file = "cffi-1.17.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d6bdcd415ba87846fd317bee0774e412e8792832e7805938987e4ede1d13046d"}, + {file = "cffi-1.17.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8a98748ed1a1df4ee1d6f927e151ed6c1a09d5ec21684de879c7ea6aa96f58f2"}, + {file = "cffi-1.17.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:0a048d4f6630113e54bb4b77e315e1ba32a5a31512c31a273807d0027a7e69ab"}, + {file = "cffi-1.17.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:24aa705a5f5bd3a8bcfa4d123f03413de5d86e497435693b638cbffb7d5d8a1b"}, + {file = "cffi-1.17.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:856bf0924d24e7f93b8aee12a3a1095c34085600aa805693fb7f5d1962393206"}, + {file = "cffi-1.17.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:4304d4416ff032ed50ad6bb87416d802e67139e31c0bde4628f36a47a3164bfa"}, + {file = "cffi-1.17.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:331ad15c39c9fe9186ceaf87203a9ecf5ae0ba2538c9e898e3a6967e8ad3db6f"}, + {file = "cffi-1.17.0-cp310-cp310-win32.whl", hash = "sha256:669b29a9eca6146465cc574659058ed949748f0809a2582d1f1a324eb91054dc"}, + {file = "cffi-1.17.0-cp310-cp310-win_amd64.whl", hash = "sha256:48b389b1fd5144603d61d752afd7167dfd205973a43151ae5045b35793232aa2"}, + {file = "cffi-1.17.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:c5d97162c196ce54af6700949ddf9409e9833ef1003b4741c2b39ef46f1d9720"}, + {file = "cffi-1.17.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:5ba5c243f4004c750836f81606a9fcb7841f8874ad8f3bf204ff5e56332b72b9"}, + {file = "cffi-1.17.0-cp311-cp311-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:bb9333f58fc3a2296fb1d54576138d4cf5d496a2cc118422bd77835e6ae0b9cb"}, + {file = "cffi-1.17.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:435a22d00ec7d7ea533db494da8581b05977f9c37338c80bc86314bec2619424"}, + {file = "cffi-1.17.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d1df34588123fcc88c872f5acb6f74ae59e9d182a2707097f9e28275ec26a12d"}, + {file = "cffi-1.17.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:df8bb0010fdd0a743b7542589223a2816bdde4d94bb5ad67884348fa2c1c67e8"}, + {file = "cffi-1.17.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a8b5b9712783415695663bd463990e2f00c6750562e6ad1d28e072a611c5f2a6"}, + {file = "cffi-1.17.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:ffef8fd58a36fb5f1196919638f73dd3ae0db1a878982b27a9a5a176ede4ba91"}, + {file = "cffi-1.17.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:4e67d26532bfd8b7f7c05d5a766d6f437b362c1bf203a3a5ce3593a645e870b8"}, + {file = "cffi-1.17.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:45f7cd36186db767d803b1473b3c659d57a23b5fa491ad83c6d40f2af58e4dbb"}, + {file = "cffi-1.17.0-cp311-cp311-win32.whl", hash = "sha256:a9015f5b8af1bb6837a3fcb0cdf3b874fe3385ff6274e8b7925d81ccaec3c5c9"}, + {file = "cffi-1.17.0-cp311-cp311-win_amd64.whl", hash = "sha256:b50aaac7d05c2c26dfd50c3321199f019ba76bb650e346a6ef3616306eed67b0"}, + {file = "cffi-1.17.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:aec510255ce690d240f7cb23d7114f6b351c733a74c279a84def763660a2c3bc"}, + {file = "cffi-1.17.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:2770bb0d5e3cc0e31e7318db06efcbcdb7b31bcb1a70086d3177692a02256f59"}, + {file = "cffi-1.17.0-cp312-cp312-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:db9a30ec064129d605d0f1aedc93e00894b9334ec74ba9c6bdd08147434b33eb"}, + {file = "cffi-1.17.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a47eef975d2b8b721775a0fa286f50eab535b9d56c70a6e62842134cf7841195"}, + {file = "cffi-1.17.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f3e0992f23bbb0be00a921eae5363329253c3b86287db27092461c887b791e5e"}, + {file = "cffi-1.17.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:6107e445faf057c118d5050560695e46d272e5301feffda3c41849641222a828"}, + {file = "cffi-1.17.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:eb862356ee9391dc5a0b3cbc00f416b48c1b9a52d252d898e5b7696a5f9fe150"}, + {file = "cffi-1.17.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:c1c13185b90bbd3f8b5963cd8ce7ad4ff441924c31e23c975cb150e27c2bf67a"}, + {file = "cffi-1.17.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:17c6d6d3260c7f2d94f657e6872591fe8733872a86ed1345bda872cfc8c74885"}, + {file = "cffi-1.17.0-cp312-cp312-win32.whl", hash = "sha256:c3b8bd3133cd50f6b637bb4322822c94c5ce4bf0d724ed5ae70afce62187c492"}, + {file = "cffi-1.17.0-cp312-cp312-win_amd64.whl", hash = "sha256:dca802c8db0720ce1c49cce1149ff7b06e91ba15fa84b1d59144fef1a1bc7ac2"}, + {file = "cffi-1.17.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:6ce01337d23884b21c03869d2f68c5523d43174d4fc405490eb0091057943118"}, + {file = "cffi-1.17.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:cab2eba3830bf4f6d91e2d6718e0e1c14a2f5ad1af68a89d24ace0c6b17cced7"}, + {file = "cffi-1.17.0-cp313-cp313-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:14b9cbc8f7ac98a739558eb86fabc283d4d564dafed50216e7f7ee62d0d25377"}, + {file = "cffi-1.17.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b00e7bcd71caa0282cbe3c90966f738e2db91e64092a877c3ff7f19a1628fdcb"}, + {file = "cffi-1.17.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:41f4915e09218744d8bae14759f983e466ab69b178de38066f7579892ff2a555"}, + {file = "cffi-1.17.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e4760a68cab57bfaa628938e9c2971137e05ce48e762a9cb53b76c9b569f1204"}, + {file = "cffi-1.17.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:011aff3524d578a9412c8b3cfaa50f2c0bd78e03eb7af7aa5e0df59b158efb2f"}, + {file = "cffi-1.17.0-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:a003ac9edc22d99ae1286b0875c460351f4e101f8c9d9d2576e78d7e048f64e0"}, + {file = "cffi-1.17.0-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:ef9528915df81b8f4c7612b19b8628214c65c9b7f74db2e34a646a0a2a0da2d4"}, + {file = "cffi-1.17.0-cp313-cp313-win32.whl", hash = "sha256:70d2aa9fb00cf52034feac4b913181a6e10356019b18ef89bc7c12a283bf5f5a"}, + {file = "cffi-1.17.0-cp313-cp313-win_amd64.whl", hash = "sha256:b7b6ea9e36d32582cda3465f54c4b454f62f23cb083ebc7a94e2ca6ef011c3a7"}, + {file = "cffi-1.17.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:964823b2fc77b55355999ade496c54dde161c621cb1f6eac61dc30ed1b63cd4c"}, + {file = "cffi-1.17.0-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:516a405f174fd3b88829eabfe4bb296ac602d6a0f68e0d64d5ac9456194a5b7e"}, + {file = "cffi-1.17.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dec6b307ce928e8e112a6bb9921a1cb00a0e14979bf28b98e084a4b8a742bd9b"}, + {file = "cffi-1.17.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e4094c7b464cf0a858e75cd14b03509e84789abf7b79f8537e6a72152109c76e"}, + {file = "cffi-1.17.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2404f3de742f47cb62d023f0ba7c5a916c9c653d5b368cc966382ae4e57da401"}, + {file = "cffi-1.17.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3aa9d43b02a0c681f0bfbc12d476d47b2b2b6a3f9287f11ee42989a268a1833c"}, + {file = "cffi-1.17.0-cp38-cp38-win32.whl", hash = "sha256:0bb15e7acf8ab35ca8b24b90af52c8b391690ef5c4aec3d31f38f0d37d2cc499"}, + {file = "cffi-1.17.0-cp38-cp38-win_amd64.whl", hash = "sha256:93a7350f6706b31f457c1457d3a3259ff9071a66f312ae64dc024f049055f72c"}, + {file = "cffi-1.17.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:1a2ddbac59dc3716bc79f27906c010406155031a1c801410f1bafff17ea304d2"}, + {file = "cffi-1.17.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:6327b572f5770293fc062a7ec04160e89741e8552bf1c358d1a23eba68166759"}, + {file = "cffi-1.17.0-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:dbc183e7bef690c9abe5ea67b7b60fdbca81aa8da43468287dae7b5c046107d4"}, + {file = "cffi-1.17.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5bdc0f1f610d067c70aa3737ed06e2726fd9d6f7bfee4a351f4c40b6831f4e82"}, + {file = "cffi-1.17.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:6d872186c1617d143969defeadac5a904e6e374183e07977eedef9c07c8953bf"}, + {file = "cffi-1.17.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:0d46ee4764b88b91f16661a8befc6bfb24806d885e27436fdc292ed7e6f6d058"}, + {file = "cffi-1.17.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6f76a90c345796c01d85e6332e81cab6d70de83b829cf1d9762d0a3da59c7932"}, + {file = "cffi-1.17.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:0e60821d312f99d3e1569202518dddf10ae547e799d75aef3bca3a2d9e8ee693"}, + {file = "cffi-1.17.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:eb09b82377233b902d4c3fbeeb7ad731cdab579c6c6fda1f763cd779139e47c3"}, + {file = "cffi-1.17.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:24658baf6224d8f280e827f0a50c46ad819ec8ba380a42448e24459daf809cf4"}, + {file = "cffi-1.17.0-cp39-cp39-win32.whl", hash = "sha256:0fdacad9e0d9fc23e519efd5ea24a70348305e8d7d85ecbb1a5fa66dc834e7fb"}, + {file = "cffi-1.17.0-cp39-cp39-win_amd64.whl", hash = "sha256:7cbc78dc018596315d4e7841c8c3a7ae31cc4d638c9b627f87d52e8abaaf2d29"}, + {file = "cffi-1.17.0.tar.gz", hash = "sha256:f3157624b7558b914cb039fd1af735e5e8049a87c817cc215109ad1c8779df76"}, ] [package.dependencies] @@ -405,6 +443,23 @@ files = [ {file = "colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44"}, ] +[[package]] +name = "coloredlogs" +version = "15.0.1" +description = "Colored terminal output for Python's logging module" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" +files = [ + {file = "coloredlogs-15.0.1-py2.py3-none-any.whl", hash = "sha256:612ee75c546f53e92e70049c9dbfcc18c935a2b9a53b66085ce9ef6a6e5c0934"}, + {file = "coloredlogs-15.0.1.tar.gz", hash = "sha256:7c991aa71a4577af2f82600d8f8f3a89f936baeaf9b50a9c197da014e5bf16b0"}, +] + +[package.dependencies] +humanfriendly = ">=9.1" + +[package.extras] +cron = ["capturer (>=2.4)"] + [[package]] name = "cose" version = "0.9.dev8" @@ -425,63 +480,83 @@ ecdsa = "*" [[package]] name = "coverage" -version = "7.5.3" +version = "7.6.1" description = "Code coverage measurement for Python" optional = false python-versions = ">=3.8" files = [ - {file = "coverage-7.5.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:a6519d917abb15e12380406d721e37613e2a67d166f9fb7e5a8ce0375744cd45"}, - {file = "coverage-7.5.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:aea7da970f1feccf48be7335f8b2ca64baf9b589d79e05b9397a06696ce1a1ec"}, - {file = "coverage-7.5.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:923b7b1c717bd0f0f92d862d1ff51d9b2b55dbbd133e05680204465f454bb286"}, - {file = "coverage-7.5.3-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:62bda40da1e68898186f274f832ef3e759ce929da9a9fd9fcf265956de269dbc"}, - {file = "coverage-7.5.3-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d8b7339180d00de83e930358223c617cc343dd08e1aa5ec7b06c3a121aec4e1d"}, - {file = "coverage-7.5.3-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:25a5caf742c6195e08002d3b6c2dd6947e50efc5fc2c2205f61ecb47592d2d83"}, - {file = "coverage-7.5.3-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:05ac5f60faa0c704c0f7e6a5cbfd6f02101ed05e0aee4d2822637a9e672c998d"}, - {file = "coverage-7.5.3-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:239a4e75e09c2b12ea478d28815acf83334d32e722e7433471fbf641c606344c"}, - {file = "coverage-7.5.3-cp310-cp310-win32.whl", hash = "sha256:a5812840d1d00eafae6585aba38021f90a705a25b8216ec7f66aebe5b619fb84"}, - {file = "coverage-7.5.3-cp310-cp310-win_amd64.whl", hash = "sha256:33ca90a0eb29225f195e30684ba4a6db05dbef03c2ccd50b9077714c48153cac"}, - {file = "coverage-7.5.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:f81bc26d609bf0fbc622c7122ba6307993c83c795d2d6f6f6fd8c000a770d974"}, - {file = "coverage-7.5.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:7cec2af81f9e7569280822be68bd57e51b86d42e59ea30d10ebdbb22d2cb7232"}, - {file = "coverage-7.5.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:55f689f846661e3f26efa535071775d0483388a1ccfab899df72924805e9e7cd"}, - {file = "coverage-7.5.3-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:50084d3516aa263791198913a17354bd1dc627d3c1639209640b9cac3fef5807"}, - {file = "coverage-7.5.3-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:341dd8f61c26337c37988345ca5c8ccabeff33093a26953a1ac72e7d0103c4fb"}, - {file = "coverage-7.5.3-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:ab0b028165eea880af12f66086694768f2c3139b2c31ad5e032c8edbafca6ffc"}, - {file = "coverage-7.5.3-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:5bc5a8c87714b0c67cfeb4c7caa82b2d71e8864d1a46aa990b5588fa953673b8"}, - {file = "coverage-7.5.3-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:38a3b98dae8a7c9057bd91fbf3415c05e700a5114c5f1b5b0ea5f8f429ba6614"}, - {file = "coverage-7.5.3-cp311-cp311-win32.whl", hash = "sha256:fcf7d1d6f5da887ca04302db8e0e0cf56ce9a5e05f202720e49b3e8157ddb9a9"}, - {file = "coverage-7.5.3-cp311-cp311-win_amd64.whl", hash = "sha256:8c836309931839cca658a78a888dab9676b5c988d0dd34ca247f5f3e679f4e7a"}, - {file = "coverage-7.5.3-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:296a7d9bbc598e8744c00f7a6cecf1da9b30ae9ad51c566291ff1314e6cbbed8"}, - {file = "coverage-7.5.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:34d6d21d8795a97b14d503dcaf74226ae51eb1f2bd41015d3ef332a24d0a17b3"}, - {file = "coverage-7.5.3-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8e317953bb4c074c06c798a11dbdd2cf9979dbcaa8ccc0fa4701d80042d4ebf1"}, - {file = "coverage-7.5.3-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:705f3d7c2b098c40f5b81790a5fedb274113373d4d1a69e65f8b68b0cc26f6db"}, - {file = "coverage-7.5.3-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b1196e13c45e327d6cd0b6e471530a1882f1017eb83c6229fc613cd1a11b53cd"}, - {file = "coverage-7.5.3-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:015eddc5ccd5364dcb902eaecf9515636806fa1e0d5bef5769d06d0f31b54523"}, - {file = "coverage-7.5.3-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:fd27d8b49e574e50caa65196d908f80e4dff64d7e592d0c59788b45aad7e8b35"}, - {file = "coverage-7.5.3-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:33fc65740267222fc02975c061eb7167185fef4cc8f2770267ee8bf7d6a42f84"}, - {file = "coverage-7.5.3-cp312-cp312-win32.whl", hash = "sha256:7b2a19e13dfb5c8e145c7a6ea959485ee8e2204699903c88c7d25283584bfc08"}, - {file = "coverage-7.5.3-cp312-cp312-win_amd64.whl", hash = "sha256:0bbddc54bbacfc09b3edaec644d4ac90c08ee8ed4844b0f86227dcda2d428fcb"}, - {file = "coverage-7.5.3-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:f78300789a708ac1f17e134593f577407d52d0417305435b134805c4fb135adb"}, - {file = "coverage-7.5.3-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:b368e1aee1b9b75757942d44d7598dcd22a9dbb126affcbba82d15917f0cc155"}, - {file = "coverage-7.5.3-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f836c174c3a7f639bded48ec913f348c4761cbf49de4a20a956d3431a7c9cb24"}, - {file = "coverage-7.5.3-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:244f509f126dc71369393ce5fea17c0592c40ee44e607b6d855e9c4ac57aac98"}, - {file = "coverage-7.5.3-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c4c2872b3c91f9baa836147ca33650dc5c172e9273c808c3c3199c75490e709d"}, - {file = "coverage-7.5.3-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:dd4b3355b01273a56b20c219e74e7549e14370b31a4ffe42706a8cda91f19f6d"}, - {file = "coverage-7.5.3-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:f542287b1489c7a860d43a7d8883e27ca62ab84ca53c965d11dac1d3a1fab7ce"}, - {file = "coverage-7.5.3-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:75e3f4e86804023e991096b29e147e635f5e2568f77883a1e6eed74512659ab0"}, - {file = "coverage-7.5.3-cp38-cp38-win32.whl", hash = "sha256:c59d2ad092dc0551d9f79d9d44d005c945ba95832a6798f98f9216ede3d5f485"}, - {file = "coverage-7.5.3-cp38-cp38-win_amd64.whl", hash = "sha256:fa21a04112c59ad54f69d80e376f7f9d0f5f9123ab87ecd18fbb9ec3a2beed56"}, - {file = "coverage-7.5.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:f5102a92855d518b0996eb197772f5ac2a527c0ec617124ad5242a3af5e25f85"}, - {file = "coverage-7.5.3-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:d1da0a2e3b37b745a2b2a678a4c796462cf753aebf94edcc87dcc6b8641eae31"}, - {file = "coverage-7.5.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8383a6c8cefba1b7cecc0149415046b6fc38836295bc4c84e820872eb5478b3d"}, - {file = "coverage-7.5.3-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9aad68c3f2566dfae84bf46295a79e79d904e1c21ccfc66de88cd446f8686341"}, - {file = "coverage-7.5.3-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2e079c9ec772fedbade9d7ebc36202a1d9ef7291bc9b3a024ca395c4d52853d7"}, - {file = "coverage-7.5.3-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:bde997cac85fcac227b27d4fb2c7608a2c5f6558469b0eb704c5726ae49e1c52"}, - {file = "coverage-7.5.3-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:990fb20b32990b2ce2c5f974c3e738c9358b2735bc05075d50a6f36721b8f303"}, - {file = "coverage-7.5.3-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:3d5a67f0da401e105753d474369ab034c7bae51a4c31c77d94030d59e41df5bd"}, - {file = "coverage-7.5.3-cp39-cp39-win32.whl", hash = "sha256:e08c470c2eb01977d221fd87495b44867a56d4d594f43739a8028f8646a51e0d"}, - {file = "coverage-7.5.3-cp39-cp39-win_amd64.whl", hash = "sha256:1d2a830ade66d3563bb61d1e3c77c8def97b30ed91e166c67d0632c018f380f0"}, - {file = "coverage-7.5.3-pp38.pp39.pp310-none-any.whl", hash = "sha256:3538d8fb1ee9bdd2e2692b3b18c22bb1c19ffbefd06880f5ac496e42d7bb3884"}, - {file = "coverage-7.5.3.tar.gz", hash = "sha256:04aefca5190d1dc7a53a4c1a5a7f8568811306d7a8ee231c42fb69215571944f"}, + {file = "coverage-7.6.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:b06079abebbc0e89e6163b8e8f0e16270124c154dc6e4a47b413dd538859af16"}, + {file = "coverage-7.6.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:cf4b19715bccd7ee27b6b120e7e9dd56037b9c0681dcc1adc9ba9db3d417fa36"}, + {file = "coverage-7.6.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e61c0abb4c85b095a784ef23fdd4aede7a2628478e7baba7c5e3deba61070a02"}, + {file = "coverage-7.6.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:fd21f6ae3f08b41004dfb433fa895d858f3f5979e7762d052b12aef444e29afc"}, + {file = "coverage-7.6.1-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8f59d57baca39b32db42b83b2a7ba6f47ad9c394ec2076b084c3f029b7afca23"}, + {file = "coverage-7.6.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:a1ac0ae2b8bd743b88ed0502544847c3053d7171a3cff9228af618a068ed9c34"}, + {file = "coverage-7.6.1-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:e6a08c0be454c3b3beb105c0596ebdc2371fab6bb90c0c0297f4e58fd7e1012c"}, + {file = "coverage-7.6.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:f5796e664fe802da4f57a168c85359a8fbf3eab5e55cd4e4569fbacecc903959"}, + {file = "coverage-7.6.1-cp310-cp310-win32.whl", hash = "sha256:7bb65125fcbef8d989fa1dd0e8a060999497629ca5b0efbca209588a73356232"}, + {file = "coverage-7.6.1-cp310-cp310-win_amd64.whl", hash = "sha256:3115a95daa9bdba70aea750db7b96b37259a81a709223c8448fa97727d546fe0"}, + {file = "coverage-7.6.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:7dea0889685db8550f839fa202744652e87c60015029ce3f60e006f8c4462c93"}, + {file = "coverage-7.6.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:ed37bd3c3b063412f7620464a9ac1314d33100329f39799255fb8d3027da50d3"}, + {file = "coverage-7.6.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d85f5e9a5f8b73e2350097c3756ef7e785f55bd71205defa0bfdaf96c31616ff"}, + {file = "coverage-7.6.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9bc572be474cafb617672c43fe989d6e48d3c83af02ce8de73fff1c6bb3c198d"}, + {file = "coverage-7.6.1-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0c0420b573964c760df9e9e86d1a9a622d0d27f417e1a949a8a66dd7bcee7bc6"}, + {file = "coverage-7.6.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:1f4aa8219db826ce6be7099d559f8ec311549bfc4046f7f9fe9b5cea5c581c56"}, + {file = "coverage-7.6.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:fc5a77d0c516700ebad189b587de289a20a78324bc54baee03dd486f0855d234"}, + {file = "coverage-7.6.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:b48f312cca9621272ae49008c7f613337c53fadca647d6384cc129d2996d1133"}, + {file = "coverage-7.6.1-cp311-cp311-win32.whl", hash = "sha256:1125ca0e5fd475cbbba3bb67ae20bd2c23a98fac4e32412883f9bcbaa81c314c"}, + {file = "coverage-7.6.1-cp311-cp311-win_amd64.whl", hash = "sha256:8ae539519c4c040c5ffd0632784e21b2f03fc1340752af711f33e5be83a9d6c6"}, + {file = "coverage-7.6.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:95cae0efeb032af8458fc27d191f85d1717b1d4e49f7cb226cf526ff28179778"}, + {file = "coverage-7.6.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:5621a9175cf9d0b0c84c2ef2b12e9f5f5071357c4d2ea6ca1cf01814f45d2391"}, + {file = "coverage-7.6.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:260933720fdcd75340e7dbe9060655aff3af1f0c5d20f46b57f262ab6c86a5e8"}, + {file = "coverage-7.6.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:07e2ca0ad381b91350c0ed49d52699b625aab2b44b65e1b4e02fa9df0e92ad2d"}, + {file = "coverage-7.6.1-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c44fee9975f04b33331cb8eb272827111efc8930cfd582e0320613263ca849ca"}, + {file = "coverage-7.6.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:877abb17e6339d96bf08e7a622d05095e72b71f8afd8a9fefc82cf30ed944163"}, + {file = "coverage-7.6.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:3e0cadcf6733c09154b461f1ca72d5416635e5e4ec4e536192180d34ec160f8a"}, + {file = "coverage-7.6.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:c3c02d12f837d9683e5ab2f3d9844dc57655b92c74e286c262e0fc54213c216d"}, + {file = "coverage-7.6.1-cp312-cp312-win32.whl", hash = "sha256:e05882b70b87a18d937ca6768ff33cc3f72847cbc4de4491c8e73880766718e5"}, + {file = "coverage-7.6.1-cp312-cp312-win_amd64.whl", hash = "sha256:b5d7b556859dd85f3a541db6a4e0167b86e7273e1cdc973e5b175166bb634fdb"}, + {file = "coverage-7.6.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:a4acd025ecc06185ba2b801f2de85546e0b8ac787cf9d3b06e7e2a69f925b106"}, + {file = "coverage-7.6.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:a6d3adcf24b624a7b778533480e32434a39ad8fa30c315208f6d3e5542aeb6e9"}, + {file = "coverage-7.6.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d0c212c49b6c10e6951362f7c6df3329f04c2b1c28499563d4035d964ab8e08c"}, + {file = "coverage-7.6.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6e81d7a3e58882450ec4186ca59a3f20a5d4440f25b1cff6f0902ad890e6748a"}, + {file = "coverage-7.6.1-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:78b260de9790fd81e69401c2dc8b17da47c8038176a79092a89cb2b7d945d060"}, + {file = "coverage-7.6.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:a78d169acd38300060b28d600344a803628c3fd585c912cacc9ea8790fe96862"}, + {file = "coverage-7.6.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:2c09f4ce52cb99dd7505cd0fc8e0e37c77b87f46bc9c1eb03fe3bc9991085388"}, + {file = "coverage-7.6.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:6878ef48d4227aace338d88c48738a4258213cd7b74fd9a3d4d7582bb1d8a155"}, + {file = "coverage-7.6.1-cp313-cp313-win32.whl", hash = "sha256:44df346d5215a8c0e360307d46ffaabe0f5d3502c8a1cefd700b34baf31d411a"}, + {file = "coverage-7.6.1-cp313-cp313-win_amd64.whl", hash = "sha256:8284cf8c0dd272a247bc154eb6c95548722dce90d098c17a883ed36e67cdb129"}, + {file = "coverage-7.6.1-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:d3296782ca4eab572a1a4eca686d8bfb00226300dcefdf43faa25b5242ab8a3e"}, + {file = "coverage-7.6.1-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:502753043567491d3ff6d08629270127e0c31d4184c4c8d98f92c26f65019962"}, + {file = "coverage-7.6.1-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6a89ecca80709d4076b95f89f308544ec8f7b4727e8a547913a35f16717856cb"}, + {file = "coverage-7.6.1-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a318d68e92e80af8b00fa99609796fdbcdfef3629c77c6283566c6f02c6d6704"}, + {file = "coverage-7.6.1-cp313-cp313t-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:13b0a73a0896988f053e4fbb7de6d93388e6dd292b0d87ee51d106f2c11b465b"}, + {file = "coverage-7.6.1-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:4421712dbfc5562150f7554f13dde997a2e932a6b5f352edcce948a815efee6f"}, + {file = "coverage-7.6.1-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:166811d20dfea725e2e4baa71fffd6c968a958577848d2131f39b60043400223"}, + {file = "coverage-7.6.1-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:225667980479a17db1048cb2bf8bfb39b8e5be8f164b8f6628b64f78a72cf9d3"}, + {file = "coverage-7.6.1-cp313-cp313t-win32.whl", hash = "sha256:170d444ab405852903b7d04ea9ae9b98f98ab6d7e63e1115e82620807519797f"}, + {file = "coverage-7.6.1-cp313-cp313t-win_amd64.whl", hash = "sha256:b9f222de8cded79c49bf184bdbc06630d4c58eec9459b939b4a690c82ed05657"}, + {file = "coverage-7.6.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:6db04803b6c7291985a761004e9060b2bca08da6d04f26a7f2294b8623a0c1a0"}, + {file = "coverage-7.6.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:f1adfc8ac319e1a348af294106bc6a8458a0f1633cc62a1446aebc30c5fa186a"}, + {file = "coverage-7.6.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a95324a9de9650a729239daea117df21f4b9868ce32e63f8b650ebe6cef5595b"}, + {file = "coverage-7.6.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b43c03669dc4618ec25270b06ecd3ee4fa94c7f9b3c14bae6571ca00ef98b0d3"}, + {file = "coverage-7.6.1-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8929543a7192c13d177b770008bc4e8119f2e1f881d563fc6b6305d2d0ebe9de"}, + {file = "coverage-7.6.1-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:a09ece4a69cf399510c8ab25e0950d9cf2b42f7b3cb0374f95d2e2ff594478a6"}, + {file = "coverage-7.6.1-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:9054a0754de38d9dbd01a46621636689124d666bad1936d76c0341f7d71bf569"}, + {file = "coverage-7.6.1-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:0dbde0f4aa9a16fa4d754356a8f2e36296ff4d83994b2c9d8398aa32f222f989"}, + {file = "coverage-7.6.1-cp38-cp38-win32.whl", hash = "sha256:da511e6ad4f7323ee5702e6633085fb76c2f893aaf8ce4c51a0ba4fc07580ea7"}, + {file = "coverage-7.6.1-cp38-cp38-win_amd64.whl", hash = "sha256:3f1156e3e8f2872197af3840d8ad307a9dd18e615dc64d9ee41696f287c57ad8"}, + {file = "coverage-7.6.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:abd5fd0db5f4dc9289408aaf34908072f805ff7792632250dcb36dc591d24255"}, + {file = "coverage-7.6.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:547f45fa1a93154bd82050a7f3cddbc1a7a4dd2a9bf5cb7d06f4ae29fe94eaf8"}, + {file = "coverage-7.6.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:645786266c8f18a931b65bfcefdbf6952dd0dea98feee39bd188607a9d307ed2"}, + {file = "coverage-7.6.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9e0b2df163b8ed01d515807af24f63de04bebcecbd6c3bfeff88385789fdf75a"}, + {file = "coverage-7.6.1-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:609b06f178fe8e9f89ef676532760ec0b4deea15e9969bf754b37f7c40326dbc"}, + {file = "coverage-7.6.1-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:702855feff378050ae4f741045e19a32d57d19f3e0676d589df0575008ea5004"}, + {file = "coverage-7.6.1-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:2bdb062ea438f22d99cba0d7829c2ef0af1d768d1e4a4f528087224c90b132cb"}, + {file = "coverage-7.6.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:9c56863d44bd1c4fe2abb8a4d6f5371d197f1ac0ebdee542f07f35895fc07f36"}, + {file = "coverage-7.6.1-cp39-cp39-win32.whl", hash = "sha256:6e2cd258d7d927d09493c8df1ce9174ad01b381d4729a9d8d4e38670ca24774c"}, + {file = "coverage-7.6.1-cp39-cp39-win_amd64.whl", hash = "sha256:06a737c882bd26d0d6ee7269b20b12f14a8704807a01056c80bb881a4b2ce6ca"}, + {file = "coverage-7.6.1-pp38.pp39.pp310-none-any.whl", hash = "sha256:e9a6e0eb86070e8ccaedfbd9d38fec54864f3125ab95419970575b42af7541df"}, + {file = "coverage-7.6.1.tar.gz", hash = "sha256:953510dfb7b12ab69d20135a0662397f077c59b1e6379a768e97c59d852ee51d"}, ] [package.dependencies] @@ -492,43 +567,38 @@ toml = ["tomli"] [[package]] name = "cryptography" -version = "42.0.7" +version = "43.0.0" description = "cryptography is a package which provides cryptographic recipes and primitives to Python developers." optional = false python-versions = ">=3.7" files = [ - {file = "cryptography-42.0.7-cp37-abi3-macosx_10_12_universal2.whl", hash = "sha256:a987f840718078212fdf4504d0fd4c6effe34a7e4740378e59d47696e8dfb477"}, - {file = "cryptography-42.0.7-cp37-abi3-macosx_10_12_x86_64.whl", hash = "sha256:bd13b5e9b543532453de08bcdc3cc7cebec6f9883e886fd20a92f26940fd3e7a"}, - {file = "cryptography-42.0.7-cp37-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a79165431551042cc9d1d90e6145d5d0d3ab0f2d66326c201d9b0e7f5bf43604"}, - {file = "cryptography-42.0.7-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a47787a5e3649008a1102d3df55424e86606c9bae6fb77ac59afe06d234605f8"}, - {file = "cryptography-42.0.7-cp37-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:02c0eee2d7133bdbbc5e24441258d5d2244beb31da5ed19fbb80315f4bbbff55"}, - {file = "cryptography-42.0.7-cp37-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:5e44507bf8d14b36b8389b226665d597bc0f18ea035d75b4e53c7b1ea84583cc"}, - {file = "cryptography-42.0.7-cp37-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:7f8b25fa616d8b846aef64b15c606bb0828dbc35faf90566eb139aa9cff67af2"}, - {file = "cryptography-42.0.7-cp37-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:93a3209f6bb2b33e725ed08ee0991b92976dfdcf4e8b38646540674fc7508e13"}, - {file = "cryptography-42.0.7-cp37-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:e6b8f1881dac458c34778d0a424ae5769de30544fc678eac51c1c8bb2183e9da"}, - {file = "cryptography-42.0.7-cp37-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:3de9a45d3b2b7d8088c3fbf1ed4395dfeff79d07842217b38df14ef09ce1d8d7"}, - {file = "cryptography-42.0.7-cp37-abi3-win32.whl", hash = "sha256:789caea816c6704f63f6241a519bfa347f72fbd67ba28d04636b7c6b7da94b0b"}, - {file = "cryptography-42.0.7-cp37-abi3-win_amd64.whl", hash = "sha256:8cb8ce7c3347fcf9446f201dc30e2d5a3c898d009126010cbd1f443f28b52678"}, - {file = "cryptography-42.0.7-cp39-abi3-macosx_10_12_universal2.whl", hash = "sha256:a3a5ac8b56fe37f3125e5b72b61dcde43283e5370827f5233893d461b7360cd4"}, - {file = "cryptography-42.0.7-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:779245e13b9a6638df14641d029add5dc17edbef6ec915688f3acb9e720a5858"}, - {file = "cryptography-42.0.7-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0d563795db98b4cd57742a78a288cdbdc9daedac29f2239793071fe114f13785"}, - {file = "cryptography-42.0.7-cp39-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:31adb7d06fe4383226c3e963471f6837742889b3c4caa55aac20ad951bc8ffda"}, - {file = "cryptography-42.0.7-cp39-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:efd0bf5205240182e0f13bcaea41be4fdf5c22c5129fc7ced4a0282ac86998c9"}, - {file = "cryptography-42.0.7-cp39-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:a9bc127cdc4ecf87a5ea22a2556cab6c7eda2923f84e4f3cc588e8470ce4e42e"}, - {file = "cryptography-42.0.7-cp39-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:3577d029bc3f4827dd5bf8bf7710cac13527b470bbf1820a3f394adb38ed7d5f"}, - {file = "cryptography-42.0.7-cp39-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:2e47577f9b18723fa294b0ea9a17d5e53a227867a0a4904a1a076d1646d45ca1"}, - {file = "cryptography-42.0.7-cp39-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:1a58839984d9cb34c855197043eaae2c187d930ca6d644612843b4fe8513c886"}, - {file = "cryptography-42.0.7-cp39-abi3-win32.whl", hash = "sha256:e6b79d0adb01aae87e8a44c2b64bc3f3fe59515280e00fb6d57a7267a2583cda"}, - {file = "cryptography-42.0.7-cp39-abi3-win_amd64.whl", hash = "sha256:16268d46086bb8ad5bf0a2b5544d8a9ed87a0e33f5e77dd3c3301e63d941a83b"}, - {file = "cryptography-42.0.7-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:2954fccea107026512b15afb4aa664a5640cd0af630e2ee3962f2602693f0c82"}, - {file = "cryptography-42.0.7-pp310-pypy310_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:362e7197754c231797ec45ee081f3088a27a47c6c01eff2ac83f60f85a50fe60"}, - {file = "cryptography-42.0.7-pp310-pypy310_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:4f698edacf9c9e0371112792558d2f705b5645076cc0aaae02f816a0171770fd"}, - {file = "cryptography-42.0.7-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:5482e789294854c28237bba77c4c83be698be740e31a3ae5e879ee5444166582"}, - {file = "cryptography-42.0.7-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:e9b2a6309f14c0497f348d08a065d52f3020656f675819fc405fb63bbcd26562"}, - {file = "cryptography-42.0.7-pp39-pypy39_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:d8e3098721b84392ee45af2dd554c947c32cc52f862b6a3ae982dbb90f577f14"}, - {file = "cryptography-42.0.7-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:c65f96dad14f8528a447414125e1fc8feb2ad5a272b8f68477abbcc1ea7d94b9"}, - {file = "cryptography-42.0.7-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:36017400817987670037fbb0324d71489b6ead6231c9604f8fc1f7d008087c68"}, - {file = "cryptography-42.0.7.tar.gz", hash = "sha256:ecbfbc00bf55888edda9868a4cf927205de8499e7fabe6c050322298382953f2"}, + {file = "cryptography-43.0.0-cp37-abi3-macosx_10_9_universal2.whl", hash = "sha256:64c3f16e2a4fc51c0d06af28441881f98c5d91009b8caaff40cf3548089e9c74"}, + {file = "cryptography-43.0.0-cp37-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3dcdedae5c7710b9f97ac6bba7e1052b95c7083c9d0e9df96e02a1932e777895"}, + {file = "cryptography-43.0.0-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3d9a1eca329405219b605fac09ecfc09ac09e595d6def650a437523fcd08dd22"}, + {file = "cryptography-43.0.0-cp37-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:ea9e57f8ea880eeea38ab5abf9fbe39f923544d7884228ec67d666abd60f5a47"}, + {file = "cryptography-43.0.0-cp37-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:9a8d6802e0825767476f62aafed40532bd435e8a5f7d23bd8b4f5fd04cc80ecf"}, + {file = "cryptography-43.0.0-cp37-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:cc70b4b581f28d0a254d006f26949245e3657d40d8857066c2ae22a61222ef55"}, + {file = "cryptography-43.0.0-cp37-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:4a997df8c1c2aae1e1e5ac49c2e4f610ad037fc5a3aadc7b64e39dea42249431"}, + {file = "cryptography-43.0.0-cp37-abi3-win32.whl", hash = "sha256:6e2b11c55d260d03a8cf29ac9b5e0608d35f08077d8c087be96287f43af3ccdc"}, + {file = "cryptography-43.0.0-cp37-abi3-win_amd64.whl", hash = "sha256:31e44a986ceccec3d0498e16f3d27b2ee5fdf69ce2ab89b52eaad1d2f33d8778"}, + {file = "cryptography-43.0.0-cp39-abi3-macosx_10_9_universal2.whl", hash = "sha256:7b3f5fe74a5ca32d4d0f302ffe6680fcc5c28f8ef0dc0ae8f40c0f3a1b4fca66"}, + {file = "cryptography-43.0.0-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ac1955ce000cb29ab40def14fd1bbfa7af2017cca696ee696925615cafd0dce5"}, + {file = "cryptography-43.0.0-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:299d3da8e00b7e2b54bb02ef58d73cd5f55fb31f33ebbf33bd00d9aa6807df7e"}, + {file = "cryptography-43.0.0-cp39-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:ee0c405832ade84d4de74b9029bedb7b31200600fa524d218fc29bfa371e97f5"}, + {file = "cryptography-43.0.0-cp39-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:cb013933d4c127349b3948aa8aaf2f12c0353ad0eccd715ca789c8a0f671646f"}, + {file = "cryptography-43.0.0-cp39-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:fdcb265de28585de5b859ae13e3846a8e805268a823a12a4da2597f1f5afc9f0"}, + {file = "cryptography-43.0.0-cp39-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:2905ccf93a8a2a416f3ec01b1a7911c3fe4073ef35640e7ee5296754e30b762b"}, + {file = "cryptography-43.0.0-cp39-abi3-win32.whl", hash = "sha256:47ca71115e545954e6c1d207dd13461ab81f4eccfcb1345eac874828b5e3eaaf"}, + {file = "cryptography-43.0.0-cp39-abi3-win_amd64.whl", hash = "sha256:0663585d02f76929792470451a5ba64424acc3cd5227b03921dab0e2f27b1709"}, + {file = "cryptography-43.0.0-pp310-pypy310_pp73-macosx_10_9_x86_64.whl", hash = "sha256:2c6d112bf61c5ef44042c253e4859b3cbbb50df2f78fa8fae6747a7814484a70"}, + {file = "cryptography-43.0.0-pp310-pypy310_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:844b6d608374e7d08f4f6e6f9f7b951f9256db41421917dfb2d003dde4cd6b66"}, + {file = "cryptography-43.0.0-pp310-pypy310_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:51956cf8730665e2bdf8ddb8da0056f699c1a5715648c1b0144670c1ba00b48f"}, + {file = "cryptography-43.0.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:aae4d918f6b180a8ab8bf6511a419473d107df4dbb4225c7b48c5c9602c38c7f"}, + {file = "cryptography-43.0.0-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:232ce02943a579095a339ac4b390fbbe97f5b5d5d107f8a08260ea2768be8cc2"}, + {file = "cryptography-43.0.0-pp39-pypy39_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:5bcb8a5620008a8034d39bce21dc3e23735dfdb6a33a06974739bfa04f853947"}, + {file = "cryptography-43.0.0-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:08a24a7070b2b6804c1940ff0f910ff728932a9d0e80e7814234269f9d46d069"}, + {file = "cryptography-43.0.0-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:e9c5266c432a1e23738d178e51c2c7a5e2ddf790f248be939448c0ba2021f9d1"}, + {file = "cryptography-43.0.0.tar.gz", hash = "sha256:b88075ada2d51aa9f18283532c9f60e72170041bba88d7f37e49cbb10275299e"}, ] [package.dependencies] @@ -541,7 +611,7 @@ nox = ["nox"] pep8test = ["check-sdist", "click", "mypy", "ruff"] sdist = ["build"] ssh = ["bcrypt (>=3.1.5)"] -test = ["certifi", "pretend", "pytest (>=6.2.0)", "pytest-benchmark", "pytest-cov", "pytest-xdist"] +test = ["certifi", "cryptography-vectors (==43.0.0)", "pretend", "pytest (>=6.2.0)", "pytest-benchmark", "pytest-cov", "pytest-xdist"] test-randomorder = ["pytest-randomly"] [[package]] @@ -619,13 +689,13 @@ files = [ [[package]] name = "exceptiongroup" -version = "1.2.1" +version = "1.2.2" description = "Backport of PEP 654 (exception groups)" optional = false python-versions = ">=3.7" files = [ - {file = "exceptiongroup-1.2.1-py3-none-any.whl", hash = "sha256:5258b9ed329c5bbdd31a309f53cbfb0b155341807f6ff7606a1e801a891b29ad"}, - {file = "exceptiongroup-1.2.1.tar.gz", hash = "sha256:a4785e48b045528f5bfe627b6ad554ff32def154f42372786903b7abcfe1aa16"}, + {file = "exceptiongroup-1.2.2-py3-none-any.whl", hash = "sha256:3111b9d131c238bec2f8f516e123e14ba243563fb135d3fe885990585aa7795b"}, + {file = "exceptiongroup-1.2.2.tar.gz", hash = "sha256:47c2edf7c6738fafb49fd34290706d1a1a2f4d1c6df275526b62cbb4aa5393cc"}, ] [package.extras] @@ -647,18 +717,18 @@ testing = ["hatch", "pre-commit", "pytest", "tox"] [[package]] name = "flake8" -version = "7.0.0" +version = "7.1.1" description = "the modular source code checker: pep8 pyflakes and co" optional = false python-versions = ">=3.8.1" files = [ - {file = "flake8-7.0.0-py2.py3-none-any.whl", hash = "sha256:a6dfbb75e03252917f2473ea9653f7cd799c3064e54d4c8140044c5c065f53c3"}, - {file = "flake8-7.0.0.tar.gz", hash = "sha256:33f96621059e65eec474169085dc92bf26e7b2d47366b70be2f67ab80dc25132"}, + {file = "flake8-7.1.1-py2.py3-none-any.whl", hash = "sha256:597477df7860daa5aa0fdd84bf5208a043ab96b8e96ab708770ae0364dd03213"}, + {file = "flake8-7.1.1.tar.gz", hash = "sha256:049d058491e228e03e67b390f311bbf88fce2dbaa8fa673e7aea87b7198b8d38"}, ] [package.dependencies] mccabe = ">=0.7.0,<0.8.0" -pycodestyle = ">=2.11.0,<2.12.0" +pycodestyle = ">=2.12.0,<2.13.0" pyflakes = ">=3.2.0,<3.3.0" [[package]] @@ -675,7 +745,6 @@ files = [ [package.dependencies] blinker = ">=1.6.2" click = ">=8.1.3" -importlib-metadata = {version = ">=3.6.0", markers = "python_version < \"3.10\""} itsdangerous = ">=2.1.2" Jinja2 = ">=3.1.2" Werkzeug = ">=2.3.7" @@ -812,6 +881,20 @@ files = [ {file = "frozenlist-1.4.1.tar.gz", hash = "sha256:c037a86e8513059a2613aaba4d817bb90b9d9b6b69aace3ce9c877e8c8ed402b"}, ] +[[package]] +name = "humanfriendly" +version = "10.0" +description = "Human friendly output for text interfaces using Python" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" +files = [ + {file = "humanfriendly-10.0-py2.py3-none-any.whl", hash = "sha256:1697e1a8a8f550fd43c2865cd84542fc175a61dcb779b6fee18cf6b6ccba1477"}, + {file = "humanfriendly-10.0.tar.gz", hash = "sha256:6b0b831ce8f15f7300721aa49829fc4e83921a9a301cc7f606be6686a2288ddc"}, +] + +[package.dependencies] +pyreadline3 = {version = "*", markers = "sys_platform == \"win32\" and python_version >= \"3.8\""} + [[package]] name = "idna" version = "3.7" @@ -834,25 +917,6 @@ files = [ {file = "imagesize-1.4.1.tar.gz", hash = "sha256:69150444affb9cb0d5cc5a92b3676f0b2fb7cd9ae39e947a5e11a36b4497cd4a"}, ] -[[package]] -name = "importlib-metadata" -version = "7.1.0" -description = "Read metadata from Python packages" -optional = false -python-versions = ">=3.8" -files = [ - {file = "importlib_metadata-7.1.0-py3-none-any.whl", hash = "sha256:30962b96c0c223483ed6cc7280e7f0199feb01a0e40cfae4d4450fc6fab1f570"}, - {file = "importlib_metadata-7.1.0.tar.gz", hash = "sha256:b78938b926ee8d5f020fc4772d487045805a55ddbad2ecf21c6d60938dc7fcd2"}, -] - -[package.dependencies] -zipp = ">=0.5" - -[package.extras] -docs = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"] -perf = ["ipython"] -testing = ["flufl.flake8", "importlib-resources (>=1.3)", "jaraco.test (>=5.4)", "packaging", "pyfakefs", "pytest (>=6)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-mypy", "pytest-perf (>=0.9.2)", "pytest-ruff (>=0.2.1)"] - [[package]] name = "iniconfig" version = "2.0.0" @@ -1054,6 +1118,96 @@ files = [ {file = "mypy_extensions-1.0.0.tar.gz", hash = "sha256:75dbf8955dc00442a438fc4d0666508a9a97b6bd41aa2f0ffe9d2f2725af0782"}, ] +[[package]] +name = "ogmios" +version = "1.1.1" +description = "Ogmios is a lightweight bridge interface for cardano-node. It offers a WebSockets API that enables local clients to speak Ouroboros' mini-protocols via JSON/RPC. ogmios-python is an Ogmios client written in Python designed for ease of use." +optional = false +python-versions = ">=3.10" +files = [ + {file = "ogmios-1.1.1-py3-none-any.whl", hash = "sha256:ff289416452ff78e39c772824c88e90a762f9d16fd893e42a52b22cf533cf344"}, + {file = "ogmios-1.1.1.tar.gz", hash = "sha256:b24884c2ce497cf72394c03aecb94eec27f14f79b305e5b0816544703fba0c60"}, +] + +[package.dependencies] +cachetools = "*" +cardano-tools = "*" +coloredlogs = "*" +orjson = "*" +pycardano = "*" +pydantic = ">=2.0" +websockets = "*" + +[package.extras] +dev = ["black", "datamodel-code-generator", "flake8-pyproject", "isort", "sphinx", "sphinx-rtd-theme"] +testing = ["coverage[toml] (>=6.5)", "pytest"] + +[[package]] +name = "orjson" +version = "3.10.7" +description = "Fast, correct Python JSON library supporting dataclasses, datetimes, and numpy" +optional = false +python-versions = ">=3.8" +files = [ + {file = "orjson-3.10.7-cp310-cp310-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:74f4544f5a6405b90da8ea724d15ac9c36da4d72a738c64685003337401f5c12"}, + {file = "orjson-3.10.7-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:34a566f22c28222b08875b18b0dfbf8a947e69df21a9ed5c51a6bf91cfb944ac"}, + {file = "orjson-3.10.7-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:bf6ba8ebc8ef5792e2337fb0419f8009729335bb400ece005606336b7fd7bab7"}, + {file = "orjson-3.10.7-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ac7cf6222b29fbda9e3a472b41e6a5538b48f2c8f99261eecd60aafbdb60690c"}, + {file = "orjson-3.10.7-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:de817e2f5fc75a9e7dd350c4b0f54617b280e26d1631811a43e7e968fa71e3e9"}, + {file = "orjson-3.10.7-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:348bdd16b32556cf8d7257b17cf2bdb7ab7976af4af41ebe79f9796c218f7e91"}, + {file = "orjson-3.10.7-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:479fd0844ddc3ca77e0fd99644c7fe2de8e8be1efcd57705b5c92e5186e8a250"}, + {file = "orjson-3.10.7-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:fdf5197a21dd660cf19dfd2a3ce79574588f8f5e2dbf21bda9ee2d2b46924d84"}, + {file = "orjson-3.10.7-cp310-none-win32.whl", hash = "sha256:d374d36726746c81a49f3ff8daa2898dccab6596864ebe43d50733275c629175"}, + {file = "orjson-3.10.7-cp310-none-win_amd64.whl", hash = "sha256:cb61938aec8b0ffb6eef484d480188a1777e67b05d58e41b435c74b9d84e0b9c"}, + {file = "orjson-3.10.7-cp311-cp311-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:7db8539039698ddfb9a524b4dd19508256107568cdad24f3682d5773e60504a2"}, + {file = "orjson-3.10.7-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:480f455222cb7a1dea35c57a67578848537d2602b46c464472c995297117fa09"}, + {file = "orjson-3.10.7-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:8a9c9b168b3a19e37fe2778c0003359f07822c90fdff8f98d9d2a91b3144d8e0"}, + {file = "orjson-3.10.7-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8de062de550f63185e4c1c54151bdddfc5625e37daf0aa1e75d2a1293e3b7d9a"}, + {file = "orjson-3.10.7-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:6b0dd04483499d1de9c8f6203f8975caf17a6000b9c0c54630cef02e44ee624e"}, + {file = "orjson-3.10.7-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b58d3795dafa334fc8fd46f7c5dc013e6ad06fd5b9a4cc98cb1456e7d3558bd6"}, + {file = "orjson-3.10.7-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:33cfb96c24034a878d83d1a9415799a73dc77480e6c40417e5dda0710d559ee6"}, + {file = "orjson-3.10.7-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:e724cebe1fadc2b23c6f7415bad5ee6239e00a69f30ee423f319c6af70e2a5c0"}, + {file = "orjson-3.10.7-cp311-none-win32.whl", hash = "sha256:82763b46053727a7168d29c772ed5c870fdae2f61aa8a25994c7984a19b1021f"}, + {file = "orjson-3.10.7-cp311-none-win_amd64.whl", hash = "sha256:eb8d384a24778abf29afb8e41d68fdd9a156cf6e5390c04cc07bbc24b89e98b5"}, + {file = "orjson-3.10.7-cp312-cp312-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:44a96f2d4c3af51bfac6bc4ef7b182aa33f2f054fd7f34cc0ee9a320d051d41f"}, + {file = "orjson-3.10.7-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:76ac14cd57df0572453543f8f2575e2d01ae9e790c21f57627803f5e79b0d3c3"}, + {file = "orjson-3.10.7-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:bdbb61dcc365dd9be94e8f7df91975edc9364d6a78c8f7adb69c1cdff318ec93"}, + {file = "orjson-3.10.7-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b48b3db6bb6e0a08fa8c83b47bc169623f801e5cc4f24442ab2b6617da3b5313"}, + {file = "orjson-3.10.7-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:23820a1563a1d386414fef15c249040042b8e5d07b40ab3fe3efbfbbcbcb8864"}, + {file = "orjson-3.10.7-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a0c6a008e91d10a2564edbb6ee5069a9e66df3fbe11c9a005cb411f441fd2c09"}, + {file = "orjson-3.10.7-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:d352ee8ac1926d6193f602cbe36b1643bbd1bbcb25e3c1a657a4390f3000c9a5"}, + {file = "orjson-3.10.7-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:d2d9f990623f15c0ae7ac608103c33dfe1486d2ed974ac3f40b693bad1a22a7b"}, + {file = "orjson-3.10.7-cp312-none-win32.whl", hash = "sha256:7c4c17f8157bd520cdb7195f75ddbd31671997cbe10aee559c2d613592e7d7eb"}, + {file = "orjson-3.10.7-cp312-none-win_amd64.whl", hash = "sha256:1d9c0e733e02ada3ed6098a10a8ee0052dd55774de3d9110d29868d24b17faa1"}, + {file = "orjson-3.10.7-cp313-cp313-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:77d325ed866876c0fa6492598ec01fe30e803272a6e8b10e992288b009cbe149"}, + {file = "orjson-3.10.7-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9ea2c232deedcb605e853ae1db2cc94f7390ac776743b699b50b071b02bea6fe"}, + {file = "orjson-3.10.7-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:3dcfbede6737fdbef3ce9c37af3fb6142e8e1ebc10336daa05872bfb1d87839c"}, + {file = "orjson-3.10.7-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:11748c135f281203f4ee695b7f80bb1358a82a63905f9f0b794769483ea854ad"}, + {file = "orjson-3.10.7-cp313-none-win32.whl", hash = "sha256:a7e19150d215c7a13f39eb787d84db274298d3f83d85463e61d277bbd7f401d2"}, + {file = "orjson-3.10.7-cp313-none-win_amd64.whl", hash = "sha256:eef44224729e9525d5261cc8d28d6b11cafc90e6bd0be2157bde69a52ec83024"}, + {file = "orjson-3.10.7-cp38-cp38-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:6ea2b2258eff652c82652d5e0f02bd5e0463a6a52abb78e49ac288827aaa1469"}, + {file = "orjson-3.10.7-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:430ee4d85841e1483d487e7b81401785a5dfd69db5de01314538f31f8fbf7ee1"}, + {file = "orjson-3.10.7-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:4b6146e439af4c2472c56f8540d799a67a81226e11992008cb47e1267a9b3225"}, + {file = "orjson-3.10.7-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:084e537806b458911137f76097e53ce7bf5806dda33ddf6aaa66a028f8d43a23"}, + {file = "orjson-3.10.7-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:4829cf2195838e3f93b70fd3b4292156fc5e097aac3739859ac0dcc722b27ac0"}, + {file = "orjson-3.10.7-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1193b2416cbad1a769f868b1749535d5da47626ac29445803dae7cc64b3f5c98"}, + {file = "orjson-3.10.7-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:4e6c3da13e5a57e4b3dca2de059f243ebec705857522f188f0180ae88badd354"}, + {file = "orjson-3.10.7-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:c31008598424dfbe52ce8c5b47e0752dca918a4fdc4a2a32004efd9fab41d866"}, + {file = "orjson-3.10.7-cp38-none-win32.whl", hash = "sha256:7122a99831f9e7fe977dc45784d3b2edc821c172d545e6420c375e5a935f5a1c"}, + {file = "orjson-3.10.7-cp38-none-win_amd64.whl", hash = "sha256:a763bc0e58504cc803739e7df040685816145a6f3c8a589787084b54ebc9f16e"}, + {file = "orjson-3.10.7-cp39-cp39-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:e76be12658a6fa376fcd331b1ea4e58f5a06fd0220653450f0d415b8fd0fbe20"}, + {file = "orjson-3.10.7-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ed350d6978d28b92939bfeb1a0570c523f6170efc3f0a0ef1f1df287cd4f4960"}, + {file = "orjson-3.10.7-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:144888c76f8520e39bfa121b31fd637e18d4cc2f115727865fdf9fa325b10412"}, + {file = "orjson-3.10.7-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:09b2d92fd95ad2402188cf51573acde57eb269eddabaa60f69ea0d733e789fe9"}, + {file = "orjson-3.10.7-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5b24a579123fa884f3a3caadaed7b75eb5715ee2b17ab5c66ac97d29b18fe57f"}, + {file = "orjson-3.10.7-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e72591bcfe7512353bd609875ab38050efe3d55e18934e2f18950c108334b4ff"}, + {file = "orjson-3.10.7-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:f4db56635b58cd1a200b0a23744ff44206ee6aa428185e2b6c4a65b3197abdcd"}, + {file = "orjson-3.10.7-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:0fa5886854673222618638c6df7718ea7fe2f3f2384c452c9ccedc70b4a510a5"}, + {file = "orjson-3.10.7-cp39-none-win32.whl", hash = "sha256:8272527d08450ab16eb405f47e0f4ef0e5ff5981c3d82afe0efd25dcbef2bcd2"}, + {file = "orjson-3.10.7-cp39-none-win_amd64.whl", hash = "sha256:974683d4618c0c7dbf4f69c95a979734bf183d0658611760017f6e70a145af58"}, + {file = "orjson-3.10.7.tar.gz", hash = "sha256:75ef0640403f945f3a1f9f6400686560dbfb0fb5b16589ad62cd477043c4eee3"}, +] + [[package]] name = "oscrypto" version = "1.3.0" @@ -1070,13 +1224,13 @@ asn1crypto = ">=1.5.1" [[package]] name = "packaging" -version = "24.0" +version = "24.1" description = "Core utilities for Python packages" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "packaging-24.0-py3-none-any.whl", hash = "sha256:2ddfb553fdf02fb784c234c7ba6ccc288296ceabec964ad2eae3777778130bc5"}, - {file = "packaging-24.0.tar.gz", hash = "sha256:eb82c5e3e56209074766e6885bb04b8c38a0c015d0a30036ebe7ece34c9989e9"}, + {file = "packaging-24.1-py3-none-any.whl", hash = "sha256:5b8f2217dbdbd2f7f384c41c628544e6d52f2d0f53c6d0c3ea61aa5d1d7ff124"}, + {file = "packaging-24.1.tar.gz", hash = "sha256:026ed72c8ed3fcce5bf8950572258698927fd1dbda10a5e981cdf0ac37f4f002"}, ] [[package]] @@ -1090,6 +1244,20 @@ files = [ {file = "pathspec-0.12.1.tar.gz", hash = "sha256:a482d51503a1ab33b1c67a6c3813a26953dbdc71c31dacaef9a838c4e29f5712"}, ] +[[package]] +name = "pexpect" +version = "4.9.0" +description = "Pexpect allows easy control of interactive console applications." +optional = false +python-versions = "*" +files = [ + {file = "pexpect-4.9.0-py2.py3-none-any.whl", hash = "sha256:7236d1e080e4936be2dc3e326cec0af72acf9212a7e1d060210e70a47e253523"}, + {file = "pexpect-4.9.0.tar.gz", hash = "sha256:ee7d41123f3c9911050ea2c2dac107568dc43b2d3b0c7557a33212c398ead30f"}, +] + +[package.dependencies] +ptyprocess = ">=0.5" + [[package]] name = "platformdirs" version = "4.2.2" @@ -1132,6 +1300,17 @@ files = [ {file = "pprintpp-0.4.0.tar.gz", hash = "sha256:ea826108e2c7f49dc6d66c752973c3fc9749142a798d6b254e1e301cfdbc6403"}, ] +[[package]] +name = "ptyprocess" +version = "0.7.0" +description = "Run a subprocess in a pseudo terminal" +optional = false +python-versions = "*" +files = [ + {file = "ptyprocess-0.7.0-py2.py3-none-any.whl", hash = "sha256:4b41f3967fce3af57cc7e94b888626c18bf37a083e3651ca8feeb66d492fef35"}, + {file = "ptyprocess-0.7.0.tar.gz", hash = "sha256:5c5d0a3b48ceee0b48485e0c26037c0acd7d29765ca3fbb5cb3831d347423220"}, +] + [[package]] name = "py" version = "1.11.0" @@ -1145,13 +1324,13 @@ files = [ [[package]] name = "pycodestyle" -version = "2.11.1" +version = "2.12.1" description = "Python style guide checker" optional = false python-versions = ">=3.8" files = [ - {file = "pycodestyle-2.11.1-py2.py3-none-any.whl", hash = "sha256:44fe31000b2d866f2e41841b18528a505fbd7fef9017b04eff4e2648a0fadc67"}, - {file = "pycodestyle-2.11.1.tar.gz", hash = "sha256:41ba0e7afc9752dfb53ced5489e89f8186be00e599e712660695b7a75ff2663f"}, + {file = "pycodestyle-2.12.1-py2.py3-none-any.whl", hash = "sha256:46f0fb92069a7c28ab7bb558f05bfc0110dac69a0cd23c61ea0040283a9d78b3"}, + {file = "pycodestyle-2.12.1.tar.gz", hash = "sha256:6838eae08bbce4f6accd5d5572075c63626a15ee3e6f842df996bf62f6d73521"}, ] [[package]] @@ -1165,6 +1344,129 @@ files = [ {file = "pycparser-2.22.tar.gz", hash = "sha256:491c8be9c040f5390f5bf44a5b07752bd07f56edf992381b05c701439eec10f6"}, ] +[[package]] +name = "pydantic" +version = "2.8.2" +description = "Data validation using Python type hints" +optional = false +python-versions = ">=3.8" +files = [ + {file = "pydantic-2.8.2-py3-none-any.whl", hash = "sha256:73ee9fddd406dc318b885c7a2eab8a6472b68b8fb5ba8150949fc3db939f23c8"}, + {file = "pydantic-2.8.2.tar.gz", hash = "sha256:6f62c13d067b0755ad1c21a34bdd06c0c12625a22b0fc09c6b149816604f7c2a"}, +] + +[package.dependencies] +annotated-types = ">=0.4.0" +pydantic-core = "2.20.1" +typing-extensions = [ + {version = ">=4.12.2", markers = "python_version >= \"3.13\""}, + {version = ">=4.6.1", markers = "python_version < \"3.13\""}, +] + +[package.extras] +email = ["email-validator (>=2.0.0)"] + +[[package]] +name = "pydantic-core" +version = "2.20.1" +description = "Core functionality for Pydantic validation and serialization" +optional = false +python-versions = ">=3.8" +files = [ + {file = "pydantic_core-2.20.1-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:3acae97ffd19bf091c72df4d726d552c473f3576409b2a7ca36b2f535ffff4a3"}, + {file = "pydantic_core-2.20.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:41f4c96227a67a013e7de5ff8f20fb496ce573893b7f4f2707d065907bffdbd6"}, + {file = "pydantic_core-2.20.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5f239eb799a2081495ea659d8d4a43a8f42cd1fe9ff2e7e436295c38a10c286a"}, + {file = "pydantic_core-2.20.1-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:53e431da3fc53360db73eedf6f7124d1076e1b4ee4276b36fb25514544ceb4a3"}, + {file = "pydantic_core-2.20.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f1f62b2413c3a0e846c3b838b2ecd6c7a19ec6793b2a522745b0869e37ab5bc1"}, + {file = "pydantic_core-2.20.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5d41e6daee2813ecceea8eda38062d69e280b39df793f5a942fa515b8ed67953"}, + {file = "pydantic_core-2.20.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3d482efec8b7dc6bfaedc0f166b2ce349df0011f5d2f1f25537ced4cfc34fd98"}, + {file = "pydantic_core-2.20.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:e93e1a4b4b33daed65d781a57a522ff153dcf748dee70b40c7258c5861e1768a"}, + {file = "pydantic_core-2.20.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:e7c4ea22b6739b162c9ecaaa41d718dfad48a244909fe7ef4b54c0b530effc5a"}, + {file = "pydantic_core-2.20.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:4f2790949cf385d985a31984907fecb3896999329103df4e4983a4a41e13e840"}, + {file = "pydantic_core-2.20.1-cp310-none-win32.whl", hash = "sha256:5e999ba8dd90e93d57410c5e67ebb67ffcaadcea0ad973240fdfd3a135506250"}, + {file = "pydantic_core-2.20.1-cp310-none-win_amd64.whl", hash = "sha256:512ecfbefef6dac7bc5eaaf46177b2de58cdf7acac8793fe033b24ece0b9566c"}, + {file = "pydantic_core-2.20.1-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:d2a8fa9d6d6f891f3deec72f5cc668e6f66b188ab14bb1ab52422fe8e644f312"}, + {file = "pydantic_core-2.20.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:175873691124f3d0da55aeea1d90660a6ea7a3cfea137c38afa0a5ffabe37b88"}, + {file = "pydantic_core-2.20.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:37eee5b638f0e0dcd18d21f59b679686bbd18917b87db0193ae36f9c23c355fc"}, + {file = "pydantic_core-2.20.1-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:25e9185e2d06c16ee438ed39bf62935ec436474a6ac4f9358524220f1b236e43"}, + {file = "pydantic_core-2.20.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:150906b40ff188a3260cbee25380e7494ee85048584998c1e66df0c7a11c17a6"}, + {file = "pydantic_core-2.20.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8ad4aeb3e9a97286573c03df758fc7627aecdd02f1da04516a86dc159bf70121"}, + {file = "pydantic_core-2.20.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d3f3ed29cd9f978c604708511a1f9c2fdcb6c38b9aae36a51905b8811ee5cbf1"}, + {file = "pydantic_core-2.20.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:b0dae11d8f5ded51699c74d9548dcc5938e0804cc8298ec0aa0da95c21fff57b"}, + {file = "pydantic_core-2.20.1-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:faa6b09ee09433b87992fb5a2859efd1c264ddc37280d2dd5db502126d0e7f27"}, + {file = "pydantic_core-2.20.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:9dc1b507c12eb0481d071f3c1808f0529ad41dc415d0ca11f7ebfc666e66a18b"}, + {file = "pydantic_core-2.20.1-cp311-none-win32.whl", hash = "sha256:fa2fddcb7107e0d1808086ca306dcade7df60a13a6c347a7acf1ec139aa6789a"}, + {file = "pydantic_core-2.20.1-cp311-none-win_amd64.whl", hash = "sha256:40a783fb7ee353c50bd3853e626f15677ea527ae556429453685ae32280c19c2"}, + {file = "pydantic_core-2.20.1-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:595ba5be69b35777474fa07f80fc260ea71255656191adb22a8c53aba4479231"}, + {file = "pydantic_core-2.20.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:a4f55095ad087474999ee28d3398bae183a66be4823f753cd7d67dd0153427c9"}, + {file = "pydantic_core-2.20.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f9aa05d09ecf4c75157197f27cdc9cfaeb7c5f15021c6373932bf3e124af029f"}, + {file = "pydantic_core-2.20.1-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:e97fdf088d4b31ff4ba35db26d9cc472ac7ef4a2ff2badeabf8d727b3377fc52"}, + {file = "pydantic_core-2.20.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:bc633a9fe1eb87e250b5c57d389cf28998e4292336926b0b6cdaee353f89a237"}, + {file = "pydantic_core-2.20.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d573faf8eb7e6b1cbbcb4f5b247c60ca8be39fe2c674495df0eb4318303137fe"}, + {file = "pydantic_core-2.20.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:26dc97754b57d2fd00ac2b24dfa341abffc380b823211994c4efac7f13b9e90e"}, + {file = "pydantic_core-2.20.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:33499e85e739a4b60c9dac710c20a08dc73cb3240c9a0e22325e671b27b70d24"}, + {file = "pydantic_core-2.20.1-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:bebb4d6715c814597f85297c332297c6ce81e29436125ca59d1159b07f423eb1"}, + {file = "pydantic_core-2.20.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:516d9227919612425c8ef1c9b869bbbee249bc91912c8aaffb66116c0b447ebd"}, + {file = "pydantic_core-2.20.1-cp312-none-win32.whl", hash = "sha256:469f29f9093c9d834432034d33f5fe45699e664f12a13bf38c04967ce233d688"}, + {file = "pydantic_core-2.20.1-cp312-none-win_amd64.whl", hash = "sha256:035ede2e16da7281041f0e626459bcae33ed998cca6a0a007a5ebb73414ac72d"}, + {file = "pydantic_core-2.20.1-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:0827505a5c87e8aa285dc31e9ec7f4a17c81a813d45f70b1d9164e03a813a686"}, + {file = "pydantic_core-2.20.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:19c0fa39fa154e7e0b7f82f88ef85faa2a4c23cc65aae2f5aea625e3c13c735a"}, + {file = "pydantic_core-2.20.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4aa223cd1e36b642092c326d694d8bf59b71ddddc94cdb752bbbb1c5c91d833b"}, + {file = "pydantic_core-2.20.1-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:c336a6d235522a62fef872c6295a42ecb0c4e1d0f1a3e500fe949415761b8a19"}, + {file = "pydantic_core-2.20.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:7eb6a0587eded33aeefea9f916899d42b1799b7b14b8f8ff2753c0ac1741edac"}, + {file = "pydantic_core-2.20.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:70c8daf4faca8da5a6d655f9af86faf6ec2e1768f4b8b9d0226c02f3d6209703"}, + {file = "pydantic_core-2.20.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e9fa4c9bf273ca41f940bceb86922a7667cd5bf90e95dbb157cbb8441008482c"}, + {file = "pydantic_core-2.20.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:11b71d67b4725e7e2a9f6e9c0ac1239bbc0c48cce3dc59f98635efc57d6dac83"}, + {file = "pydantic_core-2.20.1-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:270755f15174fb983890c49881e93f8f1b80f0b5e3a3cc1394a255706cabd203"}, + {file = "pydantic_core-2.20.1-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:c81131869240e3e568916ef4c307f8b99583efaa60a8112ef27a366eefba8ef0"}, + {file = "pydantic_core-2.20.1-cp313-none-win32.whl", hash = "sha256:b91ced227c41aa29c672814f50dbb05ec93536abf8f43cd14ec9521ea09afe4e"}, + {file = "pydantic_core-2.20.1-cp313-none-win_amd64.whl", hash = "sha256:65db0f2eefcaad1a3950f498aabb4875c8890438bc80b19362cf633b87a8ab20"}, + {file = "pydantic_core-2.20.1-cp38-cp38-macosx_10_12_x86_64.whl", hash = "sha256:4745f4ac52cc6686390c40eaa01d48b18997cb130833154801a442323cc78f91"}, + {file = "pydantic_core-2.20.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:a8ad4c766d3f33ba8fd692f9aa297c9058970530a32c728a2c4bfd2616d3358b"}, + {file = "pydantic_core-2.20.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:41e81317dd6a0127cabce83c0c9c3fbecceae981c8391e6f1dec88a77c8a569a"}, + {file = "pydantic_core-2.20.1-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:04024d270cf63f586ad41fff13fde4311c4fc13ea74676962c876d9577bcc78f"}, + {file = "pydantic_core-2.20.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:eaad4ff2de1c3823fddf82f41121bdf453d922e9a238642b1dedb33c4e4f98ad"}, + {file = "pydantic_core-2.20.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:26ab812fa0c845df815e506be30337e2df27e88399b985d0bb4e3ecfe72df31c"}, + {file = "pydantic_core-2.20.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3c5ebac750d9d5f2706654c638c041635c385596caf68f81342011ddfa1e5598"}, + {file = "pydantic_core-2.20.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:2aafc5a503855ea5885559eae883978c9b6d8c8993d67766ee73d82e841300dd"}, + {file = "pydantic_core-2.20.1-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:4868f6bd7c9d98904b748a2653031fc9c2f85b6237009d475b1008bfaeb0a5aa"}, + {file = "pydantic_core-2.20.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:aa2f457b4af386254372dfa78a2eda2563680d982422641a85f271c859df1987"}, + {file = "pydantic_core-2.20.1-cp38-none-win32.whl", hash = "sha256:225b67a1f6d602de0ce7f6c1c3ae89a4aa25d3de9be857999e9124f15dab486a"}, + {file = "pydantic_core-2.20.1-cp38-none-win_amd64.whl", hash = "sha256:6b507132dcfc0dea440cce23ee2182c0ce7aba7054576efc65634f080dbe9434"}, + {file = "pydantic_core-2.20.1-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:b03f7941783b4c4a26051846dea594628b38f6940a2fdc0df00b221aed39314c"}, + {file = "pydantic_core-2.20.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:1eedfeb6089ed3fad42e81a67755846ad4dcc14d73698c120a82e4ccf0f1f9f6"}, + {file = "pydantic_core-2.20.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:635fee4e041ab9c479e31edda27fcf966ea9614fff1317e280d99eb3e5ab6fe2"}, + {file = "pydantic_core-2.20.1-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:77bf3ac639c1ff567ae3b47f8d4cc3dc20f9966a2a6dd2311dcc055d3d04fb8a"}, + {file = "pydantic_core-2.20.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:7ed1b0132f24beeec5a78b67d9388656d03e6a7c837394f99257e2d55b461611"}, + {file = "pydantic_core-2.20.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c6514f963b023aeee506678a1cf821fe31159b925c4b76fe2afa94cc70b3222b"}, + {file = "pydantic_core-2.20.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:10d4204d8ca33146e761c79f83cc861df20e7ae9f6487ca290a97702daf56006"}, + {file = "pydantic_core-2.20.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:2d036c7187b9422ae5b262badb87a20a49eb6c5238b2004e96d4da1231badef1"}, + {file = "pydantic_core-2.20.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:9ebfef07dbe1d93efb94b4700f2d278494e9162565a54f124c404a5656d7ff09"}, + {file = "pydantic_core-2.20.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:6b9d9bb600328a1ce523ab4f454859e9d439150abb0906c5a1983c146580ebab"}, + {file = "pydantic_core-2.20.1-cp39-none-win32.whl", hash = "sha256:784c1214cb6dd1e3b15dd8b91b9a53852aed16671cc3fbe4786f4f1db07089e2"}, + {file = "pydantic_core-2.20.1-cp39-none-win_amd64.whl", hash = "sha256:d2fe69c5434391727efa54b47a1e7986bb0186e72a41b203df8f5b0a19a4f669"}, + {file = "pydantic_core-2.20.1-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:a45f84b09ac9c3d35dfcf6a27fd0634d30d183205230a0ebe8373a0e8cfa0906"}, + {file = "pydantic_core-2.20.1-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:d02a72df14dfdbaf228424573a07af10637bd490f0901cee872c4f434a735b94"}, + {file = "pydantic_core-2.20.1-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d2b27e6af28f07e2f195552b37d7d66b150adbaa39a6d327766ffd695799780f"}, + {file = "pydantic_core-2.20.1-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:084659fac3c83fd674596612aeff6041a18402f1e1bc19ca39e417d554468482"}, + {file = "pydantic_core-2.20.1-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:242b8feb3c493ab78be289c034a1f659e8826e2233786e36f2893a950a719bb6"}, + {file = "pydantic_core-2.20.1-pp310-pypy310_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:38cf1c40a921d05c5edc61a785c0ddb4bed67827069f535d794ce6bcded919fc"}, + {file = "pydantic_core-2.20.1-pp310-pypy310_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:e0bbdd76ce9aa5d4209d65f2b27fc6e5ef1312ae6c5333c26db3f5ade53a1e99"}, + {file = "pydantic_core-2.20.1-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:254ec27fdb5b1ee60684f91683be95e5133c994cc54e86a0b0963afa25c8f8a6"}, + {file = "pydantic_core-2.20.1-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:407653af5617f0757261ae249d3fba09504d7a71ab36ac057c938572d1bc9331"}, + {file = "pydantic_core-2.20.1-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:c693e916709c2465b02ca0ad7b387c4f8423d1db7b4649c551f27a529181c5ad"}, + {file = "pydantic_core-2.20.1-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5b5ff4911aea936a47d9376fd3ab17e970cc543d1b68921886e7f64bd28308d1"}, + {file = "pydantic_core-2.20.1-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:177f55a886d74f1808763976ac4efd29b7ed15c69f4d838bbd74d9d09cf6fa86"}, + {file = "pydantic_core-2.20.1-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:964faa8a861d2664f0c7ab0c181af0bea66098b1919439815ca8803ef136fc4e"}, + {file = "pydantic_core-2.20.1-pp39-pypy39_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:4dd484681c15e6b9a977c785a345d3e378d72678fd5f1f3c0509608da24f2ac0"}, + {file = "pydantic_core-2.20.1-pp39-pypy39_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:f6d6cff3538391e8486a431569b77921adfcdef14eb18fbf19b7c0a5294d4e6a"}, + {file = "pydantic_core-2.20.1-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:a6d511cc297ff0883bc3708b465ff82d7560193169a8b93260f74ecb0a5e08a7"}, + {file = "pydantic_core-2.20.1.tar.gz", hash = "sha256:26ca695eeee5f9f1aeeb211ffc12f10bcb6f71e2989988fda61dabd65db878d4"}, +] + +[package.dependencies] +typing-extensions = ">=4.6.0,<4.7.0 || >4.7.0" + [[package]] name = "pyflakes" version = "3.2.0" @@ -1216,15 +1518,26 @@ cffi = ">=1.4.1" docs = ["sphinx (>=1.6.5)", "sphinx-rtd-theme"] tests = ["hypothesis (>=3.27.0)", "pytest (>=3.2.1,!=3.3.0)"] +[[package]] +name = "pyreadline3" +version = "3.4.1" +description = "A python implementation of GNU readline." +optional = false +python-versions = "*" +files = [ + {file = "pyreadline3-3.4.1-py3-none-any.whl", hash = "sha256:b0efb6516fd4fb07b45949053826a62fa4cb353db5be2bbb4a7aa1fdd1e345fb"}, + {file = "pyreadline3-3.4.1.tar.gz", hash = "sha256:6f3d1f7b8a31ba32b73917cefc1f28cc660562f39aea8646d30bd6eff21f7bae"}, +] + [[package]] name = "pytest" -version = "8.2.1" +version = "8.3.2" description = "pytest: simple powerful testing with Python" optional = false python-versions = ">=3.8" files = [ - {file = "pytest-8.2.1-py3-none-any.whl", hash = "sha256:faccc5d332b8c3719f40283d0d44aa5cf101cec36f88cde9ed8f2bc0538612b1"}, - {file = "pytest-8.2.1.tar.gz", hash = "sha256:5046e5b46d8e4cac199c373041f26be56fdb81eb4e67dc11d4e10811fc3408fd"}, + {file = "pytest-8.3.2-py3-none-any.whl", hash = "sha256:4ba08f9ae7dcf84ded419494d229b48d0903ea6407b030eaec46df5e6a73bba5"}, + {file = "pytest-8.3.2.tar.gz", hash = "sha256:c132345d12ce551242c87269de812483f5bcc87cdbb4722e48487ba194f9fdce"}, ] [package.dependencies] @@ -1232,7 +1545,7 @@ colorama = {version = "*", markers = "sys_platform == \"win32\""} exceptiongroup = {version = ">=1.0.0rc8", markers = "python_version < \"3.11\""} iniconfig = "*" packaging = "*" -pluggy = ">=1.5,<2.0" +pluggy = ">=1.5,<2" tomli = {version = ">=1", markers = "python_version < \"3.11\""} [package.extras] @@ -1276,17 +1589,6 @@ psutil = ["psutil (>=3.0)"] setproctitle = ["setproctitle"] testing = ["filelock"] -[[package]] -name = "pytz" -version = "2024.1" -description = "World timezone definitions, modern and historical" -optional = false -python-versions = "*" -files = [ - {file = "pytz-2024.1-py2.py3-none-any.whl", hash = "sha256:328171f4e3623139da4983451950b28e95ac706e13f3f2630a879749e7a8b319"}, - {file = "pytz-2024.1.tar.gz", hash = "sha256:2a29735ea9c18baf14b448846bde5a48030ed267578472d8955cd0e7443a9812"}, -] - [[package]] name = "pywin32" version = "306" @@ -1401,7 +1703,6 @@ babel = ">=2.9" colorama = {version = ">=0.4.5", markers = "sys_platform == \"win32\""} docutils = ">=0.14,<0.20" imagesize = ">=1.3" -importlib-metadata = {version = ">=4.8", markers = "python_version < \"3.10\""} Jinja2 = ">=3.0" packaging = ">=21.0" Pygments = ">=2.12" @@ -1458,47 +1759,50 @@ dev = ["bump2version", "sphinxcontrib-httpdomain", "transifex-client", "wheel"] [[package]] name = "sphinxcontrib-applehelp" -version = "1.0.4" +version = "2.0.0" description = "sphinxcontrib-applehelp is a Sphinx extension which outputs Apple help books" optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" files = [ - {file = "sphinxcontrib-applehelp-1.0.4.tar.gz", hash = "sha256:828f867945bbe39817c210a1abfd1bc4895c8b73fcaade56d45357a348a07d7e"}, - {file = "sphinxcontrib_applehelp-1.0.4-py3-none-any.whl", hash = "sha256:29d341f67fb0f6f586b23ad80e072c8e6ad0b48417db2bde114a4c9746feb228"}, + {file = "sphinxcontrib_applehelp-2.0.0-py3-none-any.whl", hash = "sha256:4cd3f0ec4ac5dd9c17ec65e9ab272c9b867ea77425228e68ecf08d6b28ddbdb5"}, + {file = "sphinxcontrib_applehelp-2.0.0.tar.gz", hash = "sha256:2f29ef331735ce958efa4734873f084941970894c6090408b079c61b2e1c06d1"}, ] [package.extras] -lint = ["docutils-stubs", "flake8", "mypy"] +lint = ["mypy", "ruff (==0.5.5)", "types-docutils"] +standalone = ["Sphinx (>=5)"] test = ["pytest"] [[package]] name = "sphinxcontrib-devhelp" -version = "1.0.2" -description = "sphinxcontrib-devhelp is a sphinx extension which outputs Devhelp document." +version = "2.0.0" +description = "sphinxcontrib-devhelp is a sphinx extension which outputs Devhelp documents" optional = false -python-versions = ">=3.5" +python-versions = ">=3.9" files = [ - {file = "sphinxcontrib-devhelp-1.0.2.tar.gz", hash = "sha256:ff7f1afa7b9642e7060379360a67e9c41e8f3121f2ce9164266f61b9f4b338e4"}, - {file = "sphinxcontrib_devhelp-1.0.2-py2.py3-none-any.whl", hash = "sha256:8165223f9a335cc1af7ffe1ed31d2871f325254c0423bc0c4c7cd1c1e4734a2e"}, + {file = "sphinxcontrib_devhelp-2.0.0-py3-none-any.whl", hash = "sha256:aefb8b83854e4b0998877524d1029fd3e6879210422ee3780459e28a1f03a8a2"}, + {file = "sphinxcontrib_devhelp-2.0.0.tar.gz", hash = "sha256:411f5d96d445d1d73bb5d52133377b4248ec79db5c793ce7dbe59e074b4dd1ad"}, ] [package.extras] -lint = ["docutils-stubs", "flake8", "mypy"] +lint = ["mypy", "ruff (==0.5.5)", "types-docutils"] +standalone = ["Sphinx (>=5)"] test = ["pytest"] [[package]] name = "sphinxcontrib-htmlhelp" -version = "2.0.1" +version = "2.1.0" description = "sphinxcontrib-htmlhelp is a sphinx extension which renders HTML help files" optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" files = [ - {file = "sphinxcontrib-htmlhelp-2.0.1.tar.gz", hash = "sha256:0cbdd302815330058422b98a113195c9249825d681e18f11e8b1f78a2f11efff"}, - {file = "sphinxcontrib_htmlhelp-2.0.1-py3-none-any.whl", hash = "sha256:c38cb46dccf316c79de6e5515e1770414b797162b23cd3d06e67020e1d2a6903"}, + {file = "sphinxcontrib_htmlhelp-2.1.0-py3-none-any.whl", hash = "sha256:166759820b47002d22914d64a075ce08f4c46818e17cfc9470a9786b759b19f8"}, + {file = "sphinxcontrib_htmlhelp-2.1.0.tar.gz", hash = "sha256:c9e2916ace8aad64cc13a0d233ee22317f2b9025b9cf3295249fa985cc7082e9"}, ] [package.extras] -lint = ["docutils-stubs", "flake8", "mypy"] +lint = ["mypy", "ruff (==0.5.5)", "types-docutils"] +standalone = ["Sphinx (>=5)"] test = ["html5lib", "pytest"] [[package]] @@ -1531,32 +1835,34 @@ test = ["flake8", "mypy", "pytest"] [[package]] name = "sphinxcontrib-qthelp" -version = "1.0.3" -description = "sphinxcontrib-qthelp is a sphinx extension which outputs QtHelp document." +version = "2.0.0" +description = "sphinxcontrib-qthelp is a sphinx extension which outputs QtHelp documents" optional = false -python-versions = ">=3.5" +python-versions = ">=3.9" files = [ - {file = "sphinxcontrib-qthelp-1.0.3.tar.gz", hash = "sha256:4c33767ee058b70dba89a6fc5c1892c0d57a54be67ddd3e7875a18d14cba5a72"}, - {file = "sphinxcontrib_qthelp-1.0.3-py2.py3-none-any.whl", hash = "sha256:bd9fc24bcb748a8d51fd4ecaade681350aa63009a347a8c14e637895444dfab6"}, + {file = "sphinxcontrib_qthelp-2.0.0-py3-none-any.whl", hash = "sha256:b18a828cdba941ccd6ee8445dbe72ffa3ef8cbe7505d8cd1fa0d42d3f2d5f3eb"}, + {file = "sphinxcontrib_qthelp-2.0.0.tar.gz", hash = "sha256:4fe7d0ac8fc171045be623aba3e2a8f613f8682731f9153bb2e40ece16b9bbab"}, ] [package.extras] -lint = ["docutils-stubs", "flake8", "mypy"] -test = ["pytest"] +lint = ["mypy", "ruff (==0.5.5)", "types-docutils"] +standalone = ["Sphinx (>=5)"] +test = ["defusedxml (>=0.7.1)", "pytest"] [[package]] name = "sphinxcontrib-serializinghtml" -version = "1.1.5" -description = "sphinxcontrib-serializinghtml is a sphinx extension which outputs \"serialized\" HTML files (json and pickle)." +version = "2.0.0" +description = "sphinxcontrib-serializinghtml is a sphinx extension which outputs \"serialized\" HTML files (json and pickle)" optional = false -python-versions = ">=3.5" +python-versions = ">=3.9" files = [ - {file = "sphinxcontrib-serializinghtml-1.1.5.tar.gz", hash = "sha256:aa5f6de5dfdf809ef505c4895e51ef5c9eac17d0f287933eb49ec495280b6952"}, - {file = "sphinxcontrib_serializinghtml-1.1.5-py2.py3-none-any.whl", hash = "sha256:352a9a00ae864471d3a7ead8d7d79f5fc0b57e8b3f95e9867eb9eb28999b92fd"}, + {file = "sphinxcontrib_serializinghtml-2.0.0-py3-none-any.whl", hash = "sha256:6e2cb0eef194e10c27ec0023bfeb25badbbb5868244cf5bc5bdc04e4464bf331"}, + {file = "sphinxcontrib_serializinghtml-2.0.0.tar.gz", hash = "sha256:e9d912827f872c029017a53f0ef2180b327c3f7fd23c87229f7a8e8b70031d4d"}, ] [package.extras] -lint = ["docutils-stubs", "flake8", "mypy"] +lint = ["mypy", "ruff (==0.5.5)", "types-docutils"] +standalone = ["Sphinx (>=5)"] test = ["pytest"] [[package]] @@ -1582,7 +1888,6 @@ files = [ ] [package.dependencies] -importlib-metadata = {version = ">=3.6", markers = "python_version < \"3.10\""} typing-extensions = ">=4.10.0" [package.extras] @@ -1605,24 +1910,24 @@ urllib3 = ">=2" [[package]] name = "typing-extensions" -version = "4.12.0" +version = "4.12.2" description = "Backported and Experimental Type Hints for Python 3.8+" optional = false python-versions = ">=3.8" files = [ - {file = "typing_extensions-4.12.0-py3-none-any.whl", hash = "sha256:b349c66bea9016ac22978d800cfff206d5f9816951f12a7d0ec5578b0a819594"}, - {file = "typing_extensions-4.12.0.tar.gz", hash = "sha256:8cbcdc8606ebcb0d95453ad7dc5065e6237b6aa230a31e81d0f440c30fed5fd8"}, + {file = "typing_extensions-4.12.2-py3-none-any.whl", hash = "sha256:04e5ca0351e0f3f85c6853954072df659d0d13fac324d0072316b67d7794700d"}, + {file = "typing_extensions-4.12.2.tar.gz", hash = "sha256:1a7ead55c7e559dd4dee8856e3a88b41225abfe1ce8df57b7c13915fe121ffb8"}, ] [[package]] name = "urllib3" -version = "2.2.1" +version = "2.2.2" description = "HTTP library with thread-safe connection pooling, file post, and more." optional = false python-versions = ">=3.8" files = [ - {file = "urllib3-2.2.1-py3-none-any.whl", hash = "sha256:450b20ec296a467077128bff42b73080516e71b56ff59a60a02bef2232c4fa9d"}, - {file = "urllib3-2.2.1.tar.gz", hash = "sha256:d0570876c61ab9e520d776c38acbbb5b05a776d3f9ff98a5c8fd5162a444cf19"}, + {file = "urllib3-2.2.2-py3-none-any.whl", hash = "sha256:a448b2f64d686155468037e1ace9f2d2199776e17f0a46610480d311f73e3472"}, + {file = "urllib3-2.2.2.tar.gz", hash = "sha256:dd505485549a7a552833da5e6063639d0d177c04f23bc3864e41e5dc5f612168"}, ] [package.extras] @@ -1647,6 +1952,101 @@ docs = ["Sphinx (>=6.0)", "myst-parser (>=2.0.0)", "sphinx-rtd-theme (>=1.1.0)"] optional = ["python-socks", "wsaccel"] test = ["websockets"] +[[package]] +name = "websockets" +version = "13.0" +description = "An implementation of the WebSocket Protocol (RFC 6455 & 7692)" +optional = false +python-versions = ">=3.8" +files = [ + {file = "websockets-13.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:ad4fa707ff9e2ffee019e946257b5300a45137a58f41fbd9a4db8e684ab61528"}, + {file = "websockets-13.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:6fd757f313c13c34dae9f126d3ba4cf97175859c719e57c6a614b781c86b617e"}, + {file = "websockets-13.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:cbac2eb7ce0fac755fb983c9247c4a60c4019bcde4c0e4d167aeb17520cc7ef1"}, + {file = "websockets-13.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d4b83cf7354cbbc058e97b3e545dceb75b8d9cf17fd5a19db419c319ddbaaf7a"}, + {file = "websockets-13.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9202c0010c78fad1041e1c5285232b6508d3633f92825687549540a70e9e5901"}, + {file = "websockets-13.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3e6566e79c8c7cbea75ec450f6e1828945fc5c9a4769ceb1c7b6e22470539712"}, + {file = "websockets-13.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:e7fcad070dcd9ad37a09d89a4cbc2a5e3e45080b88977c0da87b3090f9f55ead"}, + {file = "websockets-13.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:0a8f7d65358a25172db00c69bcc7df834155ee24229f560d035758fd6613111a"}, + {file = "websockets-13.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:63b702fb31e3f058f946ccdfa551f4d57a06f7729c369e8815eb18643099db37"}, + {file = "websockets-13.0-cp310-cp310-win32.whl", hash = "sha256:3a20cf14ba7b482c4a1924b5e061729afb89c890ca9ed44ac4127c6c5986e424"}, + {file = "websockets-13.0-cp310-cp310-win_amd64.whl", hash = "sha256:587245f0704d0bb675f919898d7473e8827a6d578e5a122a21756ca44b811ec8"}, + {file = "websockets-13.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:06df8306c241c235075d2ae77367038e701e53bc8c1bb4f6644f4f53aa6dedd0"}, + {file = "websockets-13.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:85a1f92a02f0b8c1bf02699731a70a8a74402bb3f82bee36e7768b19a8ed9709"}, + {file = "websockets-13.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:9ed02c604349068d46d87ef4c2012c112c791f2bec08671903a6bb2bd9c06784"}, + {file = "websockets-13.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b89849171b590107f6724a7b0790736daead40926ddf47eadf998b4ff51d6414"}, + {file = "websockets-13.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:939a16849d71203628157a5e4a495da63967c744e1e32018e9b9e2689aca64d4"}, + {file = "websockets-13.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ad818cdac37c0ad4c58e51cb4964eae4f18b43c4a83cb37170b0d90c31bd80cf"}, + {file = "websockets-13.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:cbfe82a07596a044de78bb7a62519e71690c5812c26c5f1d4b877e64e4f46309"}, + {file = "websockets-13.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:e07e76c49f39c5b45cbd7362b94f001ae209a3ea4905ae9a09cfd53b3c76373d"}, + {file = "websockets-13.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:372f46a0096cfda23c88f7e42349a33f8375e10912f712e6b496d3a9a557290f"}, + {file = "websockets-13.0-cp311-cp311-win32.whl", hash = "sha256:376a43a4fd96725f13450d3d2e98f4f36c3525c562ab53d9a98dd2950dca9a8a"}, + {file = "websockets-13.0-cp311-cp311-win_amd64.whl", hash = "sha256:2be1382a4daa61e2f3e2be3b3c86932a8db9d1f85297feb6e9df22f391f94452"}, + {file = "websockets-13.0-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:b5407c34776b9b77bd89a5f95eb0a34aaf91889e3f911c63f13035220eb50107"}, + {file = "websockets-13.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:4782ec789f059f888c1e8fdf94383d0e64b531cffebbf26dd55afd53ab487ca4"}, + {file = "websockets-13.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:c8feb8e19ef65c9994e652c5b0324abd657bedd0abeb946fb4f5163012c1e730"}, + {file = "websockets-13.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d3f3d2e20c442b58dbac593cb1e02bc02d149a86056cc4126d977ad902472e3b"}, + {file = "websockets-13.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e39d393e0ab5b8bd01717cc26f2922026050188947ff54fe6a49dc489f7750b7"}, + {file = "websockets-13.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1f661a4205741bdc88ac9c2b2ec003c72cee97e4acd156eb733662ff004ba429"}, + {file = "websockets-13.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:384129ad0490e06bab2b98c1da9b488acb35bb11e2464c728376c6f55f0d45f3"}, + {file = "websockets-13.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:df5c0eff91f61b8205a6c9f7b255ff390cdb77b61c7b41f79ca10afcbb22b6cb"}, + {file = "websockets-13.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:02cc9bb1a887dac0e08bf657c5d00aa3fac0d03215d35a599130c2034ae6663a"}, + {file = "websockets-13.0-cp312-cp312-win32.whl", hash = "sha256:d9726d2c9bd6aed8cb994d89b3910ca0079406edce3670886ec828a73e7bdd53"}, + {file = "websockets-13.0-cp312-cp312-win_amd64.whl", hash = "sha256:fa0839f35322f7b038d8adcf679e2698c3a483688cc92e3bd15ee4fb06669e9a"}, + {file = "websockets-13.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:da7e501e59857e8e3e9d10586139dc196b80445a591451ca9998aafba1af5278"}, + {file = "websockets-13.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:a00e1e587c655749afb5b135d8d3edcfe84ec6db864201e40a882e64168610b3"}, + {file = "websockets-13.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:a7fbf2a8fe7556a8f4e68cb3e736884af7bf93653e79f6219f17ebb75e97d8f0"}, + {file = "websockets-13.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7ea9c9c7443a97ea4d84d3e4d42d0e8c4235834edae652993abcd2aff94affd7"}, + {file = "websockets-13.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:35c2221b539b360203f3f9ad168e527bf16d903e385068ae842c186efb13d0ea"}, + {file = "websockets-13.0-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:358d37c5c431dd050ffb06b4b075505aae3f4f795d7fff9794e5ed96ce99b998"}, + {file = "websockets-13.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:038e7a0f1bfafc7bf52915ab3506b7a03d1e06381e9f60440c856e8918138151"}, + {file = "websockets-13.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:fd038bc9e2c134847f1e0ce3191797fad110756e690c2fdd9702ed34e7a43abb"}, + {file = "websockets-13.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:93b8c2008f372379fb6e5d2b3f7c9ec32f7b80316543fd3a5ace6610c5cde1b0"}, + {file = "websockets-13.0-cp313-cp313-win32.whl", hash = "sha256:851fd0afb3bc0b73f7c5b5858975d42769a5fdde5314f4ef2c106aec63100687"}, + {file = "websockets-13.0-cp313-cp313-win_amd64.whl", hash = "sha256:7d14901fdcf212804970c30ab9ee8f3f0212e620c7ea93079d6534863444fb4e"}, + {file = "websockets-13.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:ae7a519a56a714f64c3445cabde9fc2fc927e7eae44f413eae187cddd9e54178"}, + {file = "websockets-13.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:5575031472ca87302aeb2ce2c2349f4c6ea978c86a9d1289bc5d16058ad4c10a"}, + {file = "websockets-13.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:9895df6cd0bfe79d09bcd1dbdc03862846f26fbd93797153de954306620c1d00"}, + {file = "websockets-13.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a4de299c947a54fca9ce1c5fd4a08eb92ffce91961becb13bd9195f7c6e71b47"}, + {file = "websockets-13.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:05c25f7b849702950b6fd0e233989bb73a0d2bc83faa3b7233313ca395205f6d"}, + {file = "websockets-13.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ede95125a30602b1691a4b1da88946bf27dae283cf30f22cd2cb8ca4b2e0d119"}, + {file = "websockets-13.0-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:addf0a16e4983280efed272d8cb3b2e05f0051755372461e7d966b80a6554e16"}, + {file = "websockets-13.0-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:06b3186e97bf9a33921fa60734d5ed90f2a9b407cce8d23c7333a0984049ef61"}, + {file = "websockets-13.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:eae368cac85adc4c7dc3b0d5f84ffcca609d658db6447387300478e44db70796"}, + {file = "websockets-13.0-cp38-cp38-win32.whl", hash = "sha256:337837ac788d955728b1ab01876d72b73da59819a3388e1c5e8e05c3999f1afa"}, + {file = "websockets-13.0-cp38-cp38-win_amd64.whl", hash = "sha256:f66e00e42f25ca7e91076366303e11c82572ca87cc5aae51e6e9c094f315ab41"}, + {file = "websockets-13.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:94c1c02721139fe9940b38d28fb15b4b782981d800d5f40f9966264fbf23dcc8"}, + {file = "websockets-13.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:bd4ba86513430513e2aa25a441bb538f6f83734dc368a2c5d18afdd39097aa33"}, + {file = "websockets-13.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:a1ab8f0e0cadc5be5f3f9fa11a663957fecbf483d434762c8dfb8aa44948944a"}, + {file = "websockets-13.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3670def5d3dfd5af6f6e2b3b243ea8f1f72d8da1ef927322f0703f85c90d9603"}, + {file = "websockets-13.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6058b6be92743358885ad6dcdecb378fde4a4c74d4dd16a089d07580c75a0e80"}, + {file = "websockets-13.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:516062a0a8ef5ecbfa4acbaec14b199fc070577834f9fe3d40800a99f92523ca"}, + {file = "websockets-13.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:da7e918d82e7bdfc6f66d31febe1b2e28a1ca3387315f918de26f5e367f61572"}, + {file = "websockets-13.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:9cc7f35dcb49a4e32db82a849fcc0714c4d4acc9d2273aded2d61f87d7f660b7"}, + {file = "websockets-13.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:f5737c53eb2c8ed8f64b50d3dafd3c1dae739f78aa495a288421ac1b3de82717"}, + {file = "websockets-13.0-cp39-cp39-win32.whl", hash = "sha256:265e1f0d3f788ce8ef99dca591a1aec5263b26083ca0934467ad9a1d1181067c"}, + {file = "websockets-13.0-cp39-cp39-win_amd64.whl", hash = "sha256:4d70c89e3d3b347a7c4d3c33f8d323f0584c9ceb69b82c2ef8a174ca84ea3d4a"}, + {file = "websockets-13.0-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:602cbd010d8c21c8475f1798b705bb18567eb189c533ab5ef568bc3033fdf417"}, + {file = "websockets-13.0-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:bf8eb5dca4f484a60f5327b044e842e0d7f7cdbf02ea6dc4a4f811259f1f1f0b"}, + {file = "websockets-13.0-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:89d795c1802d99a643bf689b277e8604c14b5af1bc0a31dade2cd7a678087212"}, + {file = "websockets-13.0-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:788bc841d250beccff67a20a5a53a15657a60111ef9c0c0a97fbdd614fae0fe2"}, + {file = "websockets-13.0-pp310-pypy310_pp73-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7334752052532c156d28b8eaf3558137e115c7871ea82adff69b6d94a7bee273"}, + {file = "websockets-13.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:e7a1963302947332c3039e3f66209ec73b1626f8a0191649e0713c391e9f5b0d"}, + {file = "websockets-13.0-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:2e1cf4e1eb84b4fd74a47688e8b0940c89a04ad9f6937afa43d468e71128cd68"}, + {file = "websockets-13.0-pp38-pypy38_pp73-macosx_11_0_arm64.whl", hash = "sha256:c026ee729c4ce55708a14b839ba35086dfae265fc12813b62d34ce33f4980c1c"}, + {file = "websockets-13.0-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f5f9d23fbbf96eefde836d9692670bfc89e2d159f456d499c5efcf6a6281c1af"}, + {file = "websockets-13.0-pp38-pypy38_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6ad684cb7efce227d756bae3e8484f2e56aa128398753b54245efdfbd1108f2c"}, + {file = "websockets-13.0-pp38-pypy38_pp73-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e1e10b3fbed7be4a59831d3a939900e50fcd34d93716e433d4193a4d0d1d335d"}, + {file = "websockets-13.0-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:d42a818e634f789350cd8fb413a3f5eec1cf0400a53d02062534c41519f5125c"}, + {file = "websockets-13.0-pp39-pypy39_pp73-macosx_10_15_x86_64.whl", hash = "sha256:e5ba5e9b332267d0f2c33ede390061850f1ac3ee6cd1bdcf4c5ea33ead971966"}, + {file = "websockets-13.0-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:f9af457ed593e35f467140d8b61d425495b127744a9d65d45a366f8678449a23"}, + {file = "websockets-13.0-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bcea3eb58c09c3a31cc83b45c06d5907f02ddaf10920aaa6443975310f699b95"}, + {file = "websockets-13.0-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c210d1460dc8d326ffdef9703c2f83269b7539a1690ad11ae04162bc1878d33d"}, + {file = "websockets-13.0-pp39-pypy39_pp73-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b32f38bc81170fd56d0482d505b556e52bf9078b36819a8ba52624bd6667e39e"}, + {file = "websockets-13.0-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:81a11a1ddd5320429db47c04d35119c3e674d215173d87aaeb06ae80f6e9031f"}, + {file = "websockets-13.0-py3-none-any.whl", hash = "sha256:dbbac01e80aee253d44c4f098ab3cc17c822518519e869b284cfbb8cd16cc9de"}, + {file = "websockets-13.0.tar.gz", hash = "sha256:b7bf950234a482b7461afdb2ec99eee3548ec4d53f418c7990bb79c620476602"}, +] + [[package]] name = "werkzeug" version = "3.0.3" @@ -1664,22 +2064,7 @@ MarkupSafe = ">=2.1.1" [package.extras] watchdog = ["watchdog (>=2.3)"] -[[package]] -name = "zipp" -version = "3.19.1" -description = "Backport of pathlib-compatible object wrapper for zip files" -optional = false -python-versions = ">=3.8" -files = [ - {file = "zipp-3.19.1-py3-none-any.whl", hash = "sha256:2828e64edb5386ea6a52e7ba7cdb17bb30a73a858f5eb6eb93d8d36f5ea26091"}, - {file = "zipp-3.19.1.tar.gz", hash = "sha256:35427f6d5594f4acf82d25541438348c26736fa9b3afa2754bcd63cdb99d8e8f"}, -] - -[package.extras] -doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"] -test = ["big-O", "jaraco.functools", "jaraco.itertools", "jaraco.test", "more-itertools", "pytest (>=6,!=8.1.*)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-ignore-flaky", "pytest-mypy", "pytest-ruff (>=0.2.1)"] - [metadata] lock-version = "2.0" -python-versions = "^3.8.1" -content-hash = "f31a679539ac947fa6513bb72fa994e992f128bd666dba7fd87d57f2e315fedf" +python-versions = "^3.10.0" +content-hash = "6bae0a8686c4f2c807706e7f3676e57bb58675e48a325f9a883ad5cbe647a908" diff --git a/pycardano/backend/__init__.py b/pycardano/backend/__init__.py index 515b7cde..5c10a07a 100644 --- a/pycardano/backend/__init__.py +++ b/pycardano/backend/__init__.py @@ -3,4 +3,4 @@ from .base import * from .blockfrost import * from .cardano_cli import * -from .ogmios import * +from .ogmios_v5 import * diff --git a/pycardano/backend/kupo.py b/pycardano/backend/kupo.py new file mode 100644 index 00000000..1f6452db --- /dev/null +++ b/pycardano/backend/kupo.py @@ -0,0 +1,230 @@ +from typing import Dict, List, Optional, Union + +import requests +from cachetools import Cache, LRUCache, TTLCache + +from pycardano.address import Address +from pycardano.backend.base import ( + ChainContext, + GenesisParameters, +) +from pycardano.backend.blockfrost import _try_fix_script +from pycardano.hash import DatumHash +from pycardano.network import Network +from pycardano.plutus import ExecutionUnits, PlutusV1Script, PlutusV2Script +from pycardano.serialization import RawCBOR +from pycardano.transaction import ( + Asset, + MultiAsset, + TransactionInput, + TransactionOutput, + UTxO, + Value, +) + +__all__ = ["KupoChainContextExtension"] + + +class KupoChainContextExtension(ChainContext): + _wrapped_backend: ChainContext + _kupo_url: Optional[str] + _utxo_cache: Cache + _datum_cache: Cache + _refetch_chain_tip_interval: int + + def __init__( + self, + wrapped_backend: ChainContext, + kupo_url: Optional[str] = None, + refetch_chain_tip_interval: int = 10, + utxo_cache_size: int = 1000, + datum_cache_size: int = 1000, + ): + self._kupo_url = kupo_url + self._wrapped_backend = wrapped_backend + self._refetch_chain_tip_interval = refetch_chain_tip_interval + self._utxo_cache = TTLCache( + ttl=self._refetch_chain_tip_interval, maxsize=utxo_cache_size + ) + self._datum_cache = LRUCache(maxsize=datum_cache_size) + + @property + def genesis_param(self) -> GenesisParameters: + """Get chain genesis parameters""" + + return self._wrapped_backend.genesis_param + + @property + def network(self) -> Network: + """Get current network""" + return self._wrapped_backend.network + + @property + def epoch(self) -> int: + """Current epoch number""" + return self._wrapped_backend.epoch + + @property + def last_block_slot(self) -> int: + """Last block slot""" + return self._wrapped_backend.last_block_slot + + def _utxos(self, address: str) -> List[UTxO]: + """Get all UTxOs associated with an address. + + Args: + address (str): An address encoded with bech32. + + Returns: + List[UTxO]: A list of UTxOs. + """ + key = (self.last_block_slot, address) + if key in self._utxo_cache: + return self._utxo_cache[key] + + if self._kupo_url: + utxos = self._utxos_kupo(address) + else: + utxos = self._wrapped_backend.utxos(address) + + self._utxo_cache[key] = utxos + + return utxos + + def _get_datum_from_kupo(self, datum_hash: str) -> Optional[RawCBOR]: + """Get datum from Kupo. + + Args: + datum_hash (str): A datum hash. + + Returns: + Optional[RawCBOR]: A datum. + """ + datum = self._datum_cache.get(datum_hash, None) + + if datum is not None: + return datum + + if self._kupo_url is None: + raise AssertionError( + "kupo_url object attribute has not been assigned properly." + ) + + kupo_datum_url = self._kupo_url + "/datums/" + datum_hash + datum_result = requests.get(kupo_datum_url).json() + if datum_result and datum_result["datum"] != datum_hash: + datum = RawCBOR(bytes.fromhex(datum_result["datum"])) + + self._datum_cache[datum_hash] = datum + return datum + + def _utxos_kupo(self, address: str) -> List[UTxO]: + """Get all UTxOs associated with an address with Kupo. + Since UTxO querying will be deprecated from Ogmios in next + major release: https://ogmios.dev/mini-protocols/local-state-query/. + + Args: + address (str): An address encoded with bech32. + + Returns: + List[UTxO]: A list of UTxOs. + """ + if self._kupo_url is None: + raise AssertionError( + "kupo_url object attribute has not been assigned properly." + ) + + kupo_utxo_url = self._kupo_url + "/matches/" + address + "?unspent" + results = requests.get(kupo_utxo_url).json() + + utxos = [] + + for result in results: + tx_id = result["transaction_id"] + index = result["output_index"] + + if result["spent_at"] is None: + tx_in = TransactionInput.from_primitive([tx_id, index]) + + lovelace_amount = result["value"]["coins"] + + script = None + script_hash = result.get("script_hash", None) + if script_hash: + kupo_script_url = self._kupo_url + "/scripts/" + script_hash + script = requests.get(kupo_script_url).json() + if script["language"] == "plutus:v2": + script = PlutusV2Script(bytes.fromhex(script["script"])) + script = _try_fix_script(script_hash, script) + elif script["language"] == "plutus:v1": + script = PlutusV1Script(bytes.fromhex(script["script"])) + script = _try_fix_script(script_hash, script) + else: + raise ValueError("Unknown plutus script type") + + datum = None + datum_hash = ( + DatumHash.from_primitive(result["datum_hash"]) + if result["datum_hash"] + else None + ) + if datum_hash and result.get("datum_type", "inline"): + datum = self._get_datum_from_kupo(result["datum_hash"]) + + if not result["value"]["assets"]: + tx_out = TransactionOutput( + Address.from_primitive(address), + amount=lovelace_amount, + datum_hash=datum_hash, + datum=datum, + script=script, + ) + else: + multi_assets = MultiAsset() + + for asset, quantity in result["value"]["assets"].items(): + policy_hex, policy, asset_name_hex = self._extract_asset_info( + asset + ) + multi_assets.setdefault(policy, Asset())[ + asset_name_hex + ] = quantity + + tx_out = TransactionOutput( + Address.from_primitive(address), + amount=Value(lovelace_amount, multi_assets), + datum_hash=datum_hash, + datum=datum, + script=script, + ) + utxos.append(UTxO(tx_in, tx_out)) + else: + continue + + return utxos + + def submit_tx_cbor(self, cbor: Union[bytes, str]): + """Submit a transaction to the blockchain. + + Args: + cbor (Union[bytes, str]): The transaction to be submitted. + + Raises: + :class:`InvalidArgumentException`: When the transaction is invalid. + :class:`TransactionFailedException`: When fails to submit the transaction to blockchain. + """ + return self._wrapped_backend.submit_tx_cbor(cbor) + + def evaluate_tx_cbor(self, cbor: Union[bytes, str]) -> Dict[str, ExecutionUnits]: + """Evaluate execution units of a transaction. + + Args: + cbor (Union[bytes, str]): The serialized transaction to be evaluated. + + Returns: + Dict[str, ExecutionUnits]: A list of execution units calculated for each of the transaction's redeemers + + Raises: + :class:`TransactionFailedException`: When fails to evaluate the transaction. + """ + return self._wrapped_backend.evaluate_tx_cbor(cbor) diff --git a/pycardano/backend/ogmios.py b/pycardano/backend/ogmios_v5.py similarity index 77% rename from pycardano/backend/ogmios.py rename to pycardano/backend/ogmios_v5.py index 63ffaf14..7449db33 100644 --- a/pycardano/backend/ogmios.py +++ b/pycardano/backend/ogmios_v5.py @@ -5,7 +5,6 @@ from fractions import Fraction from typing import Any, Dict, List, Optional, Tuple, Union -import requests import websocket from cachetools import Cache, LRUCache, TTLCache, func @@ -16,7 +15,6 @@ GenesisParameters, ProtocolParameters, ) -from pycardano.backend.blockfrost import _try_fix_script from pycardano.exception import TransactionFailedException from pycardano.hash import DatumHash, ScriptHash from pycardano.network import Network @@ -32,8 +30,9 @@ Value, ) from pycardano.types import JsonDict +from pycardano.backend.kupo import KupoChainContextExtension -__all__ = ["OgmiosChainContext"] +__all__ = ["OgmiosV5ChainContext"] class OgmiosQueryType(str, Enum): @@ -42,11 +41,10 @@ class OgmiosQueryType(str, Enum): EvaluateTx = "EvaluateTx" -class OgmiosChainContext(ChainContext): +class OgmiosV5ChainContext(ChainContext): _ws_url: str _network: Network _service_name: str - _kupo_url: Optional[str] _last_known_block_slot: int _last_chain_tip_fetch: float _genesis_param: Optional[GenesisParameters] @@ -59,7 +57,6 @@ def __init__( ws_url: str, network: Network, compact_result=True, - kupo_url=None, refetch_chain_tip_interval: Optional[float] = None, utxo_cache_size: int = 10000, datum_cache_size: int = 10000, @@ -67,7 +64,6 @@ def __init__( self._ws_url = ws_url self._network = network self._service_name = "ogmios.v1:compact" if compact_result else "ogmios" - self._kupo_url = kupo_url self._last_known_block_slot = 0 self._refetch_chain_tip_interval = ( refetch_chain_tip_interval @@ -271,127 +267,12 @@ def _utxos(self, address: str) -> List[UTxO]: if key in self._utxo_cache: return self._utxo_cache[key] - if self._kupo_url: - utxos = self._utxos_kupo(address) - else: - utxos = self._utxos_ogmios(address) + utxos = self._utxos_ogmios(address) self._utxo_cache[key] = utxos return utxos - def _get_datum_from_kupo(self, datum_hash: str) -> Optional[RawCBOR]: - """Get datum from Kupo. - - Args: - datum_hash (str): A datum hash. - - Returns: - Optional[RawCBOR]: A datum. - """ - datum = self._datum_cache.get(datum_hash, None) - - if datum is not None: - return datum - - if self._kupo_url is None: - raise AssertionError( - "kupo_url object attribute has not been assigned properly." - ) - - kupo_datum_url = self._kupo_url + "/datums/" + datum_hash - datum_result = requests.get(kupo_datum_url).json() - if datum_result and datum_result["datum"] != datum_hash: - datum = RawCBOR(bytes.fromhex(datum_result["datum"])) - - self._datum_cache[datum_hash] = datum - return datum - - def _utxos_kupo(self, address: str) -> List[UTxO]: - """Get all UTxOs associated with an address with Kupo. - Since UTxO querying will be deprecated from Ogmios in next - major release: https://ogmios.dev/mini-protocols/local-state-query/. - - Args: - address (str): An address encoded with bech32. - - Returns: - List[UTxO]: A list of UTxOs. - """ - if self._kupo_url is None: - raise AssertionError( - "kupo_url object attribute has not been assigned properly." - ) - - kupo_utxo_url = self._kupo_url + "/matches/" + address + "?unspent" - results = requests.get(kupo_utxo_url).json() - - utxos = [] - - for result in results: - tx_id = result["transaction_id"] - index = result["output_index"] - - if result["spent_at"] is None: - tx_in = TransactionInput.from_primitive([tx_id, index]) - - lovelace_amount = result["value"]["coins"] - - script = None - script_hash = result.get("script_hash", None) - if script_hash: - kupo_script_url = self._kupo_url + "/scripts/" + script_hash - script = requests.get(kupo_script_url).json() - if script["language"] == "plutus:v2": - script = PlutusV2Script(bytes.fromhex(script["script"])) - script = _try_fix_script(script_hash, script) - elif script["language"] == "plutus:v1": - script = PlutusV1Script(bytes.fromhex(script["script"])) - script = _try_fix_script(script_hash, script) - else: - raise ValueError("Unknown plutus script type") - - datum = None - datum_hash = ( - DatumHash.from_primitive(result["datum_hash"]) - if result["datum_hash"] - else None - ) - if datum_hash and result.get("datum_type", "inline"): - datum = self._get_datum_from_kupo(result["datum_hash"]) - - if not result["value"]["assets"]: - tx_out = TransactionOutput( - Address.from_primitive(address), - amount=lovelace_amount, - datum_hash=datum_hash, - datum=datum, - script=script, - ) - else: - multi_assets = MultiAsset() - - for asset, quantity in result["value"]["assets"].items(): - policy_hex, policy, asset_name_hex = self._extract_asset_info( - asset - ) - multi_assets.setdefault(policy, Asset())[ - asset_name_hex - ] = quantity - - tx_out = TransactionOutput( - Address.from_primitive(address), - amount=Value(lovelace_amount, multi_assets), - datum_hash=datum_hash, - datum=datum, - script=script, - ) - utxos.append(UTxO(tx_in, tx_out)) - else: - continue - - return utxos - def _check_utxo_unspent(self, tx_id: str, index: int) -> bool: """Check whether an UTxO is unspent with Ogmios. @@ -545,3 +426,25 @@ def evaluate_tx_cbor(self, cbor: Union[bytes, str]) -> Dict[str, ExecutionUnits] result["EvaluationResult"][k]["steps"], ) return result["EvaluationResult"] + + +def KupoOgmiosV5ChainContext( + ws_url: str, + network: Network, + compact_result=True, + refetch_chain_tip_interval: Optional[float] = None, + utxo_cache_size: int = 10000, + datum_cache_size: int = 10000, + kupo_url: Optional[str] = None, +) -> KupoChainContextExtension: + return KupoChainContextExtension( + OgmiosV5ChainContext( + ws_url, + network, + compact_result, + refetch_chain_tip_interval, + utxo_cache_size, + datum_cache_size, + ), + kupo_url, + ) diff --git a/pycardano/backend/ogmios_v6.py b/pycardano/backend/ogmios_v6.py new file mode 100644 index 00000000..52acc701 --- /dev/null +++ b/pycardano/backend/ogmios_v6.py @@ -0,0 +1,366 @@ +import time +from typing import Optional, Union, Dict +from cachetools import Cache, LRUCache, TTLCache, func + +from ogmios.client import Client +from ogmios.datatypes import ( + ProtocolParameters, + Era, + Tip, + Utxo, + Address, + TxOutputReference, +) +from ogmios.utils import get_current_era, GenesisParameters + +from pycardano import RawCBOR +from pycardano.backend.kupo import KupoChainContextExtension +from pycardano.backend.base import ( + ChainContext, + ProtocolParameters as pycProtocolParameters, +) +from pycardano.network import Network +from pycardano.transaction import ( + UTxO, + TransactionOutput, + Value, + TransactionInput, + MultiAsset, + AssetName, + Asset, +) +from pycardano.plutus import ( + PLUTUS_V1_COST_MODEL, + PLUTUS_V2_COST_MODEL, + PlutusV1Script, + PlutusV2Script, + ExecutionUnits, +) +from pycardano.hash import ScriptHash, DatumHash + +ALONZO_COINS_PER_UTXO_WORD = 34482 +DEFAULT_REFETCH_INTERVAL = 1000 + + +class OgmiosV6ChainContext(ChainContext): + """Ogmios chain context for use with PyCardano""" + + _network: Network + _client: Client + _service_name: str + _last_known_block_slot: int + _last_chain_tip_fetch: float + _genesis_param: Optional[GenesisParameters] + _protocol_param: Optional[ProtocolParameters] + _utxo_cache: Cache + _datum_cache: Cache + + def __init__( + self, + host: str = "localhost", + port: int = 1337, + secure: bool = False, + refetch_chain_tip_interval: Optional[float] = None, + utxo_cache_size: int = 10000, + datum_cache_size: int = 10000, + network: Network = Network.TESTNET, + ): + self.host = host + self.port = port + self.secure = secure + self._network = network + self._service_name = "ogmios" + self._last_known_block_slot = 0 + self._refetch_chain_tip_interval = ( + refetch_chain_tip_interval + if refetch_chain_tip_interval is not None + else DEFAULT_REFETCH_INTERVAL + ) + self._last_chain_tip_fetch = 0 + self._genesis_param = None + self._protocol_param = None + + self._utxo_cache = TTLCache( + ttl=self._refetch_chain_tip_interval, maxsize=utxo_cache_size + ) + self._datum_cache = LRUCache(maxsize=datum_cache_size) + + def _query_current_era(self) -> Era: + with Client(self.host, self.port, self.secure) as client: + return get_current_era(client) + + def _query_current_epoch(self) -> int: + with Client(self.host, self.port, self.secure) as client: + epoch, _ = client.query_epoch.execute() + return epoch + + def _query_chain_tip(self) -> Tip: + with Client(self.host, self.port, self.secure) as client: + tip, _ = client.query_network_tip.execute() + return tip + + def _query_utxos_by_address(self, address: Address) -> list[Utxo]: + with Client(self.host, self.port, self.secure) as client: + utxos, _ = client.query_utxo.execute([address]) + return utxos + + def _query_utxos_by_tx_id(self, tx_id: str, index: int) -> list[Utxo]: + with Client(self.host, self.port, self.secure) as client: + utxos, _ = client.query_utxo.execute([TxOutputReference(tx_id, index)]) + return utxos + + def _is_chain_tip_updated(self): + # fetch at most every twenty seconds! + if time.time() - self._last_chain_tip_fetch < self._refetch_chain_tip_interval: + return False + self._last_chain_tip_fetch = time.time() + slot = self.last_block_slot + if self._last_known_block_slot < slot: + self._last_known_block_slot = slot + return True + else: + return False + + @staticmethod + def _fraction_parser(fraction: str) -> float: + x, y = fraction.split("/") + return int(x) / int(y) + + @property + def protocol_param(self) -> pycProtocolParameters: + if not self._protocol_param or self._is_chain_tip_updated(): + self._protocol_param = self._fetch_protocol_param() + return self._protocol_param + + def _fetch_protocol_param(self) -> ProtocolParameters: + with Client(self.host, self.port, self.secure) as client: + protocol_parameters, _ = client.query_protocol_parameters.execute() + pyc_protocol_params = pycProtocolParameters( + min_fee_constant=protocol_parameters.min_fee_constant.lovelace, + min_fee_coefficient=protocol_parameters.min_fee_coefficient, + min_pool_cost=protocol_parameters.min_stake_pool_cost.lovelace, + max_block_size=protocol_parameters.max_block_body_size.get("bytes"), + max_tx_size=protocol_parameters.max_transaction_size.get("bytes"), + max_block_header_size=protocol_parameters.max_block_header_size.get( + "bytes" + ), + key_deposit=protocol_parameters.stake_credential_deposit.lovelace, + pool_deposit=protocol_parameters.stake_pool_deposit.lovelace, + pool_influence=eval(protocol_parameters.stake_pool_pledge_influence), + monetary_expansion=eval(protocol_parameters.monetary_expansion), + treasury_expansion=eval(protocol_parameters.treasury_expansion), + decentralization_param=None, # TODO + extra_entropy=protocol_parameters.extra_entropy, + protocol_major_version=protocol_parameters.version.get("major"), + protocol_minor_version=protocol_parameters.version.get("minor"), + min_utxo=None, + price_mem=eval( + protocol_parameters.script_execution_prices.get("memory") + ), + price_step=eval(protocol_parameters.script_execution_prices.get("cpu")), + max_tx_ex_mem=protocol_parameters.max_execution_units_per_transaction.get( + "memory" + ), + max_tx_ex_steps=protocol_parameters.max_execution_units_per_transaction.get( + "cpu" + ), + max_block_ex_mem=protocol_parameters.max_execution_units_per_block.get( + "memory" + ), + max_block_ex_steps=protocol_parameters.max_execution_units_per_block.get( + "cpu" + ), + max_val_size=protocol_parameters.max_value_size.get("bytes"), + collateral_percent=protocol_parameters.collateral_percentage, + max_collateral_inputs=protocol_parameters.max_collateral_inputs, + coins_per_utxo_word=ALONZO_COINS_PER_UTXO_WORD, + coins_per_utxo_byte=protocol_parameters.min_utxo_deposit_coefficient, + cost_models=self._parse_cost_models( + protocol_parameters.plutus_cost_models + ), + ) + return pyc_protocol_params + + @property + def genesis_param(self) -> GenesisParameters: + if not self._genesis_param or self._is_chain_tip_updated(): + self._genesis_param = self._fetch_genesis_param() + + # Update the refetch interval if we haven't calculated it yet + if ( + self._refetch_chain_tip_interval == DEFAULT_REFETCH_INTERVAL + and self._genesis_param.slot_length is not None + and self._genesis_param.active_slots_coefficient is not None + ): + self._refetch_chain_tip_interval = self._genesis_param.slot_length.get( + "milliseconds" + ) / eval(self._genesis_param.active_slots_coefficient) + return self._genesis_param + + def _fetch_genesis_param(self) -> GenesisParameters: + with Client(self.host, self.port, self.secure) as client: + return GenesisParameters(client, self._query_current_era()) + + @property + def network(self) -> Network: + return self._network + + @property + def epoch(self) -> int: + return self._query_current_epoch() + + @property + @func.ttl_cache(ttl=1) + def last_block_slot(self) -> int: + tip = self._query_chain_tip() + return tip.slot + + def _utxos(self, address: str) -> list[UTxO]: + key = (self.last_block_slot, address) + if key in self._utxo_cache: + return self._utxo_cache[key] + + utxos = self._utxos_ogmios(Address(address=address)) + + self._utxo_cache[key] = utxos + + return utxos + + def _check_utxo_unspent(self, tx_id: str, index: int) -> bool: + results = self._query_utxos_by_tx_id(tx_id, index) + return len(results) > 0 + + def _utxos_ogmios(self, address: Address) -> list[Utxo]: + """Get all UTxOs associated with an address with Ogmios. + + Args: + address (str): An address encoded with bech32. + + Returns: + List[UTxO]: A list of UTxOs. + """ + results = self._query_utxos_by_address(address) + + utxos = [] + for result in results: + utxos.append(self._utxo_from_ogmios_result(result)) + + return utxos + + def _utxo_from_ogmios_result(self, utxo: Utxo) -> UTxO: + """Convert an Ogmios UTxO result to a PyCardano UTxO.""" + tx_in = TransactionInput.from_primitive([utxo.tx_id, utxo.index]) + lovelace_amount = utxo.value.get("ada").get("lovelace", 0) + script = utxo.script + if script: + # TODO: Need to test with native scripts + match script["language"]: + case "plutus:v2": + script = PlutusV2Script(bytes.fromhex(script["cbor"])) + case "plutus:v1": + script = PlutusV1Script(bytes.fromhex(script["cbor"])) + case _: + raise ValueError("Unknown plutus script type") + datum_hash = ( + DatumHash.from_primitive(utxo.datum_hash) if utxo.datum_hash else None + ) + datum = None + if utxo.datum and utxo.datum != utxo.datum_hash: + datum = RawCBOR(bytes.fromhex(utxo.datum)) + if set(utxo.value.keys()) == {"ada"}: + tx_out = TransactionOutput( + Address.from_primitive(utxo.address), + amount=lovelace_amount, + datum_hash=datum_hash, + datum=datum, + script=script, + ) + else: + multi_assets = MultiAsset() + for asset_hex, token in utxo.value.items(): + if asset_hex != "ada": + for token_name_hex, quantity in token.items(): + policy = ScriptHash.from_primitive(asset_hex) + token_name = AssetName.from_primitive(token_name_hex) + multi_assets.setdefault(policy, Asset())[token_name] = quantity + + tx_out = TransactionOutput( + Address.from_primitive(utxo.address), + amount=Value(lovelace_amount, multi_assets), + datum_hash=datum_hash, + datum=datum, + script=script, + ) + pyc_utxo = UTxO(tx_in, tx_out) + return pyc_utxo + + def utxo_by_tx_id(self, tx_id: str, index: int) -> Optional[UTxO]: + utxos = self._query_utxos_by_tx_id(tx_id, index) + if len(utxos) > 0: + return self._utxo_from_ogmios_result(utxos[0]) + return None + + def submit_tx_cbor(self, cbor: Union[bytes, str]): + if isinstance(cbor, bytes): + cbor = cbor.hex() + with Client(self.host, self.port, self.secure) as client: + client.submit_transaction.execute(cbor) + + def evaluate_tx_cbor(self, cbor: Union[bytes, str]) -> Dict[str, ExecutionUnits]: + if isinstance(cbor, bytes): + cbor = cbor.hex() + with Client(self.host, self.port, self.secure) as client: + result, _ = client.evaluate_transaction.execute(cbor) + result_dict = {} + for res in result: + purpose = res["validator"]["purpose"] + # Hotfix: this purpose has been renamed in the latest version of Ogmios + if purpose == "withdraw": + purpose = "withdrawal" + result_dict[f"{purpose}:{res['validator']['index']}"] = ExecutionUnits( + mem=res["budget"]["memory"], + steps=res["budget"]["cpu"], + ) + return result_dict + + def _parse_cost_models(self, plutus_cost_models): + ogmios_cost_models = plutus_cost_models or {} + + cost_models = {} + if "plutus:v1" in ogmios_cost_models: + cost_models["PlutusV1"] = dict( + zip( + sorted(PLUTUS_V1_COST_MODEL.keys()), + ogmios_cost_models["plutus:v1"].copy(), + ) + ) + if "plutus:v2" in ogmios_cost_models: + cost_models["PlutusV2"] = dict( + zip( + sorted(PLUTUS_V2_COST_MODEL.keys()), + ogmios_cost_models["plutus:v2"].copy(), + ) + ) + return cost_models + + +def KupoOgmiosV6ChainContext( + ws_url: str, + network: Network, + compact_result=True, + refetch_chain_tip_interval: Optional[float] = None, + utxo_cache_size: int = 10000, + datum_cache_size: int = 10000, + kupo_url: Optional[str] = None, +) -> KupoChainContextExtension: + return KupoChainContextExtension( + OgmiosV6ChainContext( + ws_url, + network, + compact_result, + refetch_chain_tip_interval, + utxo_cache_size, + datum_cache_size, + ), + kupo_url, + ) diff --git a/pyproject.toml b/pyproject.toml index 69ae861c..7a20fadf 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -21,7 +21,7 @@ repository = "https://github.com/Python-Cardano/pycardano" license = "MIT" [tool.poetry.dependencies] -python = "^3.8.1" +python = "^3.10.0" PyNaCl = "^1.5.0" cbor2 = "^5.4.3" typeguard = "^4.3.0" @@ -35,6 +35,9 @@ frozendict = "^2.3.8" frozenlist = "^1.3.3" cachetools = "^5.3.0" docker = "^7.1.0" +ogmios = "^1.1.1" +requests = "^2.32.3" +websockets = "^13.0" [tool.poetry.dev-dependencies] Sphinx = "^5.0.0" diff --git a/test/pycardano/backend/test_ogmios.py b/test/pycardano/backend/test_ogmios.py index 73fa2f29..ddd7975d 100644 --- a/test/pycardano/backend/test_ogmios.py +++ b/test/pycardano/backend/test_ogmios.py @@ -4,7 +4,7 @@ import pytest from pycardano.backend.base import GenesisParameters, ProtocolParameters -from pycardano.backend.ogmios import OgmiosChainContext +from pycardano.backend.ogmios_v5 import OgmiosV5ChainContext from pycardano.network import Network from pycardano.transaction import MultiAsset, TransactionInput @@ -115,7 +115,7 @@ def chain_context(): "pycardano.backend.ogmios.OgmiosChainContext._request", side_effect=override_request, ): - context = OgmiosChainContext("", Network.TESTNET) + context = OgmiosV5ChainContext("", Network.TESTNET) context._request = override_request return context From 0e285e5bfcb85e56d29cea5202fc910f94a59303 Mon Sep 17 00:00:00 2001 From: Niels Date: Wed, 21 Aug 2024 10:23:41 +0200 Subject: [PATCH 06/44] Fix ogmios test --- .github/workflows/main.yml | 2 +- test/pycardano/backend/{test_ogmios.py => test_ogmios_v5.py} | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) rename test/pycardano/backend/{test_ogmios.py => test_ogmios_v5.py} (99%) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index bb8ace29..e854fa54 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -14,7 +14,7 @@ jobs: strategy: matrix: os: [ubuntu-latest, macos-latest] - python-version: [3.8, 3.9, '3.10', '3.11'] + python-version: ['3.10', '3.11'] steps: - uses: actions/checkout@v4 diff --git a/test/pycardano/backend/test_ogmios.py b/test/pycardano/backend/test_ogmios_v5.py similarity index 99% rename from test/pycardano/backend/test_ogmios.py rename to test/pycardano/backend/test_ogmios_v5.py index ddd7975d..ee80058a 100644 --- a/test/pycardano/backend/test_ogmios.py +++ b/test/pycardano/backend/test_ogmios_v5.py @@ -112,7 +112,7 @@ def override_request(method, args): @pytest.fixture def chain_context(): with patch( - "pycardano.backend.ogmios.OgmiosChainContext._request", + "pycardano.backend.ogmios_v5.OgmiosV5ChainContext._request", side_effect=override_request, ): context = OgmiosV5ChainContext("", Network.TESTNET) From 9449621ae936e51a12295367dc61fc8f00b1a90b Mon Sep 17 00:00:00 2001 From: Niels Date: Tue, 27 Aug 2024 23:31:42 +0200 Subject: [PATCH 07/44] Fixes --- poetry.lock | 14 +++++------ pycardano/backend/kupo.py | 25 +++++++++++++++---- pycardano/backend/ogmios_v5.py | 24 ++++--------------- pycardano/backend/ogmios_v6.py | 44 ++++++++++++++++++---------------- 4 files changed, 54 insertions(+), 53 deletions(-) diff --git a/poetry.lock b/poetry.lock index a46af1d2..d040910b 100644 --- a/poetry.lock +++ b/poetry.lock @@ -897,13 +897,13 @@ pyreadline3 = {version = "*", markers = "sys_platform == \"win32\" and python_ve [[package]] name = "idna" -version = "3.7" +version = "3.8" description = "Internationalized Domain Names in Applications (IDNA)" optional = false -python-versions = ">=3.5" +python-versions = ">=3.6" files = [ - {file = "idna-3.7-py3-none-any.whl", hash = "sha256:82fee1fc78add43492d3a1898bfa6d8a904cc97d8427f683ed8e798d07761aa0"}, - {file = "idna-3.7.tar.gz", hash = "sha256:028ff3aadf0609c1fd278d8ea3089299412a7a8b9bd005dd08b9f8285bcb5cfc"}, + {file = "idna-3.8-py3-none-any.whl", hash = "sha256:050b4e5baadcd44d760cedbd2b8e639f2ff89bbc7a5730fcc662954303377aac"}, + {file = "idna-3.8.tar.gz", hash = "sha256:d838c2c0ed6fced7693d5e8ab8e734d5f8fda53a039c0164afb0b82e771e3603"}, ] [[package]] @@ -2049,13 +2049,13 @@ files = [ [[package]] name = "werkzeug" -version = "3.0.3" +version = "3.0.4" description = "The comprehensive WSGI web application library." optional = false python-versions = ">=3.8" files = [ - {file = "werkzeug-3.0.3-py3-none-any.whl", hash = "sha256:fc9645dc43e03e4d630d23143a04a7f947a9a3b5727cd535fdfe155a17cc48c8"}, - {file = "werkzeug-3.0.3.tar.gz", hash = "sha256:097e5bfda9f0aba8da6b8545146def481d06aa7d3266e7448e2cccf67dd8bd18"}, + {file = "werkzeug-3.0.4-py3-none-any.whl", hash = "sha256:02c9eb92b7d6c06f31a782811505d2157837cea66aaede3e217c7c27c039476c"}, + {file = "werkzeug-3.0.4.tar.gz", hash = "sha256:34f2371506b250df4d4f84bfe7b0921e4762525762bbd936614909fe25cd7306"}, ] [package.dependencies] diff --git a/pycardano/backend/kupo.py b/pycardano/backend/kupo.py index 1f6452db..28889182 100644 --- a/pycardano/backend/kupo.py +++ b/pycardano/backend/kupo.py @@ -1,4 +1,4 @@ -from typing import Dict, List, Optional, Union +from typing import Dict, List, Optional, Union, Tuple import requests from cachetools import Cache, LRUCache, TTLCache @@ -9,7 +9,7 @@ GenesisParameters, ) from pycardano.backend.blockfrost import _try_fix_script -from pycardano.hash import DatumHash +from pycardano.hash import DatumHash, ScriptHash from pycardano.network import Network from pycardano.plutus import ExecutionUnits, PlutusV1Script, PlutusV2Script from pycardano.serialization import RawCBOR @@ -20,11 +20,28 @@ TransactionOutput, UTxO, Value, + AssetName, ) __all__ = ["KupoChainContextExtension"] +def extract_asset_info(asset_hash: str) -> Tuple[str, ScriptHash, AssetName]: + split_result = asset_hash.split(".") + + if len(split_result) == 1: + policy_hex, asset_name_hex = split_result[0], "" + elif len(split_result) == 2: + policy_hex, asset_name_hex = split_result + else: + raise ValueError(f"Unable to parse asset hash: {asset_hash}") + + policy = ScriptHash.from_primitive(policy_hex) + asset_name = AssetName.from_primitive(asset_name_hex) + + return policy_hex, policy, asset_name + + class KupoChainContextExtension(ChainContext): _wrapped_backend: ChainContext _kupo_url: Optional[str] @@ -183,9 +200,7 @@ def _utxos_kupo(self, address: str) -> List[UTxO]: multi_assets = MultiAsset() for asset, quantity in result["value"]["assets"].items(): - policy_hex, policy, asset_name_hex = self._extract_asset_info( - asset - ) + policy_hex, policy, asset_name_hex = extract_asset_info(asset) multi_assets.setdefault(policy, Asset())[ asset_name_hex ] = quantity diff --git a/pycardano/backend/ogmios_v5.py b/pycardano/backend/ogmios_v5.py index 7449db33..528bd0fb 100644 --- a/pycardano/backend/ogmios_v5.py +++ b/pycardano/backend/ogmios_v5.py @@ -3,7 +3,7 @@ from datetime import datetime, timezone from enum import Enum from fractions import Fraction -from typing import Any, Dict, List, Optional, Tuple, Union +from typing import Any, Dict, List, Optional, Union import websocket from cachetools import Cache, LRUCache, TTLCache, func @@ -16,13 +16,12 @@ ProtocolParameters, ) from pycardano.exception import TransactionFailedException -from pycardano.hash import DatumHash, ScriptHash +from pycardano.hash import DatumHash from pycardano.network import Network from pycardano.plutus import ExecutionUnits, PlutusV1Script, PlutusV2Script from pycardano.serialization import RawCBOR from pycardano.transaction import ( Asset, - AssetName, MultiAsset, TransactionInput, TransactionOutput, @@ -30,7 +29,7 @@ Value, ) from pycardano.types import JsonDict -from pycardano.backend.kupo import KupoChainContextExtension +from pycardano.backend.kupo import KupoChainContextExtension, extract_asset_info __all__ = ["OgmiosV5ChainContext"] @@ -283,21 +282,6 @@ def _check_utxo_unspent(self, tx_id: str, index: int) -> bool: results = self._query_utxos_by_tx_id(tx_id, index) return len(results) > 0 - def _extract_asset_info(self, asset_hash: str) -> Tuple[str, ScriptHash, AssetName]: - split_result = asset_hash.split(".") - - if len(split_result) == 1: - policy_hex, asset_name_hex = split_result[0], "" - elif len(split_result) == 2: - policy_hex, asset_name_hex = split_result - else: - raise ValueError(f"Unable to parse asset hash: {asset_hash}") - - policy = ScriptHash.from_primitive(policy_hex) - asset_name = AssetName.from_primitive(asset_name_hex) - - return policy_hex, policy, asset_name - def _utxos_ogmios(self, address: str) -> List[UTxO]: """Get all UTxOs associated with an address with Ogmios. @@ -369,7 +353,7 @@ def _utxo_from_ogmios_result(self, result) -> UTxO: multi_assets = MultiAsset() for asset, quantity in output["value"]["assets"].items(): - policy_hex, policy, asset_name_hex = self._extract_asset_info(asset) + policy_hex, policy, asset_name_hex = extract_asset_info(asset) multi_assets.setdefault(policy, Asset())[asset_name_hex] = quantity tx_out = TransactionOutput( diff --git a/pycardano/backend/ogmios_v6.py b/pycardano/backend/ogmios_v6.py index 52acc701..d5eb0638 100644 --- a/pycardano/backend/ogmios_v6.py +++ b/pycardano/backend/ogmios_v6.py @@ -1,5 +1,5 @@ import time -from typing import Optional, Union, Dict +from typing import Optional, Union, Dict, List from cachetools import Cache, LRUCache, TTLCache, func from ogmios.client import Client @@ -13,7 +13,6 @@ ) from ogmios.utils import get_current_era, GenesisParameters -from pycardano import RawCBOR from pycardano.backend.kupo import KupoChainContextExtension from pycardano.backend.base import ( ChainContext, @@ -28,6 +27,7 @@ MultiAsset, AssetName, Asset, + Address as pyc_Address, ) from pycardano.plutus import ( PLUTUS_V1_COST_MODEL, @@ -37,6 +37,7 @@ ExecutionUnits, ) from pycardano.hash import ScriptHash, DatumHash +from pycardano.serialization import RawCBOR ALONZO_COINS_PER_UTXO_WORD = 34482 DEFAULT_REFETCH_INTERVAL = 1000 @@ -99,12 +100,12 @@ def _query_chain_tip(self) -> Tip: tip, _ = client.query_network_tip.execute() return tip - def _query_utxos_by_address(self, address: Address) -> list[Utxo]: + def _query_utxos_by_address(self, address: pyc_Address) -> List[Utxo]: with Client(self.host, self.port, self.secure) as client: utxos, _ = client.query_utxo.execute([address]) return utxos - def _query_utxos_by_tx_id(self, tx_id: str, index: int) -> list[Utxo]: + def _query_utxos_by_tx_id(self, tx_id: str, index: int) -> List[Utxo]: with Client(self.host, self.port, self.secure) as client: utxos, _ = client.query_utxo.execute([TxOutputReference(tx_id, index)]) return utxos @@ -215,7 +216,7 @@ def last_block_slot(self) -> int: tip = self._query_chain_tip() return tip.slot - def _utxos(self, address: str) -> list[UTxO]: + def _utxos(self, address: str) -> List[UTxO]: key = (self.last_block_slot, address) if key in self._utxo_cache: return self._utxo_cache[key] @@ -230,7 +231,7 @@ def _check_utxo_unspent(self, tx_id: str, index: int) -> bool: results = self._query_utxos_by_tx_id(tx_id, index) return len(results) > 0 - def _utxos_ogmios(self, address: Address) -> list[Utxo]: + def _utxos_ogmios(self, address: pyc_Address) -> List[Utxo]: """Get all UTxOs associated with an address with Ogmios. Args: @@ -254,13 +255,12 @@ def _utxo_from_ogmios_result(self, utxo: Utxo) -> UTxO: script = utxo.script if script: # TODO: Need to test with native scripts - match script["language"]: - case "plutus:v2": - script = PlutusV2Script(bytes.fromhex(script["cbor"])) - case "plutus:v1": - script = PlutusV1Script(bytes.fromhex(script["cbor"])) - case _: - raise ValueError("Unknown plutus script type") + if script["language"] == "plutus:v2": + script = PlutusV2Script(bytes.fromhex(script["cbor"])) + elif script["language"] == "plutus:v1": + script = PlutusV1Script(bytes.fromhex(script["cbor"])) + else: + raise ValueError("Unknown plutus script type") datum_hash = ( DatumHash.from_primitive(utxo.datum_hash) if utxo.datum_hash else None ) @@ -269,7 +269,7 @@ def _utxo_from_ogmios_result(self, utxo: Utxo) -> UTxO: datum = RawCBOR(bytes.fromhex(utxo.datum)) if set(utxo.value.keys()) == {"ada"}: tx_out = TransactionOutput( - Address.from_primitive(utxo.address), + pyc_Address.from_primitive(utxo.address), amount=lovelace_amount, datum_hash=datum_hash, datum=datum, @@ -285,7 +285,7 @@ def _utxo_from_ogmios_result(self, utxo: Utxo) -> UTxO: multi_assets.setdefault(policy, Asset())[token_name] = quantity tx_out = TransactionOutput( - Address.from_primitive(utxo.address), + pyc_Address.from_primitive(utxo.address), amount=Value(lovelace_amount, multi_assets), datum_hash=datum_hash, datum=datum, @@ -345,22 +345,24 @@ def _parse_cost_models(self, plutus_cost_models): def KupoOgmiosV6ChainContext( - ws_url: str, - network: Network, - compact_result=True, + host: str, + port: int, + secure: bool, refetch_chain_tip_interval: Optional[float] = None, utxo_cache_size: int = 10000, datum_cache_size: int = 10000, + network: Network = Network.TESTNET, kupo_url: Optional[str] = None, ) -> KupoChainContextExtension: return KupoChainContextExtension( OgmiosV6ChainContext( - ws_url, - network, - compact_result, + host, + port, + secure, refetch_chain_tip_interval, utxo_cache_size, datum_cache_size, + network, ), kupo_url, ) From ed52278a636595c032e9b120afc09780805310f7 Mon Sep 17 00:00:00 2001 From: Niels Date: Tue, 27 Aug 2024 23:32:52 +0200 Subject: [PATCH 08/44] Re-add 3.8/3.9 --- .github/workflows/main.yml | 2 +- pyproject.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index e854fa54..c8317c28 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -14,7 +14,7 @@ jobs: strategy: matrix: os: [ubuntu-latest, macos-latest] - python-version: ['3.10', '3.11'] + python-version: ['3.8', '3.9', '3.10', '3.11'] steps: - uses: actions/checkout@v4 diff --git a/pyproject.toml b/pyproject.toml index 7a20fadf..07e95cd0 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -21,7 +21,7 @@ repository = "https://github.com/Python-Cardano/pycardano" license = "MIT" [tool.poetry.dependencies] -python = "^3.10.0" +python = "^3.8.0" PyNaCl = "^1.5.0" cbor2 = "^5.4.3" typeguard = "^4.3.0" From b7d8b09a38e4c33fb3b0028026434ffeb6e4b8b6 Mon Sep 17 00:00:00 2001 From: Niels Date: Tue, 27 Aug 2024 23:36:30 +0200 Subject: [PATCH 09/44] Bump ogmios requirement --- poetry.lock | 152 +++++++++++++++++++++++++++++++++---------------- pyproject.toml | 4 +- 2 files changed, 106 insertions(+), 50 deletions(-) diff --git a/poetry.lock b/poetry.lock index d040910b..1e2799dc 100644 --- a/poetry.lock +++ b/poetry.lock @@ -2,13 +2,13 @@ [[package]] name = "alabaster" -version = "0.7.16" -description = "A light, configurable Sphinx theme" +version = "0.7.13" +description = "A configurable sidebar-enabled Sphinx theme" optional = false -python-versions = ">=3.9" +python-versions = ">=3.6" files = [ - {file = "alabaster-0.7.16-py3-none-any.whl", hash = "sha256:b46733c07dce03ae4e150330b975c75737fa60f0a7c591b6c8bf4928a28e2c92"}, - {file = "alabaster-0.7.16.tar.gz", hash = "sha256:75a8b99c28a5dad50dd7f8ccdd447a121ddb3892da9e53d1ca5cca3106d58d65"}, + {file = "alabaster-0.7.13-py3-none-any.whl", hash = "sha256:1ee19aca801bbabb5ba3f5f258e4422dfa86f82f3e9cefb0859b283cdd7f62a3"}, + {file = "alabaster-0.7.13.tar.gz", hash = "sha256:a27a4a084d5e690e16e01e03ad2b2e552c61a65469419b907243193de1a84ae2"}, ] [[package]] @@ -22,6 +22,9 @@ files = [ {file = "annotated_types-0.7.0.tar.gz", hash = "sha256:aff07c09a53a08bc8cfccb9c85b05f1aa9a2a6f23728d790723543408344ce89"}, ] +[package.dependencies] +typing-extensions = {version = ">=4.0.0", markers = "python_version < \"3.9\""} + [[package]] name = "asn1crypto" version = "1.5.1" @@ -63,6 +66,9 @@ files = [ {file = "babel-2.16.0.tar.gz", hash = "sha256:d1f3554ca26605fe173f3de0c65f750f5a42f924499bf134de6423582298e316"}, ] +[package.dependencies] +pytz = {version = ">=2015.7", markers = "python_version < \"3.9\""} + [package.extras] dev = ["freezegun (>=1.0,<2.0)", "pytest (>=6.0)", "pytest-cov"] @@ -745,6 +751,7 @@ files = [ [package.dependencies] blinker = ">=1.6.2" click = ">=8.1.3" +importlib-metadata = {version = ">=3.6.0", markers = "python_version < \"3.10\""} itsdangerous = ">=2.1.2" Jinja2 = ">=3.1.2" Werkzeug = ">=2.3.7" @@ -917,6 +924,25 @@ files = [ {file = "imagesize-1.4.1.tar.gz", hash = "sha256:69150444affb9cb0d5cc5a92b3676f0b2fb7cd9ae39e947a5e11a36b4497cd4a"}, ] +[[package]] +name = "importlib-metadata" +version = "8.4.0" +description = "Read metadata from Python packages" +optional = false +python-versions = ">=3.8" +files = [ + {file = "importlib_metadata-8.4.0-py3-none-any.whl", hash = "sha256:66f342cc6ac9818fc6ff340576acd24d65ba0b3efabb2b4ac08b598965a4a2f1"}, + {file = "importlib_metadata-8.4.0.tar.gz", hash = "sha256:9a547d3bc3608b025f93d403fdd1aae741c24fbb8314df4b155675742ce303c5"}, +] + +[package.dependencies] +zipp = ">=0.5" + +[package.extras] +doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"] +perf = ["ipython"] +test = ["flufl.flake8", "importlib-resources (>=1.3)", "jaraco.test (>=5.4)", "packaging", "pyfakefs", "pytest (>=6,!=8.1.*)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-mypy", "pytest-perf (>=0.9.2)", "pytest-ruff (>=0.2.1)"] + [[package]] name = "iniconfig" version = "2.0.0" @@ -1123,24 +1149,27 @@ name = "ogmios" version = "1.1.1" description = "Ogmios is a lightweight bridge interface for cardano-node. It offers a WebSockets API that enables local clients to speak Ouroboros' mini-protocols via JSON/RPC. ogmios-python is an Ogmios client written in Python designed for ease of use." optional = false -python-versions = ">=3.10" -files = [ - {file = "ogmios-1.1.1-py3-none-any.whl", hash = "sha256:ff289416452ff78e39c772824c88e90a762f9d16fd893e42a52b22cf533cf344"}, - {file = "ogmios-1.1.1.tar.gz", hash = "sha256:b24884c2ce497cf72394c03aecb94eec27f14f79b305e5b0816544703fba0c60"}, -] +python-versions = ">=3.8" +files = [] +develop = false [package.dependencies] cachetools = "*" cardano-tools = "*" coloredlogs = "*" orjson = "*" -pycardano = "*" pydantic = ">=2.0" websockets = "*" [package.extras] dev = ["black", "datamodel-code-generator", "flake8-pyproject", "isort", "sphinx", "sphinx-rtd-theme"] -testing = ["coverage[toml] (>=6.5)", "pytest"] +testing = ["coverage[toml] (>=6.5)", "pycardano", "pytest"] + +[package.source] +type = "git" +url = "https://gitlab.com/viperscience/ogmios-python.git" +reference = "HEAD" +resolved_reference = "10cf42274944d6e5d9f17032f77cafd2df5b85ea" [[package]] name = "orjson" @@ -1589,6 +1618,17 @@ psutil = ["psutil (>=3.0)"] setproctitle = ["setproctitle"] testing = ["filelock"] +[[package]] +name = "pytz" +version = "2024.1" +description = "World timezone definitions, modern and historical" +optional = false +python-versions = "*" +files = [ + {file = "pytz-2024.1-py2.py3-none-any.whl", hash = "sha256:328171f4e3623139da4983451950b28e95ac706e13f3f2630a879749e7a8b319"}, + {file = "pytz-2024.1.tar.gz", hash = "sha256:2a29735ea9c18baf14b448846bde5a48030ed267578472d8955cd0e7443a9812"}, +] + [[package]] name = "pywin32" version = "306" @@ -1703,6 +1743,7 @@ babel = ">=2.9" colorama = {version = ">=0.4.5", markers = "sys_platform == \"win32\""} docutils = ">=0.14,<0.20" imagesize = ">=1.3" +importlib-metadata = {version = ">=4.8", markers = "python_version < \"3.10\""} Jinja2 = ">=3.0" packaging = ">=21.0" Pygments = ">=2.12" @@ -1759,50 +1800,47 @@ dev = ["bump2version", "sphinxcontrib-httpdomain", "transifex-client", "wheel"] [[package]] name = "sphinxcontrib-applehelp" -version = "2.0.0" +version = "1.0.4" description = "sphinxcontrib-applehelp is a Sphinx extension which outputs Apple help books" optional = false -python-versions = ">=3.9" +python-versions = ">=3.8" files = [ - {file = "sphinxcontrib_applehelp-2.0.0-py3-none-any.whl", hash = "sha256:4cd3f0ec4ac5dd9c17ec65e9ab272c9b867ea77425228e68ecf08d6b28ddbdb5"}, - {file = "sphinxcontrib_applehelp-2.0.0.tar.gz", hash = "sha256:2f29ef331735ce958efa4734873f084941970894c6090408b079c61b2e1c06d1"}, + {file = "sphinxcontrib-applehelp-1.0.4.tar.gz", hash = "sha256:828f867945bbe39817c210a1abfd1bc4895c8b73fcaade56d45357a348a07d7e"}, + {file = "sphinxcontrib_applehelp-1.0.4-py3-none-any.whl", hash = "sha256:29d341f67fb0f6f586b23ad80e072c8e6ad0b48417db2bde114a4c9746feb228"}, ] [package.extras] -lint = ["mypy", "ruff (==0.5.5)", "types-docutils"] -standalone = ["Sphinx (>=5)"] +lint = ["docutils-stubs", "flake8", "mypy"] test = ["pytest"] [[package]] name = "sphinxcontrib-devhelp" -version = "2.0.0" -description = "sphinxcontrib-devhelp is a sphinx extension which outputs Devhelp documents" +version = "1.0.2" +description = "sphinxcontrib-devhelp is a sphinx extension which outputs Devhelp document." optional = false -python-versions = ">=3.9" +python-versions = ">=3.5" files = [ - {file = "sphinxcontrib_devhelp-2.0.0-py3-none-any.whl", hash = "sha256:aefb8b83854e4b0998877524d1029fd3e6879210422ee3780459e28a1f03a8a2"}, - {file = "sphinxcontrib_devhelp-2.0.0.tar.gz", hash = "sha256:411f5d96d445d1d73bb5d52133377b4248ec79db5c793ce7dbe59e074b4dd1ad"}, + {file = "sphinxcontrib-devhelp-1.0.2.tar.gz", hash = "sha256:ff7f1afa7b9642e7060379360a67e9c41e8f3121f2ce9164266f61b9f4b338e4"}, + {file = "sphinxcontrib_devhelp-1.0.2-py2.py3-none-any.whl", hash = "sha256:8165223f9a335cc1af7ffe1ed31d2871f325254c0423bc0c4c7cd1c1e4734a2e"}, ] [package.extras] -lint = ["mypy", "ruff (==0.5.5)", "types-docutils"] -standalone = ["Sphinx (>=5)"] +lint = ["docutils-stubs", "flake8", "mypy"] test = ["pytest"] [[package]] name = "sphinxcontrib-htmlhelp" -version = "2.1.0" +version = "2.0.1" description = "sphinxcontrib-htmlhelp is a sphinx extension which renders HTML help files" optional = false -python-versions = ">=3.9" +python-versions = ">=3.8" files = [ - {file = "sphinxcontrib_htmlhelp-2.1.0-py3-none-any.whl", hash = "sha256:166759820b47002d22914d64a075ce08f4c46818e17cfc9470a9786b759b19f8"}, - {file = "sphinxcontrib_htmlhelp-2.1.0.tar.gz", hash = "sha256:c9e2916ace8aad64cc13a0d233ee22317f2b9025b9cf3295249fa985cc7082e9"}, + {file = "sphinxcontrib-htmlhelp-2.0.1.tar.gz", hash = "sha256:0cbdd302815330058422b98a113195c9249825d681e18f11e8b1f78a2f11efff"}, + {file = "sphinxcontrib_htmlhelp-2.0.1-py3-none-any.whl", hash = "sha256:c38cb46dccf316c79de6e5515e1770414b797162b23cd3d06e67020e1d2a6903"}, ] [package.extras] -lint = ["mypy", "ruff (==0.5.5)", "types-docutils"] -standalone = ["Sphinx (>=5)"] +lint = ["docutils-stubs", "flake8", "mypy"] test = ["html5lib", "pytest"] [[package]] @@ -1835,34 +1873,32 @@ test = ["flake8", "mypy", "pytest"] [[package]] name = "sphinxcontrib-qthelp" -version = "2.0.0" -description = "sphinxcontrib-qthelp is a sphinx extension which outputs QtHelp documents" +version = "1.0.3" +description = "sphinxcontrib-qthelp is a sphinx extension which outputs QtHelp document." optional = false -python-versions = ">=3.9" +python-versions = ">=3.5" files = [ - {file = "sphinxcontrib_qthelp-2.0.0-py3-none-any.whl", hash = "sha256:b18a828cdba941ccd6ee8445dbe72ffa3ef8cbe7505d8cd1fa0d42d3f2d5f3eb"}, - {file = "sphinxcontrib_qthelp-2.0.0.tar.gz", hash = "sha256:4fe7d0ac8fc171045be623aba3e2a8f613f8682731f9153bb2e40ece16b9bbab"}, + {file = "sphinxcontrib-qthelp-1.0.3.tar.gz", hash = "sha256:4c33767ee058b70dba89a6fc5c1892c0d57a54be67ddd3e7875a18d14cba5a72"}, + {file = "sphinxcontrib_qthelp-1.0.3-py2.py3-none-any.whl", hash = "sha256:bd9fc24bcb748a8d51fd4ecaade681350aa63009a347a8c14e637895444dfab6"}, ] [package.extras] -lint = ["mypy", "ruff (==0.5.5)", "types-docutils"] -standalone = ["Sphinx (>=5)"] -test = ["defusedxml (>=0.7.1)", "pytest"] +lint = ["docutils-stubs", "flake8", "mypy"] +test = ["pytest"] [[package]] name = "sphinxcontrib-serializinghtml" -version = "2.0.0" -description = "sphinxcontrib-serializinghtml is a sphinx extension which outputs \"serialized\" HTML files (json and pickle)" +version = "1.1.5" +description = "sphinxcontrib-serializinghtml is a sphinx extension which outputs \"serialized\" HTML files (json and pickle)." optional = false -python-versions = ">=3.9" +python-versions = ">=3.5" files = [ - {file = "sphinxcontrib_serializinghtml-2.0.0-py3-none-any.whl", hash = "sha256:6e2cb0eef194e10c27ec0023bfeb25badbbb5868244cf5bc5bdc04e4464bf331"}, - {file = "sphinxcontrib_serializinghtml-2.0.0.tar.gz", hash = "sha256:e9d912827f872c029017a53f0ef2180b327c3f7fd23c87229f7a8e8b70031d4d"}, + {file = "sphinxcontrib-serializinghtml-1.1.5.tar.gz", hash = "sha256:aa5f6de5dfdf809ef505c4895e51ef5c9eac17d0f287933eb49ec495280b6952"}, + {file = "sphinxcontrib_serializinghtml-1.1.5-py2.py3-none-any.whl", hash = "sha256:352a9a00ae864471d3a7ead8d7d79f5fc0b57e8b3f95e9867eb9eb28999b92fd"}, ] [package.extras] -lint = ["mypy", "ruff (==0.5.5)", "types-docutils"] -standalone = ["Sphinx (>=5)"] +lint = ["docutils-stubs", "flake8", "mypy"] test = ["pytest"] [[package]] @@ -1888,6 +1924,7 @@ files = [ ] [package.dependencies] +importlib-metadata = {version = ">=3.6", markers = "python_version < \"3.10\""} typing-extensions = ">=4.10.0" [package.extras] @@ -2064,7 +2101,26 @@ MarkupSafe = ">=2.1.1" [package.extras] watchdog = ["watchdog (>=2.3)"] +[[package]] +name = "zipp" +version = "3.20.1" +description = "Backport of pathlib-compatible object wrapper for zip files" +optional = false +python-versions = ">=3.8" +files = [ + {file = "zipp-3.20.1-py3-none-any.whl", hash = "sha256:9960cd8967c8f85a56f920d5d507274e74f9ff813a0ab8889a5b5be2daf44064"}, + {file = "zipp-3.20.1.tar.gz", hash = "sha256:c22b14cc4763c5a5b04134207736c107db42e9d3ef2d9779d465f5f1bcba572b"}, +] + +[package.extras] +check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1)"] +cover = ["pytest-cov"] +doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"] +enabler = ["pytest-enabler (>=2.2)"] +test = ["big-O", "importlib-resources", "jaraco.functools", "jaraco.itertools", "jaraco.test", "more-itertools", "pytest (>=6,!=8.1.*)", "pytest-ignore-flaky"] +type = ["pytest-mypy"] + [metadata] lock-version = "2.0" -python-versions = "^3.10.0" -content-hash = "6bae0a8686c4f2c807706e7f3676e57bb58675e48a325f9a883ad5cbe647a908" +python-versions = "^3.8.1" +content-hash = "3aae893b86526d474abf058543d34cced34f174e7dd0682efafba13dddcec59a" diff --git a/pyproject.toml b/pyproject.toml index 07e95cd0..bdb965a8 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -21,7 +21,7 @@ repository = "https://github.com/Python-Cardano/pycardano" license = "MIT" [tool.poetry.dependencies] -python = "^3.8.0" +python = "^3.8.1" PyNaCl = "^1.5.0" cbor2 = "^5.4.3" typeguard = "^4.3.0" @@ -35,7 +35,7 @@ frozendict = "^2.3.8" frozenlist = "^1.3.3" cachetools = "^5.3.0" docker = "^7.1.0" -ogmios = "^1.1.1" +ogmios = {git = "https://gitlab.com/viperscience/ogmios-python.git"} requests = "^2.32.3" websockets = "^13.0" From 3a3df8c7b378bb1d286ca58209fa2c7c1fd3ed93 Mon Sep 17 00:00:00 2001 From: Niels Date: Tue, 27 Aug 2024 23:43:20 +0200 Subject: [PATCH 10/44] Fix mypy errors --- pycardano/backend/ogmios_v6.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pycardano/backend/ogmios_v6.py b/pycardano/backend/ogmios_v6.py index d5eb0638..0e07680e 100644 --- a/pycardano/backend/ogmios_v6.py +++ b/pycardano/backend/ogmios_v6.py @@ -150,11 +150,11 @@ def _fetch_protocol_param(self) -> ProtocolParameters: pool_influence=eval(protocol_parameters.stake_pool_pledge_influence), monetary_expansion=eval(protocol_parameters.monetary_expansion), treasury_expansion=eval(protocol_parameters.treasury_expansion), - decentralization_param=None, # TODO + decentralization_param=None, # type: ignore[arg-type] extra_entropy=protocol_parameters.extra_entropy, protocol_major_version=protocol_parameters.version.get("major"), protocol_minor_version=protocol_parameters.version.get("minor"), - min_utxo=None, + min_utxo=None, # type: ignore[arg-type] price_mem=eval( protocol_parameters.script_execution_prices.get("memory") ), From 6e8f7954920687cd9089281f20d2f055b0a56131 Mon Sep 17 00:00:00 2001 From: Jerry Date: Thu, 29 Aug 2024 16:07:12 -0700 Subject: [PATCH 11/44] Fix python ogmios --- pycardano/backend/ogmios_v6.py | 2 ++ pyproject.toml | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/pycardano/backend/ogmios_v6.py b/pycardano/backend/ogmios_v6.py index 9884fb5b..87d5501c 100644 --- a/pycardano/backend/ogmios_v6.py +++ b/pycardano/backend/ogmios_v6.py @@ -180,6 +180,8 @@ def _fetch_protocol_param(self) -> ProtocolParameters: cost_models=self._parse_cost_models( protocol_parameters.plutus_cost_models ), + maximum_reference_scripts_size=protocol_parameters.max_ref_script_size, + min_fee_reference_scripts=protocol_parameters.min_fee_ref_scripts, ) return pyc_protocol_params diff --git a/pyproject.toml b/pyproject.toml index 93967152..4e81b5e3 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -35,7 +35,7 @@ frozendict = "^2.3.8" frozenlist = "^1.3.3" cachetools = "^5.3.0" docker = "^7.1.0" -ogmios = {git = "https://gitlab.com/viperscience/ogmios-python.git"} +ogmios = {git = "https://gitlab.com/cffls/ogmios-python.git"} requests = "^2.32.3" websockets = "^13.0" From 19e617785033b0ab5f1ac41a69cdd4ff1cea5a4d Mon Sep 17 00:00:00 2001 From: Jerry Date: Thu, 29 Aug 2024 20:28:50 -0700 Subject: [PATCH 12/44] Bump default major version to 9 --- .../configs/local-chang/conway-genesis.json | 6 + .../configs/local-chang/shelley-genesis.json | 2 +- integration-test/test/test_plutus.py | 6 +- poetry.lock | 184 +++++++++--------- pycardano/transaction.py | 4 +- pycardano/txbuilder.py | 43 ++-- pyproject.toml | 2 +- 7 files changed, 132 insertions(+), 115 deletions(-) diff --git a/integration-test/configs/local-chang/conway-genesis.json b/integration-test/configs/local-chang/conway-genesis.json index 61598cba..2de0f672 100644 --- a/integration-test/configs/local-chang/conway-genesis.json +++ b/integration-test/configs/local-chang/conway-genesis.json @@ -1,4 +1,10 @@ { + "protocolParams": { + "protocolVersion": { + "minor": 0, + "major": 9 + } + }, "poolVotingThresholds": { "committeeNormal": 0.65, "committeeNoConfidence": 0.65, diff --git a/integration-test/configs/local-chang/shelley-genesis.json b/integration-test/configs/local-chang/shelley-genesis.json index 63aa1093..f3afd4c7 100644 --- a/integration-test/configs/local-chang/shelley-genesis.json +++ b/integration-test/configs/local-chang/shelley-genesis.json @@ -21,7 +21,7 @@ "keyDeposit": 1000000, "protocolVersion": { "minor": 0, - "major": 7 + "major": 9 }, "poolDeposit": 1000000, "a0": 0.0, diff --git a/integration-test/test/test_plutus.py b/integration-test/test/test_plutus.py index 62abf8f4..3144d4da 100644 --- a/integration-test/test/test_plutus.py +++ b/integration-test/test/test_plutus.py @@ -389,10 +389,12 @@ def test_plutus_v3(self): with open("./plutus_scripts/helloworldV3.plutus", "r") as f: script_hex = f.read() - hello_world_script = cbor2.loads(bytes.fromhex(script_hex)) + hello_world_script = bytes.fromhex(script_hex) script_hash = plutus_script_hash(PlutusV3Script(hello_world_script)) + print("script_hash: ", script_hash) + script_address = Address(script_hash, network=self.NETWORK) giver_address = Address(self.payment_vkey.hash(), network=self.NETWORK) @@ -417,7 +419,7 @@ def test_plutus_v3(self): utxo_to_spend = self.chain_context.utxos(script_address)[0] - taker_address = Address(self.extended_payment_vkey.hash(), network=self.NETWORK) + taker_address = Address(self.payment_vkey.hash(), network=self.NETWORK) builder = TransactionBuilder(self.chain_context) diff --git a/poetry.lock b/poetry.lock index 1e2799dc..3127a37a 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1,4 +1,4 @@ -# This file is automatically @generated by Poetry 1.8.3 and should not be changed by hand. +# This file is automatically @generated by Poetry 1.8.2 and should not be changed by hand. [[package]] name = "alabaster" @@ -222,13 +222,13 @@ test = ["coverage (>=7)", "hypothesis", "pytest"] [[package]] name = "certifi" -version = "2024.7.4" +version = "2024.8.30" description = "Python package for providing Mozilla's CA Bundle." optional = false python-versions = ">=3.6" files = [ - {file = "certifi-2024.7.4-py3-none-any.whl", hash = "sha256:c198e21b1289c2ab85ee4e67bb4b4ef3ead0892059901a8d5b622f24a1101e90"}, - {file = "certifi-2024.7.4.tar.gz", hash = "sha256:5a1e7645bc0ec61a09e26c36f6106dd4cf40c6db3a1fb6352b0244e7fb057c7b"}, + {file = "certifi-2024.8.30-py3-none-any.whl", hash = "sha256:922820b53db7a7257ffbda3f597266d435245903d80737e34f8a45ff3e3230d8"}, + {file = "certifi-2024.8.30.tar.gz", hash = "sha256:bec941d2aa8195e248a60b31ff9f0558284cf01a52591ceda73ea9afffd69fd9"}, ] [[package]] @@ -1169,7 +1169,7 @@ testing = ["coverage[toml] (>=6.5)", "pycardano", "pytest"] type = "git" url = "https://gitlab.com/viperscience/ogmios-python.git" reference = "HEAD" -resolved_reference = "10cf42274944d6e5d9f17032f77cafd2df5b85ea" +resolved_reference = "0b713e78839341d92828340a5552ef8dd1c6224b" [[package]] name = "orjson" @@ -1991,97 +1991,97 @@ test = ["websockets"] [[package]] name = "websockets" -version = "13.0" +version = "13.0.1" description = "An implementation of the WebSocket Protocol (RFC 6455 & 7692)" optional = false python-versions = ">=3.8" files = [ - {file = "websockets-13.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:ad4fa707ff9e2ffee019e946257b5300a45137a58f41fbd9a4db8e684ab61528"}, - {file = "websockets-13.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:6fd757f313c13c34dae9f126d3ba4cf97175859c719e57c6a614b781c86b617e"}, - {file = "websockets-13.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:cbac2eb7ce0fac755fb983c9247c4a60c4019bcde4c0e4d167aeb17520cc7ef1"}, - {file = "websockets-13.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d4b83cf7354cbbc058e97b3e545dceb75b8d9cf17fd5a19db419c319ddbaaf7a"}, - {file = "websockets-13.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9202c0010c78fad1041e1c5285232b6508d3633f92825687549540a70e9e5901"}, - {file = "websockets-13.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3e6566e79c8c7cbea75ec450f6e1828945fc5c9a4769ceb1c7b6e22470539712"}, - {file = "websockets-13.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:e7fcad070dcd9ad37a09d89a4cbc2a5e3e45080b88977c0da87b3090f9f55ead"}, - {file = "websockets-13.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:0a8f7d65358a25172db00c69bcc7df834155ee24229f560d035758fd6613111a"}, - {file = "websockets-13.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:63b702fb31e3f058f946ccdfa551f4d57a06f7729c369e8815eb18643099db37"}, - {file = "websockets-13.0-cp310-cp310-win32.whl", hash = "sha256:3a20cf14ba7b482c4a1924b5e061729afb89c890ca9ed44ac4127c6c5986e424"}, - {file = "websockets-13.0-cp310-cp310-win_amd64.whl", hash = "sha256:587245f0704d0bb675f919898d7473e8827a6d578e5a122a21756ca44b811ec8"}, - {file = "websockets-13.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:06df8306c241c235075d2ae77367038e701e53bc8c1bb4f6644f4f53aa6dedd0"}, - {file = "websockets-13.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:85a1f92a02f0b8c1bf02699731a70a8a74402bb3f82bee36e7768b19a8ed9709"}, - {file = "websockets-13.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:9ed02c604349068d46d87ef4c2012c112c791f2bec08671903a6bb2bd9c06784"}, - {file = "websockets-13.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b89849171b590107f6724a7b0790736daead40926ddf47eadf998b4ff51d6414"}, - {file = "websockets-13.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:939a16849d71203628157a5e4a495da63967c744e1e32018e9b9e2689aca64d4"}, - {file = "websockets-13.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ad818cdac37c0ad4c58e51cb4964eae4f18b43c4a83cb37170b0d90c31bd80cf"}, - {file = "websockets-13.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:cbfe82a07596a044de78bb7a62519e71690c5812c26c5f1d4b877e64e4f46309"}, - {file = "websockets-13.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:e07e76c49f39c5b45cbd7362b94f001ae209a3ea4905ae9a09cfd53b3c76373d"}, - {file = "websockets-13.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:372f46a0096cfda23c88f7e42349a33f8375e10912f712e6b496d3a9a557290f"}, - {file = "websockets-13.0-cp311-cp311-win32.whl", hash = "sha256:376a43a4fd96725f13450d3d2e98f4f36c3525c562ab53d9a98dd2950dca9a8a"}, - {file = "websockets-13.0-cp311-cp311-win_amd64.whl", hash = "sha256:2be1382a4daa61e2f3e2be3b3c86932a8db9d1f85297feb6e9df22f391f94452"}, - {file = "websockets-13.0-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:b5407c34776b9b77bd89a5f95eb0a34aaf91889e3f911c63f13035220eb50107"}, - {file = "websockets-13.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:4782ec789f059f888c1e8fdf94383d0e64b531cffebbf26dd55afd53ab487ca4"}, - {file = "websockets-13.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:c8feb8e19ef65c9994e652c5b0324abd657bedd0abeb946fb4f5163012c1e730"}, - {file = "websockets-13.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d3f3d2e20c442b58dbac593cb1e02bc02d149a86056cc4126d977ad902472e3b"}, - {file = "websockets-13.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e39d393e0ab5b8bd01717cc26f2922026050188947ff54fe6a49dc489f7750b7"}, - {file = "websockets-13.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1f661a4205741bdc88ac9c2b2ec003c72cee97e4acd156eb733662ff004ba429"}, - {file = "websockets-13.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:384129ad0490e06bab2b98c1da9b488acb35bb11e2464c728376c6f55f0d45f3"}, - {file = "websockets-13.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:df5c0eff91f61b8205a6c9f7b255ff390cdb77b61c7b41f79ca10afcbb22b6cb"}, - {file = "websockets-13.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:02cc9bb1a887dac0e08bf657c5d00aa3fac0d03215d35a599130c2034ae6663a"}, - {file = "websockets-13.0-cp312-cp312-win32.whl", hash = "sha256:d9726d2c9bd6aed8cb994d89b3910ca0079406edce3670886ec828a73e7bdd53"}, - {file = "websockets-13.0-cp312-cp312-win_amd64.whl", hash = "sha256:fa0839f35322f7b038d8adcf679e2698c3a483688cc92e3bd15ee4fb06669e9a"}, - {file = "websockets-13.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:da7e501e59857e8e3e9d10586139dc196b80445a591451ca9998aafba1af5278"}, - {file = "websockets-13.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:a00e1e587c655749afb5b135d8d3edcfe84ec6db864201e40a882e64168610b3"}, - {file = "websockets-13.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:a7fbf2a8fe7556a8f4e68cb3e736884af7bf93653e79f6219f17ebb75e97d8f0"}, - {file = "websockets-13.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7ea9c9c7443a97ea4d84d3e4d42d0e8c4235834edae652993abcd2aff94affd7"}, - {file = "websockets-13.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:35c2221b539b360203f3f9ad168e527bf16d903e385068ae842c186efb13d0ea"}, - {file = "websockets-13.0-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:358d37c5c431dd050ffb06b4b075505aae3f4f795d7fff9794e5ed96ce99b998"}, - {file = "websockets-13.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:038e7a0f1bfafc7bf52915ab3506b7a03d1e06381e9f60440c856e8918138151"}, - {file = "websockets-13.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:fd038bc9e2c134847f1e0ce3191797fad110756e690c2fdd9702ed34e7a43abb"}, - {file = "websockets-13.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:93b8c2008f372379fb6e5d2b3f7c9ec32f7b80316543fd3a5ace6610c5cde1b0"}, - {file = "websockets-13.0-cp313-cp313-win32.whl", hash = "sha256:851fd0afb3bc0b73f7c5b5858975d42769a5fdde5314f4ef2c106aec63100687"}, - {file = "websockets-13.0-cp313-cp313-win_amd64.whl", hash = "sha256:7d14901fdcf212804970c30ab9ee8f3f0212e620c7ea93079d6534863444fb4e"}, - {file = "websockets-13.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:ae7a519a56a714f64c3445cabde9fc2fc927e7eae44f413eae187cddd9e54178"}, - {file = "websockets-13.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:5575031472ca87302aeb2ce2c2349f4c6ea978c86a9d1289bc5d16058ad4c10a"}, - {file = "websockets-13.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:9895df6cd0bfe79d09bcd1dbdc03862846f26fbd93797153de954306620c1d00"}, - {file = "websockets-13.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a4de299c947a54fca9ce1c5fd4a08eb92ffce91961becb13bd9195f7c6e71b47"}, - {file = "websockets-13.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:05c25f7b849702950b6fd0e233989bb73a0d2bc83faa3b7233313ca395205f6d"}, - {file = "websockets-13.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ede95125a30602b1691a4b1da88946bf27dae283cf30f22cd2cb8ca4b2e0d119"}, - {file = "websockets-13.0-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:addf0a16e4983280efed272d8cb3b2e05f0051755372461e7d966b80a6554e16"}, - {file = "websockets-13.0-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:06b3186e97bf9a33921fa60734d5ed90f2a9b407cce8d23c7333a0984049ef61"}, - {file = "websockets-13.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:eae368cac85adc4c7dc3b0d5f84ffcca609d658db6447387300478e44db70796"}, - {file = "websockets-13.0-cp38-cp38-win32.whl", hash = "sha256:337837ac788d955728b1ab01876d72b73da59819a3388e1c5e8e05c3999f1afa"}, - {file = "websockets-13.0-cp38-cp38-win_amd64.whl", hash = "sha256:f66e00e42f25ca7e91076366303e11c82572ca87cc5aae51e6e9c094f315ab41"}, - {file = "websockets-13.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:94c1c02721139fe9940b38d28fb15b4b782981d800d5f40f9966264fbf23dcc8"}, - {file = "websockets-13.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:bd4ba86513430513e2aa25a441bb538f6f83734dc368a2c5d18afdd39097aa33"}, - {file = "websockets-13.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:a1ab8f0e0cadc5be5f3f9fa11a663957fecbf483d434762c8dfb8aa44948944a"}, - {file = "websockets-13.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3670def5d3dfd5af6f6e2b3b243ea8f1f72d8da1ef927322f0703f85c90d9603"}, - {file = "websockets-13.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6058b6be92743358885ad6dcdecb378fde4a4c74d4dd16a089d07580c75a0e80"}, - {file = "websockets-13.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:516062a0a8ef5ecbfa4acbaec14b199fc070577834f9fe3d40800a99f92523ca"}, - {file = "websockets-13.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:da7e918d82e7bdfc6f66d31febe1b2e28a1ca3387315f918de26f5e367f61572"}, - {file = "websockets-13.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:9cc7f35dcb49a4e32db82a849fcc0714c4d4acc9d2273aded2d61f87d7f660b7"}, - {file = "websockets-13.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:f5737c53eb2c8ed8f64b50d3dafd3c1dae739f78aa495a288421ac1b3de82717"}, - {file = "websockets-13.0-cp39-cp39-win32.whl", hash = "sha256:265e1f0d3f788ce8ef99dca591a1aec5263b26083ca0934467ad9a1d1181067c"}, - {file = "websockets-13.0-cp39-cp39-win_amd64.whl", hash = "sha256:4d70c89e3d3b347a7c4d3c33f8d323f0584c9ceb69b82c2ef8a174ca84ea3d4a"}, - {file = "websockets-13.0-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:602cbd010d8c21c8475f1798b705bb18567eb189c533ab5ef568bc3033fdf417"}, - {file = "websockets-13.0-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:bf8eb5dca4f484a60f5327b044e842e0d7f7cdbf02ea6dc4a4f811259f1f1f0b"}, - {file = "websockets-13.0-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:89d795c1802d99a643bf689b277e8604c14b5af1bc0a31dade2cd7a678087212"}, - {file = "websockets-13.0-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:788bc841d250beccff67a20a5a53a15657a60111ef9c0c0a97fbdd614fae0fe2"}, - {file = "websockets-13.0-pp310-pypy310_pp73-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7334752052532c156d28b8eaf3558137e115c7871ea82adff69b6d94a7bee273"}, - {file = "websockets-13.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:e7a1963302947332c3039e3f66209ec73b1626f8a0191649e0713c391e9f5b0d"}, - {file = "websockets-13.0-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:2e1cf4e1eb84b4fd74a47688e8b0940c89a04ad9f6937afa43d468e71128cd68"}, - {file = "websockets-13.0-pp38-pypy38_pp73-macosx_11_0_arm64.whl", hash = "sha256:c026ee729c4ce55708a14b839ba35086dfae265fc12813b62d34ce33f4980c1c"}, - {file = "websockets-13.0-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f5f9d23fbbf96eefde836d9692670bfc89e2d159f456d499c5efcf6a6281c1af"}, - {file = "websockets-13.0-pp38-pypy38_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6ad684cb7efce227d756bae3e8484f2e56aa128398753b54245efdfbd1108f2c"}, - {file = "websockets-13.0-pp38-pypy38_pp73-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e1e10b3fbed7be4a59831d3a939900e50fcd34d93716e433d4193a4d0d1d335d"}, - {file = "websockets-13.0-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:d42a818e634f789350cd8fb413a3f5eec1cf0400a53d02062534c41519f5125c"}, - {file = "websockets-13.0-pp39-pypy39_pp73-macosx_10_15_x86_64.whl", hash = "sha256:e5ba5e9b332267d0f2c33ede390061850f1ac3ee6cd1bdcf4c5ea33ead971966"}, - {file = "websockets-13.0-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:f9af457ed593e35f467140d8b61d425495b127744a9d65d45a366f8678449a23"}, - {file = "websockets-13.0-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bcea3eb58c09c3a31cc83b45c06d5907f02ddaf10920aaa6443975310f699b95"}, - {file = "websockets-13.0-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c210d1460dc8d326ffdef9703c2f83269b7539a1690ad11ae04162bc1878d33d"}, - {file = "websockets-13.0-pp39-pypy39_pp73-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b32f38bc81170fd56d0482d505b556e52bf9078b36819a8ba52624bd6667e39e"}, - {file = "websockets-13.0-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:81a11a1ddd5320429db47c04d35119c3e674d215173d87aaeb06ae80f6e9031f"}, - {file = "websockets-13.0-py3-none-any.whl", hash = "sha256:dbbac01e80aee253d44c4f098ab3cc17c822518519e869b284cfbb8cd16cc9de"}, - {file = "websockets-13.0.tar.gz", hash = "sha256:b7bf950234a482b7461afdb2ec99eee3548ec4d53f418c7990bb79c620476602"}, + {file = "websockets-13.0.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:1841c9082a3ba4a05ea824cf6d99570a6a2d8849ef0db16e9c826acb28089e8f"}, + {file = "websockets-13.0.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:c5870b4a11b77e4caa3937142b650fbbc0914a3e07a0cf3131f35c0587489c1c"}, + {file = "websockets-13.0.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:f1d3d1f2eb79fe7b0fb02e599b2bf76a7619c79300fc55f0b5e2d382881d4f7f"}, + {file = "websockets-13.0.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:15c7d62ee071fa94a2fc52c2b472fed4af258d43f9030479d9c4a2de885fd543"}, + {file = "websockets-13.0.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6724b554b70d6195ba19650fef5759ef11346f946c07dbbe390e039bcaa7cc3d"}, + {file = "websockets-13.0.1-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:56a952fa2ae57a42ba7951e6b2605e08a24801a4931b5644dfc68939e041bc7f"}, + {file = "websockets-13.0.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:17118647c0ea14796364299e942c330d72acc4b248e07e639d34b75067b3cdd8"}, + {file = "websockets-13.0.1-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:64a11aae1de4c178fa653b07d90f2fb1a2ed31919a5ea2361a38760192e1858b"}, + {file = "websockets-13.0.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:0617fd0b1d14309c7eab6ba5deae8a7179959861846cbc5cb528a7531c249448"}, + {file = "websockets-13.0.1-cp310-cp310-win32.whl", hash = "sha256:11f9976ecbc530248cf162e359a92f37b7b282de88d1d194f2167b5e7ad80ce3"}, + {file = "websockets-13.0.1-cp310-cp310-win_amd64.whl", hash = "sha256:c3c493d0e5141ec055a7d6809a28ac2b88d5b878bb22df8c621ebe79a61123d0"}, + {file = "websockets-13.0.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:699ba9dd6a926f82a277063603fc8d586b89f4cb128efc353b749b641fcddda7"}, + {file = "websockets-13.0.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:cf2fae6d85e5dc384bf846f8243ddaa9197f3a1a70044f59399af001fd1f51d4"}, + {file = "websockets-13.0.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:52aed6ef21a0f1a2a5e310fb5c42d7555e9c5855476bbd7173c3aa3d8a0302f2"}, + {file = "websockets-13.0.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8eb2b9a318542153674c6e377eb8cb9ca0fc011c04475110d3477862f15d29f0"}, + {file = "websockets-13.0.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5df891c86fe68b2c38da55b7aea7095beca105933c697d719f3f45f4220a5e0e"}, + {file = "websockets-13.0.1-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fac2d146ff30d9dd2fcf917e5d147db037a5c573f0446c564f16f1f94cf87462"}, + {file = "websockets-13.0.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:b8ac5b46fd798bbbf2ac6620e0437c36a202b08e1f827832c4bf050da081b501"}, + {file = "websockets-13.0.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:46af561eba6f9b0848b2c9d2427086cabadf14e0abdd9fde9d72d447df268418"}, + {file = "websockets-13.0.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:b5a06d7f60bc2fc378a333978470dfc4e1415ee52f5f0fce4f7853eb10c1e9df"}, + {file = "websockets-13.0.1-cp311-cp311-win32.whl", hash = "sha256:556e70e4f69be1082e6ef26dcb70efcd08d1850f5d6c5f4f2bcb4e397e68f01f"}, + {file = "websockets-13.0.1-cp311-cp311-win_amd64.whl", hash = "sha256:67494e95d6565bf395476e9d040037ff69c8b3fa356a886b21d8422ad86ae075"}, + {file = "websockets-13.0.1-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:f9c9e258e3d5efe199ec23903f5da0eeaad58cf6fccb3547b74fd4750e5ac47a"}, + {file = "websockets-13.0.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:6b41a1b3b561f1cba8321fb32987552a024a8f67f0d05f06fcf29f0090a1b956"}, + {file = "websockets-13.0.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:f73e676a46b0fe9426612ce8caeca54c9073191a77c3e9d5c94697aef99296af"}, + {file = "websockets-13.0.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1f613289f4a94142f914aafad6c6c87903de78eae1e140fa769a7385fb232fdf"}, + {file = "websockets-13.0.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0f52504023b1480d458adf496dc1c9e9811df4ba4752f0bc1f89ae92f4f07d0c"}, + {file = "websockets-13.0.1-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:139add0f98206cb74109faf3611b7783ceafc928529c62b389917a037d4cfdf4"}, + {file = "websockets-13.0.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:47236c13be337ef36546004ce8c5580f4b1150d9538b27bf8a5ad8edf23ccfab"}, + {file = "websockets-13.0.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:c44ca9ade59b2e376612df34e837013e2b273e6c92d7ed6636d0556b6f4db93d"}, + {file = "websockets-13.0.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:9bbc525f4be3e51b89b2a700f5746c2a6907d2e2ef4513a8daafc98198b92237"}, + {file = "websockets-13.0.1-cp312-cp312-win32.whl", hash = "sha256:3624fd8664f2577cf8de996db3250662e259bfbc870dd8ebdcf5d7c6ac0b5185"}, + {file = "websockets-13.0.1-cp312-cp312-win_amd64.whl", hash = "sha256:0513c727fb8adffa6d9bf4a4463b2bade0186cbd8c3604ae5540fae18a90cb99"}, + {file = "websockets-13.0.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:1ee4cc030a4bdab482a37462dbf3ffb7e09334d01dd37d1063be1136a0d825fa"}, + {file = "websockets-13.0.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:dbb0b697cc0655719522406c059eae233abaa3243821cfdfab1215d02ac10231"}, + {file = "websockets-13.0.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:acbebec8cb3d4df6e2488fbf34702cbc37fc39ac7abf9449392cefb3305562e9"}, + {file = "websockets-13.0.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:63848cdb6fcc0bf09d4a155464c46c64ffdb5807ede4fb251da2c2692559ce75"}, + {file = "websockets-13.0.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:872afa52a9f4c414d6955c365b6588bc4401272c629ff8321a55f44e3f62b553"}, + {file = "websockets-13.0.1-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:05e70fec7c54aad4d71eae8e8cab50525e899791fc389ec6f77b95312e4e9920"}, + {file = "websockets-13.0.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:e82db3756ccb66266504f5a3de05ac6b32f287faacff72462612120074103329"}, + {file = "websockets-13.0.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:4e85f46ce287f5c52438bb3703d86162263afccf034a5ef13dbe4318e98d86e7"}, + {file = "websockets-13.0.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:f3fea72e4e6edb983908f0db373ae0732b275628901d909c382aae3b592589f2"}, + {file = "websockets-13.0.1-cp313-cp313-win32.whl", hash = "sha256:254ecf35572fca01a9f789a1d0f543898e222f7b69ecd7d5381d8d8047627bdb"}, + {file = "websockets-13.0.1-cp313-cp313-win_amd64.whl", hash = "sha256:ca48914cdd9f2ccd94deab5bcb5ac98025a5ddce98881e5cce762854a5de330b"}, + {file = "websockets-13.0.1-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:b74593e9acf18ea5469c3edaa6b27fa7ecf97b30e9dabd5a94c4c940637ab96e"}, + {file = "websockets-13.0.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:132511bfd42e77d152c919147078460c88a795af16b50e42a0bd14f0ad71ddd2"}, + {file = "websockets-13.0.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:165bedf13556f985a2aa064309baa01462aa79bf6112fbd068ae38993a0e1f1b"}, + {file = "websockets-13.0.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e801ca2f448850685417d723ec70298feff3ce4ff687c6f20922c7474b4746ae"}, + {file = "websockets-13.0.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:30d3a1f041360f029765d8704eae606781e673e8918e6b2c792e0775de51352f"}, + {file = "websockets-13.0.1-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:67648f5e50231b5a7f6d83b32f9c525e319f0ddc841be0de64f24928cd75a603"}, + {file = "websockets-13.0.1-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:4f0426d51c8f0926a4879390f53c7f5a855e42d68df95fff6032c82c888b5f36"}, + {file = "websockets-13.0.1-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:ef48e4137e8799998a343706531e656fdec6797b80efd029117edacb74b0a10a"}, + {file = "websockets-13.0.1-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:249aab278810bee585cd0d4de2f08cfd67eed4fc75bde623be163798ed4db2eb"}, + {file = "websockets-13.0.1-cp38-cp38-win32.whl", hash = "sha256:06c0a667e466fcb56a0886d924b5f29a7f0886199102f0a0e1c60a02a3751cb4"}, + {file = "websockets-13.0.1-cp38-cp38-win_amd64.whl", hash = "sha256:1f3cf6d6ec1142412d4535adabc6bd72a63f5f148c43fe559f06298bc21953c9"}, + {file = "websockets-13.0.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:1fa082ea38d5de51dd409434edc27c0dcbd5fed2b09b9be982deb6f0508d25bc"}, + {file = "websockets-13.0.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:4a365bcb7be554e6e1f9f3ed64016e67e2fa03d7b027a33e436aecf194febb63"}, + {file = "websockets-13.0.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:10a0dc7242215d794fb1918f69c6bb235f1f627aaf19e77f05336d147fce7c37"}, + {file = "websockets-13.0.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:59197afd478545b1f73367620407b0083303569c5f2d043afe5363676f2697c9"}, + {file = "websockets-13.0.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7d20516990d8ad557b5abeb48127b8b779b0b7e6771a265fa3e91767596d7d97"}, + {file = "websockets-13.0.1-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a1a2e272d067030048e1fe41aa1ec8cfbbaabce733b3d634304fa2b19e5c897f"}, + {file = "websockets-13.0.1-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:ad327ac80ba7ee61da85383ca8822ff808ab5ada0e4a030d66703cc025b021c4"}, + {file = "websockets-13.0.1-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:518f90e6dd089d34eaade01101fd8a990921c3ba18ebbe9b0165b46ebff947f0"}, + {file = "websockets-13.0.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:68264802399aed6fe9652e89761031acc734fc4c653137a5911c2bfa995d6d6d"}, + {file = "websockets-13.0.1-cp39-cp39-win32.whl", hash = "sha256:a5dc0c42ded1557cc7c3f0240b24129aefbad88af4f09346164349391dea8e58"}, + {file = "websockets-13.0.1-cp39-cp39-win_amd64.whl", hash = "sha256:b448a0690ef43db5ef31b3a0d9aea79043882b4632cfc3eaab20105edecf6097"}, + {file = "websockets-13.0.1-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:faef9ec6354fe4f9a2c0bbb52fb1ff852effc897e2a4501e25eb3a47cb0a4f89"}, + {file = "websockets-13.0.1-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:03d3f9ba172e0a53e37fa4e636b86cc60c3ab2cfee4935e66ed1d7acaa4625ad"}, + {file = "websockets-13.0.1-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d450f5a7a35662a9b91a64aefa852f0c0308ee256122f5218a42f1d13577d71e"}, + {file = "websockets-13.0.1-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3f55b36d17ac50aa8a171b771e15fbe1561217510c8768af3d546f56c7576cdc"}, + {file = "websockets-13.0.1-pp310-pypy310_pp73-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:14b9c006cac63772b31abbcd3e3abb6228233eec966bf062e89e7fa7ae0b7333"}, + {file = "websockets-13.0.1-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:b79915a1179a91f6c5f04ece1e592e2e8a6bd245a0e45d12fd56b2b59e559a32"}, + {file = "websockets-13.0.1-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:f40de079779acbcdbb6ed4c65af9f018f8b77c5ec4e17a4b737c05c2db554491"}, + {file = "websockets-13.0.1-pp38-pypy38_pp73-macosx_11_0_arm64.whl", hash = "sha256:80e4ba642fc87fa532bac07e5ed7e19d56940b6af6a8c61d4429be48718a380f"}, + {file = "websockets-13.0.1-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2a02b0161c43cc9e0232711eff846569fad6ec836a7acab16b3cf97b2344c060"}, + {file = "websockets-13.0.1-pp38-pypy38_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6aa74a45d4cdc028561a7d6ab3272c8b3018e23723100b12e58be9dfa5a24491"}, + {file = "websockets-13.0.1-pp38-pypy38_pp73-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:00fd961943b6c10ee6f0b1130753e50ac5dcd906130dcd77b0003c3ab797d026"}, + {file = "websockets-13.0.1-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:d93572720d781331fb10d3da9ca1067817d84ad1e7c31466e9f5e59965618096"}, + {file = "websockets-13.0.1-pp39-pypy39_pp73-macosx_10_15_x86_64.whl", hash = "sha256:71e6e5a3a3728886caee9ab8752e8113670936a193284be9d6ad2176a137f376"}, + {file = "websockets-13.0.1-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:c4a6343e3b0714e80da0b0893543bf9a5b5fa71b846ae640e56e9abc6fbc4c83"}, + {file = "websockets-13.0.1-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1a678532018e435396e37422a95e3ab87f75028ac79570ad11f5bf23cd2a7d8c"}, + {file = "websockets-13.0.1-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d6716c087e4aa0b9260c4e579bb82e068f84faddb9bfba9906cb87726fa2e870"}, + {file = "websockets-13.0.1-pp39-pypy39_pp73-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e33505534f3f673270dd67f81e73550b11de5b538c56fe04435d63c02c3f26b5"}, + {file = "websockets-13.0.1-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:acab3539a027a85d568c2573291e864333ec9d912675107d6efceb7e2be5d980"}, + {file = "websockets-13.0.1-py3-none-any.whl", hash = "sha256:b80f0c51681c517604152eb6a572f5a9378f877763231fddb883ba2f968e8817"}, + {file = "websockets-13.0.1.tar.gz", hash = "sha256:4d6ece65099411cfd9a48d13701d7438d9c34f479046b34c50ff60bb8834e43e"}, ] [[package]] diff --git a/pycardano/transaction.py b/pycardano/transaction.py index 79b7ce01..acdd3fa4 100644 --- a/pycardano/transaction.py +++ b/pycardano/transaction.py @@ -28,7 +28,7 @@ from pycardano.metadata import AuxiliaryData from pycardano.nativescript import NativeScript from pycardano.network import Network -from pycardano.plutus import Datum, PlutusV1Script, PlutusV2Script, RawPlutusData +from pycardano.plutus import Datum, PlutusV1Script, PlutusV2Script, PlutusV3Script, RawPlutusData from pycardano.serialization import ( ArrayCBORSerializable, CBORSerializable, @@ -370,7 +370,7 @@ class TransactionOutput(CBORSerializable): datum: Optional[Datum] = None - script: Optional[Union[NativeScript, PlutusV1Script, PlutusV2Script]] = None + script: Optional[Union[NativeScript, PlutusV1Script, PlutusV2Script, PlutusV3Script]] = None post_alonzo: Optional[bool] = False diff --git a/pycardano/txbuilder.py b/pycardano/txbuilder.py index 62a0b5ad..ebc5b94d 100644 --- a/pycardano/txbuilder.py +++ b/pycardano/txbuilder.py @@ -290,9 +290,11 @@ def add_script_input( for candidate_script, candidate_utxo in candidate_scripts: if script_hash(candidate_script) != input_script_hash: continue + found_valid_script = True self._inputs_to_scripts[utxo] = candidate_script - if candidate_utxo is not None: + + if candidate_utxo is not None and candidate_utxo != utxo: self.reference_inputs.add(candidate_utxo) self._reference_scripts.append(candidate_script) break @@ -944,10 +946,14 @@ def _build_full_fake_tx(self) -> Transaction: ) return tx - def build_witness_set(self) -> TransactionWitnessSet: + def build_witness_set(self, remove_dup_script=False) -> TransactionWitnessSet: """Build a transaction witness set, excluding verification key witnesses. This function is especially useful when the transaction involves Plutus scripts. + Args: + remove_dup_script (bool): Whether to remove scripts, that are already attached to inputs, + from the witness set. + Returns: TransactionWitnessSet: A transaction witness set without verification key witnesses. """ @@ -957,21 +963,24 @@ def build_witness_set(self) -> TransactionWitnessSet: plutus_v2_scripts: List[PlutusV2Script] = [] plutus_v3_scripts: List[PlutusV3Script] = [] + input_scripts = {script_hash(i.output.script) for i in self.inputs if i.output.script is not None} if remove_dup_script else {} + for script in self.scripts: - if isinstance(script, NativeScript): - native_scripts.append(script) - elif isinstance(script, PlutusV1Script): - plutus_v1_scripts.append(script) - elif type(script) is bytes: - plutus_v1_scripts.append(PlutusV1Script(script)) - elif isinstance(script, PlutusV2Script): - plutus_v2_scripts.append(script) - elif isinstance(script, PlutusV3Script): - plutus_v3_scripts.append(script) - else: - raise InvalidArgumentException( - f"Unsupported script type: {type(script)}" - ) + if script_hash(script) not in input_scripts: + if isinstance(script, NativeScript): + native_scripts.append(script) + elif isinstance(script, PlutusV1Script): + plutus_v1_scripts.append(script) + elif type(script) is bytes: + plutus_v1_scripts.append(PlutusV1Script(script)) + elif isinstance(script, PlutusV2Script): + plutus_v2_scripts.append(script) + elif isinstance(script, PlutusV3Script): + plutus_v3_scripts.append(script) + else: + raise InvalidArgumentException( + f"Unsupported script type: {type(script)}" + ) return TransactionWitnessSet( native_scripts=native_scripts if native_scripts else None, @@ -1432,7 +1441,7 @@ def build_and_sign( auto_ttl_offset=auto_ttl_offset, auto_required_signers=auto_required_signers, ) - witness_set = self.build_witness_set() + witness_set = self.build_witness_set(True) witness_set.vkey_witnesses = [] for signing_key in set(signing_keys): diff --git a/pyproject.toml b/pyproject.toml index 4e81b5e3..93967152 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -35,7 +35,7 @@ frozendict = "^2.3.8" frozenlist = "^1.3.3" cachetools = "^5.3.0" docker = "^7.1.0" -ogmios = {git = "https://gitlab.com/cffls/ogmios-python.git"} +ogmios = {git = "https://gitlab.com/viperscience/ogmios-python.git"} requests = "^2.32.3" websockets = "^13.0" From 965dc645f8facde422a3672d27e30ad888a69a78 Mon Sep 17 00:00:00 2001 From: Jerry Date: Fri, 30 Aug 2024 18:56:02 -0700 Subject: [PATCH 13/44] Working plutus v3 --- integration-test/plutus_scripts/helloworldV3.plutus | 2 +- integration-test/test/base.py | 2 +- integration-test/test/test_plutus.py | 2 ++ pycardano/backend/ogmios_v6.py | 9 ++++++++- pycardano/txbuilder.py | 7 ++++++- 5 files changed, 18 insertions(+), 4 deletions(-) diff --git a/integration-test/plutus_scripts/helloworldV3.plutus b/integration-test/plutus_scripts/helloworldV3.plutus index a2aa60c0..d61b9448 100644 --- a/integration-test/plutus_scripts/helloworldV3.plutus +++ b/integration-test/plutus_scripts/helloworldV3.plutus @@ -1 +1 @@ -58e901010032323232323223223225333006323253330083371e6eb8c008c028dd5002a4410d48656c6c6f2c20576f726c642100100114a06644646600200200644a66601c00229404c94ccc030cdc79bae301000200414a226600600600260200026eb0c02cc030c030c030c030c030c030c030c030c024dd5180098049baa002375c600260126ea80188c02c0045261365653330043370e900018029baa001132325333009300b002149858dd7180480098031baa0011653330023370e900018019baa0011323253330073009002149858dd7180380098021baa001165734aae7555cf2ab9f5742ae881 \ No newline at end of file +59011d0100003232323232323225333002323232323253330073370e900118041baa0011323232533300a3370e900018059baa005132533300e0011613253333330120011616161613253330103012003132533300e3370e900018079baa005132533300f002100114a06644646600200200644a66602a00229404c94ccc04ccdc79bae301700200414a2266006006002602e0026eb0c048c04cc04cc04cc04cc04cc04cc04cc04cc040dd50059bae301230103754602460206ea801458cdc79bae3011300f375401091010d48656c6c6f2c20576f726c64210016375c002601e00260186ea801458c034c038008c030004c024dd50008b1805180580118048009804801180380098021baa00114984d9595cd2ab9d5573caae7d5d0aba25749 \ No newline at end of file diff --git a/integration-test/test/base.py b/integration-test/test/base.py index 085d095b..acd71973 100644 --- a/integration-test/test/base.py +++ b/integration-test/test/base.py @@ -6,7 +6,7 @@ from pycardano import * -TEST_RETRIES = 6 +TEST_RETRIES = 1 @retry(tries=10, delay=4) diff --git a/integration-test/test/test_plutus.py b/integration-test/test/test_plutus.py index 3144d4da..fa947c45 100644 --- a/integration-test/test/test_plutus.py +++ b/integration-test/test/test_plutus.py @@ -439,6 +439,8 @@ def test_plutus_v3(self): print("############### Submitting transaction ###############") self.chain_context.submit_tx(signed_tx) + time.sleep(3) + self.assert_output(taker_address, take_output) diff --git a/pycardano/backend/ogmios_v6.py b/pycardano/backend/ogmios_v6.py index 87d5501c..7c876176 100644 --- a/pycardano/backend/ogmios_v6.py +++ b/pycardano/backend/ogmios_v6.py @@ -34,7 +34,7 @@ PLUTUS_V2_COST_MODEL, PlutusV1Script, PlutusV2Script, - ExecutionUnits, + ExecutionUnits, PlutusV3Script, ) from pycardano.hash import ScriptHash, DatumHash from pycardano.serialization import RawCBOR @@ -258,6 +258,8 @@ def _utxo_from_ogmios_result(self, utxo: Utxo) -> UTxO: script = utxo.script if script: # TODO: Need to test with native scripts + if script["language"] == "plutus:v3": + script = PlutusV3Script(bytes.fromhex(script["cbor"])) if script["language"] == "plutus:v2": script = PlutusV2Script(bytes.fromhex(script["cbor"])) elif script["language"] == "plutus:v1": @@ -344,6 +346,11 @@ def _parse_cost_models(self, plutus_cost_models): ogmios_cost_models["plutus:v2"].copy(), ) ) + if "plutus:v3" in ogmios_cost_models: + cost_models["PlutusV3"] = {} + width = len(ogmios_cost_models["plutus:v3"]) + for i, v in enumerate(ogmios_cost_models["plutus:v3"].copy()): + cost_models["PlutusV3"][f"{i:0{width}d}"] = v return cost_models diff --git a/pycardano/txbuilder.py b/pycardano/txbuilder.py index ebc5b94d..ca5a66c2 100644 --- a/pycardano/txbuilder.py +++ b/pycardano/txbuilder.py @@ -496,6 +496,8 @@ def redeemers(self) -> List[Redeemer]: def script_data_hash(self) -> Optional[ScriptDataHash]: if self.datums or self.redeemers: cost_models = {} + print("All scripts", self.all_scripts) + print("Cost models", self.context.protocol_param.cost_models) for s in self.all_scripts: if isinstance(s, PlutusV1Script) or type(s) is bytes: cost_models[0] = ( @@ -508,7 +510,7 @@ def script_data_hash(self) -> Optional[ScriptDataHash]: or PLUTUS_V2_COST_MODEL ) if isinstance(s, PlutusV3Script): - cost_models[1] = self.context.protocol_param.cost_models.get( + cost_models[2] = self.context.protocol_param.cost_models.get( "PlutusV3", {} ) return script_data_hash( @@ -1263,6 +1265,7 @@ def _set_collateral_return(self, collateral_return_address: Optional[Address]): if ( not witnesses.plutus_v1_script and not witnesses.plutus_v2_script + and not witnesses.plutus_v3_script and not self._reference_scripts ): return @@ -1391,6 +1394,8 @@ def _estimate_execution_units( tx_body, witness_set, auxiliary_data=tmp_builder.auxiliary_data ) + print(tx) + return self.context.evaluate_tx(tx) def build_and_sign( From 81c4602e64e02d36869647f6c8cfa1c0ee328fdd Mon Sep 17 00:00:00 2001 From: Jerry Date: Fri, 30 Aug 2024 18:58:28 -0700 Subject: [PATCH 14/44] Restore test retries --- integration-test/test/base.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/integration-test/test/base.py b/integration-test/test/base.py index acd71973..085d095b 100644 --- a/integration-test/test/base.py +++ b/integration-test/test/base.py @@ -6,7 +6,7 @@ from pycardano import * -TEST_RETRIES = 1 +TEST_RETRIES = 6 @retry(tries=10, delay=4) From 6b757d81d2917a04bc116a5de67beb400837ded7 Mon Sep 17 00:00:00 2001 From: Jerry Date: Fri, 30 Aug 2024 18:59:08 -0700 Subject: [PATCH 15/44] Remove prints --- pycardano/txbuilder.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/pycardano/txbuilder.py b/pycardano/txbuilder.py index ca5a66c2..43b06aa9 100644 --- a/pycardano/txbuilder.py +++ b/pycardano/txbuilder.py @@ -496,8 +496,6 @@ def redeemers(self) -> List[Redeemer]: def script_data_hash(self) -> Optional[ScriptDataHash]: if self.datums or self.redeemers: cost_models = {} - print("All scripts", self.all_scripts) - print("Cost models", self.context.protocol_param.cost_models) for s in self.all_scripts: if isinstance(s, PlutusV1Script) or type(s) is bytes: cost_models[0] = ( From 9bd906b1f8a876963f0e1919e3bfa2495e9880bb Mon Sep 17 00:00:00 2001 From: Jerry Date: Fri, 30 Aug 2024 18:59:50 -0700 Subject: [PATCH 16/44] Remove more prints --- pycardano/txbuilder.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/pycardano/txbuilder.py b/pycardano/txbuilder.py index 43b06aa9..8bf91972 100644 --- a/pycardano/txbuilder.py +++ b/pycardano/txbuilder.py @@ -1392,8 +1392,6 @@ def _estimate_execution_units( tx_body, witness_set, auxiliary_data=tmp_builder.auxiliary_data ) - print(tx) - return self.context.evaluate_tx(tx) def build_and_sign( From 05a40f2afcad323e221ac14db10ca252b0303859 Mon Sep 17 00:00:00 2001 From: Jerry Date: Fri, 30 Aug 2024 19:00:11 -0700 Subject: [PATCH 17/44] Format code --- pycardano/backend/kupo.py | 9 +++---- pycardano/backend/ogmios_v5.py | 2 +- pycardano/backend/ogmios_v6.py | 44 +++++++++++++++++----------------- pycardano/transaction.py | 12 ++++++++-- pycardano/txbuilder.py | 10 +++++++- 5 files changed, 45 insertions(+), 32 deletions(-) diff --git a/pycardano/backend/kupo.py b/pycardano/backend/kupo.py index 28889182..c3e78633 100644 --- a/pycardano/backend/kupo.py +++ b/pycardano/backend/kupo.py @@ -1,13 +1,10 @@ -from typing import Dict, List, Optional, Union, Tuple +from typing import Dict, List, Optional, Tuple, Union import requests from cachetools import Cache, LRUCache, TTLCache from pycardano.address import Address -from pycardano.backend.base import ( - ChainContext, - GenesisParameters, -) +from pycardano.backend.base import ChainContext, GenesisParameters from pycardano.backend.blockfrost import _try_fix_script from pycardano.hash import DatumHash, ScriptHash from pycardano.network import Network @@ -15,12 +12,12 @@ from pycardano.serialization import RawCBOR from pycardano.transaction import ( Asset, + AssetName, MultiAsset, TransactionInput, TransactionOutput, UTxO, Value, - AssetName, ) __all__ = ["KupoChainContextExtension"] diff --git a/pycardano/backend/ogmios_v5.py b/pycardano/backend/ogmios_v5.py index 528bd0fb..74802ef9 100644 --- a/pycardano/backend/ogmios_v5.py +++ b/pycardano/backend/ogmios_v5.py @@ -15,6 +15,7 @@ GenesisParameters, ProtocolParameters, ) +from pycardano.backend.kupo import KupoChainContextExtension, extract_asset_info from pycardano.exception import TransactionFailedException from pycardano.hash import DatumHash from pycardano.network import Network @@ -29,7 +30,6 @@ Value, ) from pycardano.types import JsonDict -from pycardano.backend.kupo import KupoChainContextExtension, extract_asset_info __all__ = ["OgmiosV5ChainContext"] diff --git a/pycardano/backend/ogmios_v6.py b/pycardano/backend/ogmios_v6.py index 7c876176..715d5710 100644 --- a/pycardano/backend/ogmios_v6.py +++ b/pycardano/backend/ogmios_v6.py @@ -1,49 +1,49 @@ import time -from typing import Optional, Union, Dict, List -from cachetools import Cache, LRUCache, TTLCache, func +from typing import Dict, List, Optional, Union +from cachetools import Cache, LRUCache, TTLCache, func from ogmios.client import Client from ogmios.datatypes import ( - ProtocolParameters, + Address, Era, + ProtocolParameters, Tip, - Utxo, - Address, TxOutputReference, + Utxo, ) -from ogmios.utils import get_current_era, GenesisParameters +from ogmios.utils import GenesisParameters, get_current_era +from pycardano.backend.base import ChainContext +from pycardano.backend.base import ProtocolParameters as pycProtocolParameters from pycardano.backend.kupo import KupoChainContextExtension -from pycardano.backend.base import ( - ChainContext, - ProtocolParameters as pycProtocolParameters, -) +from pycardano.hash import DatumHash, ScriptHash from pycardano.network import Network -from pycardano.transaction import ( - UTxO, - TransactionOutput, - Value, - TransactionInput, - MultiAsset, - AssetName, - Asset, - Address as pyc_Address, -) from pycardano.plutus import ( PLUTUS_V1_COST_MODEL, PLUTUS_V2_COST_MODEL, + ExecutionUnits, PlutusV1Script, PlutusV2Script, - ExecutionUnits, PlutusV3Script, + PlutusV3Script, ) -from pycardano.hash import ScriptHash, DatumHash from pycardano.serialization import RawCBOR +from pycardano.transaction import Address as pyc_Address +from pycardano.transaction import ( + Asset, + AssetName, + MultiAsset, + TransactionInput, + TransactionOutput, + UTxO, + Value, +) ALONZO_COINS_PER_UTXO_WORD = 34482 DEFAULT_REFETCH_INTERVAL = 1000 __all__ = ["OgmiosV6ChainContext"] + class OgmiosV6ChainContext(ChainContext): """Ogmios chain context for use with PyCardano""" diff --git a/pycardano/transaction.py b/pycardano/transaction.py index acdd3fa4..fda7b7c4 100644 --- a/pycardano/transaction.py +++ b/pycardano/transaction.py @@ -28,7 +28,13 @@ from pycardano.metadata import AuxiliaryData from pycardano.nativescript import NativeScript from pycardano.network import Network -from pycardano.plutus import Datum, PlutusV1Script, PlutusV2Script, PlutusV3Script, RawPlutusData +from pycardano.plutus import ( + Datum, + PlutusV1Script, + PlutusV2Script, + PlutusV3Script, + RawPlutusData, +) from pycardano.serialization import ( ArrayCBORSerializable, CBORSerializable, @@ -370,7 +376,9 @@ class TransactionOutput(CBORSerializable): datum: Optional[Datum] = None - script: Optional[Union[NativeScript, PlutusV1Script, PlutusV2Script, PlutusV3Script]] = None + script: Optional[ + Union[NativeScript, PlutusV1Script, PlutusV2Script, PlutusV3Script] + ] = None post_alonzo: Optional[bool] = False diff --git a/pycardano/txbuilder.py b/pycardano/txbuilder.py index 8bf91972..13cbd119 100644 --- a/pycardano/txbuilder.py +++ b/pycardano/txbuilder.py @@ -963,7 +963,15 @@ def build_witness_set(self, remove_dup_script=False) -> TransactionWitnessSet: plutus_v2_scripts: List[PlutusV2Script] = [] plutus_v3_scripts: List[PlutusV3Script] = [] - input_scripts = {script_hash(i.output.script) for i in self.inputs if i.output.script is not None} if remove_dup_script else {} + input_scripts = ( + { + script_hash(i.output.script) + for i in self.inputs + if i.output.script is not None + } + if remove_dup_script + else {} + ) for script in self.scripts: if script_hash(script) not in input_scripts: From 02886456705f004098705d67878295eb6342692a Mon Sep 17 00:00:00 2001 From: Jerry Date: Fri, 30 Aug 2024 20:14:33 -0700 Subject: [PATCH 18/44] Fix mypy --- pycardano/transaction.py | 14 ++++++++++---- test/pycardano/test_txbuilder.py | 2 +- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/pycardano/transaction.py b/pycardano/transaction.py index fda7b7c4..1d10799a 100644 --- a/pycardano/transaction.py +++ b/pycardano/transaction.py @@ -265,15 +265,17 @@ def to_shallow_primitive(self): class _Script(ArrayCBORSerializable): _TYPE: int = field(init=False, default=0) - script: Union[NativeScript, PlutusV1Script, PlutusV2Script] + script: Union[NativeScript, PlutusV1Script, PlutusV2Script, PlutusV3Script] def __post_init__(self): if isinstance(self.script, NativeScript): self._TYPE = 0 elif isinstance(self.script, PlutusV1Script): self._TYPE = 1 - else: + elif isinstance(self.script, PlutusV2Script): self._TYPE = 2 + else: + self._TYPE = 3 @classmethod def from_primitive(cls: Type[_Script], values: List[Primitive]) -> _Script: @@ -282,8 +284,10 @@ def from_primitive(cls: Type[_Script], values: List[Primitive]) -> _Script: assert isinstance(values[1], bytes) if values[0] == 1: return cls(PlutusV1Script(values[1])) - else: + elif values[0] == 2: return cls(PlutusV2Script(values[1])) + else: + return cls(PlutusV3Script(values[1])) @dataclass(repr=False) @@ -350,7 +354,9 @@ class _TransactionOutputPostAlonzo(MapCBORSerializable): ) @property - def script(self) -> Optional[Union[NativeScript, PlutusV1Script, PlutusV2Script]]: + def script( + self, + ) -> Optional[Union[NativeScript, PlutusV1Script, PlutusV2Script, PlutusV3Script]]: if self.script_ref: return self.script_ref.script.script else: diff --git a/test/pycardano/test_txbuilder.py b/test/pycardano/test_txbuilder.py index 373b57c5..d1b9e4ee 100644 --- a/test/pycardano/test_txbuilder.py +++ b/test/pycardano/test_txbuilder.py @@ -595,7 +595,7 @@ def test_add_script_input_no_script(chain_context): ) tx_builder.add_output(TransactionOutput(receiver, 5000000)) tx_builder.build(change_address=receiver) - witness = tx_builder.build_witness_set() + witness = tx_builder.build_witness_set(remove_dup_script=True) assert [datum] == witness.plutus_data assert [redeemer] == witness.redeemer assert witness.plutus_v1_script is None From 1da49b6fdec1f26ce9584bf1c168f42b8bf917c4 Mon Sep 17 00:00:00 2001 From: Jerry Date: Sun, 1 Sep 2024 13:01:38 -0700 Subject: [PATCH 19/44] Add tests --- pycardano/utils.py | 10 ++--- test/pycardano/test_txbuilder.py | 73 ++++++++++++++++++++++++++++++++ test/pycardano/test_util.py | 60 +++++++++++++++++++++++++- 3 files changed, 137 insertions(+), 6 deletions(-) diff --git a/pycardano/utils.py b/pycardano/utils.py index 23a6dda1..e2e47e79 100644 --- a/pycardano/utils.py +++ b/pycardano/utils.py @@ -59,13 +59,13 @@ def tiered_reference_script_fee(context: ChainContext, scripts_size: int) -> int m = context.protocol_param.min_fee_reference_scripts["multiplier"] while scripts_size > r: - total += math.ceil(b * r) - scripts_size = math.ceil(scripts_size - r) - b = math.ceil(b * m) + total += b * r + scripts_size = scripts_size - r + b = b * m - total += math.ceil(b * scripts_size) + total += b * scripts_size - return total + return math.ceil(total) def fee( diff --git a/test/pycardano/test_txbuilder.py b/test/pycardano/test_txbuilder.py index d1b9e4ee..134047f3 100644 --- a/test/pycardano/test_txbuilder.py +++ b/test/pycardano/test_txbuilder.py @@ -25,6 +25,7 @@ POOL_KEY_HASH_SIZE, VERIFICATION_KEY_HASH_SIZE, PoolKeyHash, + TransactionId, VerificationKeyHash, ) from pycardano.key import VerificationKey @@ -39,9 +40,11 @@ PlutusData, PlutusV1Script, PlutusV2Script, + PlutusV3Script, Redeemer, RedeemerTag, plutus_script_hash, + script_hash, ) from pycardano.transaction import ( MultiAsset, @@ -1737,3 +1740,73 @@ def test_tx_builder_merge_change_to_output_3(chain_context): ) tx = builder.build(change_address=address, merge_change=True) assert len(tx.outputs) == 1 + + +def test_build_witness_set_mixed_scripts(chain_context): + # Create dummy scripts + plutus_v1_script = PlutusV1Script(b"plutus v1 script") + plutus_v2_script = PlutusV2Script(b"plutus v2 script") + plutus_v3_script = PlutusV3Script(b"plutus v3 script") + + # Create a TransactionBuilder instance + builder = TransactionBuilder(chain_context) + + # Add inputs with different scripts + input_v1 = UTxO( + TransactionInput(TransactionId(32 * b"0"), 0), + TransactionOutput( + Address(script_hash(plutus_v1_script)), + Value(1000000), + script=plutus_v1_script, + ), + ) + input_v2 = UTxO( + TransactionInput(TransactionId(32 * b"0"), 1), + TransactionOutput( + Address(script_hash(plutus_v2_script)), + Value(1000000), + script=plutus_v2_script, + ), + ) + input_v3 = UTxO( + TransactionInput(TransactionId(32 * b"0"), 3), + TransactionOutput( + Address(script_hash(plutus_v3_script)), + Value(1000000), + script=plutus_v3_script, + ), + ) + builder.add_input(input_v1) + builder.add_input(input_v2) + builder.add_input(input_v3) + + # Add scripts to the builder + builder._inputs_to_scripts[input_v1] = plutus_v1_script + builder._inputs_to_scripts[input_v2] = plutus_v2_script + builder._inputs_to_scripts[input_v3] = plutus_v3_script + + # Add an additional PlutusV1Script + additional_v1_script = PlutusV1Script(b"additional v1 script") + builder._inputs_to_scripts[ + UTxO( + TransactionInput(TransactionId(32 * b"1"), 0), + TransactionOutput( + Address(script_hash(additional_v1_script)), Value(1000000) + ), + ) + ] = additional_v1_script + + # Test with remove_dup_script=True + witness_set = builder.build_witness_set(remove_dup_script=True) + assert len(witness_set.plutus_v1_script) == 1 + assert script_hash(witness_set.plutus_v1_script[0]) == script_hash( + additional_v1_script + ) + assert witness_set.plutus_v2_script is None + assert witness_set.plutus_v3_script is None + + # Test with remove_dup_script=False + witness_set = builder.build_witness_set(remove_dup_script=False) + assert len(witness_set.plutus_v1_script) == 2 + assert len(witness_set.plutus_v2_script) == 1 + assert len(witness_set.plutus_v3_script) == 1 diff --git a/test/pycardano/test_util.py b/test/pycardano/test_util.py index 118c8e13..444546af 100644 --- a/test/pycardano/test_util.py +++ b/test/pycardano/test_util.py @@ -1,9 +1,15 @@ from test.pycardano.util import chain_context +import pytest + from pycardano.hash import SCRIPT_HASH_SIZE, ScriptDataHash from pycardano.plutus import ExecutionUnits, PlutusData, Redeemer, RedeemerTag, Unit from pycardano.transaction import Value -from pycardano.utils import min_lovelace_pre_alonzo, script_data_hash +from pycardano.utils import ( + min_lovelace_pre_alonzo, + script_data_hash, + tiered_reference_script_fee, +) def test_min_lovelace_ada_only(chain_context): @@ -166,3 +172,55 @@ def test_script_data_hash_redeemer_only(): assert ScriptDataHash.from_primitive( "a88fe2947b8d45d1f8b798e52174202579ecf847b8f17038c7398103df2d27b0" ) == script_data_hash(redeemers=redeemers, datums=[]) + + +class MockProtocolParam: + def __init__(self, max_size, base, range, multiplier): + self.maximum_reference_scripts_size = {"bytes": max_size} + self.min_fee_reference_scripts = { + "base": base, + "range": range, + "multiplier": multiplier, + } + + +class MockChainContext: + def __init__(self, protocol_param): + self.protocol_param = protocol_param + + +@pytest.mark.parametrize( + "max_size,base,range,multiplier,scripts_size,expected", + [ + (200 * 1024, 44, 25600, 1.2, 80 * 1024, 4489380), + ], +) +def test_tiered_reference_script_fee( + max_size, base, range, multiplier, scripts_size, expected +): + protocol_param = MockProtocolParam(max_size, base, range, multiplier) + context = MockChainContext(protocol_param) + + result = tiered_reference_script_fee(context, scripts_size) + assert result == expected + + +def test_tiered_reference_script_fee_exceeds_max_size(): + protocol_param = MockProtocolParam(1000, 10, 100, 1.1) + context = MockChainContext(protocol_param) + + with pytest.raises( + ValueError, match="Reference scripts size: 1001 exceeds maximum allowed size" + ): + tiered_reference_script_fee(context, 1001) + + +def test_tiered_reference_script_fee_no_params(): + class EmptyProtocolParam: + maximum_reference_scripts_size = None + min_fee_reference_scripts = None + + context = MockChainContext(EmptyProtocolParam()) + + result = tiered_reference_script_fee(context, 100) + assert result == 0 From 92689b87ca0090aee78c8f634034c3c9258a9988 Mon Sep 17 00:00:00 2001 From: Jerry Date: Sun, 1 Sep 2024 14:07:36 -0700 Subject: [PATCH 20/44] Add kupo back to integration test --- integration-test/docker-compose-chang.yml | 2 +- integration-test/test/base.py | 2 +- integration-test/test/test_plutus.py | 9 +++++---- pycardano/backend/kupo.py | 7 ++++++- pycardano/backend/ogmios_v6.py | 2 +- 5 files changed, 14 insertions(+), 8 deletions(-) diff --git a/integration-test/docker-compose-chang.yml b/integration-test/docker-compose-chang.yml index 73866f83..1ec314ce 100644 --- a/integration-test/docker-compose-chang.yml +++ b/integration-test/docker-compose-chang.yml @@ -79,7 +79,7 @@ services: max-file: "10" kupo: - image: cardanosolutions/kupo:v2.4.0 + image: cardanosolutions/kupo:v2.9.0 platform: linux/amd64 environment: NETWORK: "${NETWORK:-local}" diff --git a/integration-test/test/base.py b/integration-test/test/base.py index 085d095b..2b35ac3e 100644 --- a/integration-test/test/base.py +++ b/integration-test/test/base.py @@ -6,7 +6,7 @@ from pycardano import * -TEST_RETRIES = 6 +TEST_RETRIES = 8 @retry(tries=10, delay=4) diff --git a/integration-test/test/test_plutus.py b/integration-test/test/test_plutus.py index fa947c45..965bc0f9 100644 --- a/integration-test/test/test_plutus.py +++ b/integration-test/test/test_plutus.py @@ -8,6 +8,7 @@ from retry import retry from pycardano import * +from pycardano.backend.kupo import KupoChainContextExtension from .base import TEST_RETRIES, TestBase from .test_cardano_cli import TestCardanoCli @@ -444,10 +445,10 @@ def test_plutus_v3(self): self.assert_output(taker_address, take_output) -# class TestPlutusOgmiosOnly(TestPlutus): -# @classmethod -# def setup_class(cls): -# cls.chain_context._kupo_url = None +class TestPlutusKupoOgmios(TestPlutus): + @classmethod + def setup_class(cls): + cls.chain_context = KupoChainContextExtension(cls.chain_context, cls.KUPO_URL) def evaluate_tx(tx: Transaction) -> Dict[str, ExecutionUnits]: diff --git a/pycardano/backend/kupo.py b/pycardano/backend/kupo.py index c3e78633..f4fa5078 100644 --- a/pycardano/backend/kupo.py +++ b/pycardano/backend/kupo.py @@ -4,7 +4,7 @@ from cachetools import Cache, LRUCache, TTLCache from pycardano.address import Address -from pycardano.backend.base import ChainContext, GenesisParameters +from pycardano.backend.base import ChainContext, GenesisParameters, ProtocolParameters from pycardano.backend.blockfrost import _try_fix_script from pycardano.hash import DatumHash, ScriptHash from pycardano.network import Network @@ -68,6 +68,11 @@ def genesis_param(self) -> GenesisParameters: return self._wrapped_backend.genesis_param + @property + def protocol_param(self) -> ProtocolParameters: + """Get current protocol parameters""" + return self._wrapped_backend.protocol_param + @property def network(self) -> Network: """Get current network""" diff --git a/pycardano/backend/ogmios_v6.py b/pycardano/backend/ogmios_v6.py index 715d5710..385195b0 100644 --- a/pycardano/backend/ogmios_v6.py +++ b/pycardano/backend/ogmios_v6.py @@ -348,7 +348,7 @@ def _parse_cost_models(self, plutus_cost_models): ) if "plutus:v3" in ogmios_cost_models: cost_models["PlutusV3"] = {} - width = len(ogmios_cost_models["plutus:v3"]) + width = len(f'{len(ogmios_cost_models["plutus:v3"])}') for i, v in enumerate(ogmios_cost_models["plutus:v3"].copy()): cost_models["PlutusV3"][f"{i:0{width}d}"] = v return cost_models From 5b6bf37766c6fb73ec444993dad18e92b3247449 Mon Sep 17 00:00:00 2001 From: Jerry Date: Sun, 1 Sep 2024 14:18:17 -0700 Subject: [PATCH 21/44] Fix qa --- pycardano/utils.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pycardano/utils.py b/pycardano/utils.py index e2e47e79..036b5019 100644 --- a/pycardano/utils.py +++ b/pycardano/utils.py @@ -52,10 +52,10 @@ def tiered_reference_script_fee(context: ChainContext, scripts_size: int) -> int f"Reference scripts size: {scripts_size} exceeds maximum allowed size ({max_size})." ) - total = 0 + total = 0.0 if scripts_size: b = context.protocol_param.min_fee_reference_scripts["base"] - r = context.protocol_param.min_fee_reference_scripts["range"] + r = math.ceil(context.protocol_param.min_fee_reference_scripts["range"]) m = context.protocol_param.min_fee_reference_scripts["multiplier"] while scripts_size > r: From 5a3c0803e097371a8d4837d5238b878558446d49 Mon Sep 17 00:00:00 2001 From: Niels Date: Mon, 2 Sep 2024 18:21:05 +0200 Subject: [PATCH 22/44] Bump ogmios version --- poetry.lock | 182 ++++++++++++++++++++++++++-------------------------- 1 file changed, 91 insertions(+), 91 deletions(-) diff --git a/poetry.lock b/poetry.lock index 1e2799dc..7f1b9d28 100644 --- a/poetry.lock +++ b/poetry.lock @@ -222,13 +222,13 @@ test = ["coverage (>=7)", "hypothesis", "pytest"] [[package]] name = "certifi" -version = "2024.7.4" +version = "2024.8.30" description = "Python package for providing Mozilla's CA Bundle." optional = false python-versions = ">=3.6" files = [ - {file = "certifi-2024.7.4-py3-none-any.whl", hash = "sha256:c198e21b1289c2ab85ee4e67bb4b4ef3ead0892059901a8d5b622f24a1101e90"}, - {file = "certifi-2024.7.4.tar.gz", hash = "sha256:5a1e7645bc0ec61a09e26c36f6106dd4cf40c6db3a1fb6352b0244e7fb057c7b"}, + {file = "certifi-2024.8.30-py3-none-any.whl", hash = "sha256:922820b53db7a7257ffbda3f597266d435245903d80737e34f8a45ff3e3230d8"}, + {file = "certifi-2024.8.30.tar.gz", hash = "sha256:bec941d2aa8195e248a60b31ff9f0558284cf01a52591ceda73ea9afffd69fd9"}, ] [[package]] @@ -1169,7 +1169,7 @@ testing = ["coverage[toml] (>=6.5)", "pycardano", "pytest"] type = "git" url = "https://gitlab.com/viperscience/ogmios-python.git" reference = "HEAD" -resolved_reference = "10cf42274944d6e5d9f17032f77cafd2df5b85ea" +resolved_reference = "0b713e78839341d92828340a5552ef8dd1c6224b" [[package]] name = "orjson" @@ -1991,97 +1991,97 @@ test = ["websockets"] [[package]] name = "websockets" -version = "13.0" +version = "13.0.1" description = "An implementation of the WebSocket Protocol (RFC 6455 & 7692)" optional = false python-versions = ">=3.8" files = [ - {file = "websockets-13.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:ad4fa707ff9e2ffee019e946257b5300a45137a58f41fbd9a4db8e684ab61528"}, - {file = "websockets-13.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:6fd757f313c13c34dae9f126d3ba4cf97175859c719e57c6a614b781c86b617e"}, - {file = "websockets-13.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:cbac2eb7ce0fac755fb983c9247c4a60c4019bcde4c0e4d167aeb17520cc7ef1"}, - {file = "websockets-13.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d4b83cf7354cbbc058e97b3e545dceb75b8d9cf17fd5a19db419c319ddbaaf7a"}, - {file = "websockets-13.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9202c0010c78fad1041e1c5285232b6508d3633f92825687549540a70e9e5901"}, - {file = "websockets-13.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3e6566e79c8c7cbea75ec450f6e1828945fc5c9a4769ceb1c7b6e22470539712"}, - {file = "websockets-13.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:e7fcad070dcd9ad37a09d89a4cbc2a5e3e45080b88977c0da87b3090f9f55ead"}, - {file = "websockets-13.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:0a8f7d65358a25172db00c69bcc7df834155ee24229f560d035758fd6613111a"}, - {file = "websockets-13.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:63b702fb31e3f058f946ccdfa551f4d57a06f7729c369e8815eb18643099db37"}, - {file = "websockets-13.0-cp310-cp310-win32.whl", hash = "sha256:3a20cf14ba7b482c4a1924b5e061729afb89c890ca9ed44ac4127c6c5986e424"}, - {file = "websockets-13.0-cp310-cp310-win_amd64.whl", hash = "sha256:587245f0704d0bb675f919898d7473e8827a6d578e5a122a21756ca44b811ec8"}, - {file = "websockets-13.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:06df8306c241c235075d2ae77367038e701e53bc8c1bb4f6644f4f53aa6dedd0"}, - {file = "websockets-13.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:85a1f92a02f0b8c1bf02699731a70a8a74402bb3f82bee36e7768b19a8ed9709"}, - {file = "websockets-13.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:9ed02c604349068d46d87ef4c2012c112c791f2bec08671903a6bb2bd9c06784"}, - {file = "websockets-13.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b89849171b590107f6724a7b0790736daead40926ddf47eadf998b4ff51d6414"}, - {file = "websockets-13.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:939a16849d71203628157a5e4a495da63967c744e1e32018e9b9e2689aca64d4"}, - {file = "websockets-13.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ad818cdac37c0ad4c58e51cb4964eae4f18b43c4a83cb37170b0d90c31bd80cf"}, - {file = "websockets-13.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:cbfe82a07596a044de78bb7a62519e71690c5812c26c5f1d4b877e64e4f46309"}, - {file = "websockets-13.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:e07e76c49f39c5b45cbd7362b94f001ae209a3ea4905ae9a09cfd53b3c76373d"}, - {file = "websockets-13.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:372f46a0096cfda23c88f7e42349a33f8375e10912f712e6b496d3a9a557290f"}, - {file = "websockets-13.0-cp311-cp311-win32.whl", hash = "sha256:376a43a4fd96725f13450d3d2e98f4f36c3525c562ab53d9a98dd2950dca9a8a"}, - {file = "websockets-13.0-cp311-cp311-win_amd64.whl", hash = "sha256:2be1382a4daa61e2f3e2be3b3c86932a8db9d1f85297feb6e9df22f391f94452"}, - {file = "websockets-13.0-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:b5407c34776b9b77bd89a5f95eb0a34aaf91889e3f911c63f13035220eb50107"}, - {file = "websockets-13.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:4782ec789f059f888c1e8fdf94383d0e64b531cffebbf26dd55afd53ab487ca4"}, - {file = "websockets-13.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:c8feb8e19ef65c9994e652c5b0324abd657bedd0abeb946fb4f5163012c1e730"}, - {file = "websockets-13.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d3f3d2e20c442b58dbac593cb1e02bc02d149a86056cc4126d977ad902472e3b"}, - {file = "websockets-13.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e39d393e0ab5b8bd01717cc26f2922026050188947ff54fe6a49dc489f7750b7"}, - {file = "websockets-13.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1f661a4205741bdc88ac9c2b2ec003c72cee97e4acd156eb733662ff004ba429"}, - {file = "websockets-13.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:384129ad0490e06bab2b98c1da9b488acb35bb11e2464c728376c6f55f0d45f3"}, - {file = "websockets-13.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:df5c0eff91f61b8205a6c9f7b255ff390cdb77b61c7b41f79ca10afcbb22b6cb"}, - {file = "websockets-13.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:02cc9bb1a887dac0e08bf657c5d00aa3fac0d03215d35a599130c2034ae6663a"}, - {file = "websockets-13.0-cp312-cp312-win32.whl", hash = "sha256:d9726d2c9bd6aed8cb994d89b3910ca0079406edce3670886ec828a73e7bdd53"}, - {file = "websockets-13.0-cp312-cp312-win_amd64.whl", hash = "sha256:fa0839f35322f7b038d8adcf679e2698c3a483688cc92e3bd15ee4fb06669e9a"}, - {file = "websockets-13.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:da7e501e59857e8e3e9d10586139dc196b80445a591451ca9998aafba1af5278"}, - {file = "websockets-13.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:a00e1e587c655749afb5b135d8d3edcfe84ec6db864201e40a882e64168610b3"}, - {file = "websockets-13.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:a7fbf2a8fe7556a8f4e68cb3e736884af7bf93653e79f6219f17ebb75e97d8f0"}, - {file = "websockets-13.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7ea9c9c7443a97ea4d84d3e4d42d0e8c4235834edae652993abcd2aff94affd7"}, - {file = "websockets-13.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:35c2221b539b360203f3f9ad168e527bf16d903e385068ae842c186efb13d0ea"}, - {file = "websockets-13.0-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:358d37c5c431dd050ffb06b4b075505aae3f4f795d7fff9794e5ed96ce99b998"}, - {file = "websockets-13.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:038e7a0f1bfafc7bf52915ab3506b7a03d1e06381e9f60440c856e8918138151"}, - {file = "websockets-13.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:fd038bc9e2c134847f1e0ce3191797fad110756e690c2fdd9702ed34e7a43abb"}, - {file = "websockets-13.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:93b8c2008f372379fb6e5d2b3f7c9ec32f7b80316543fd3a5ace6610c5cde1b0"}, - {file = "websockets-13.0-cp313-cp313-win32.whl", hash = "sha256:851fd0afb3bc0b73f7c5b5858975d42769a5fdde5314f4ef2c106aec63100687"}, - {file = "websockets-13.0-cp313-cp313-win_amd64.whl", hash = "sha256:7d14901fdcf212804970c30ab9ee8f3f0212e620c7ea93079d6534863444fb4e"}, - {file = "websockets-13.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:ae7a519a56a714f64c3445cabde9fc2fc927e7eae44f413eae187cddd9e54178"}, - {file = "websockets-13.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:5575031472ca87302aeb2ce2c2349f4c6ea978c86a9d1289bc5d16058ad4c10a"}, - {file = "websockets-13.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:9895df6cd0bfe79d09bcd1dbdc03862846f26fbd93797153de954306620c1d00"}, - {file = "websockets-13.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a4de299c947a54fca9ce1c5fd4a08eb92ffce91961becb13bd9195f7c6e71b47"}, - {file = "websockets-13.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:05c25f7b849702950b6fd0e233989bb73a0d2bc83faa3b7233313ca395205f6d"}, - {file = "websockets-13.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ede95125a30602b1691a4b1da88946bf27dae283cf30f22cd2cb8ca4b2e0d119"}, - {file = "websockets-13.0-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:addf0a16e4983280efed272d8cb3b2e05f0051755372461e7d966b80a6554e16"}, - {file = "websockets-13.0-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:06b3186e97bf9a33921fa60734d5ed90f2a9b407cce8d23c7333a0984049ef61"}, - {file = "websockets-13.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:eae368cac85adc4c7dc3b0d5f84ffcca609d658db6447387300478e44db70796"}, - {file = "websockets-13.0-cp38-cp38-win32.whl", hash = "sha256:337837ac788d955728b1ab01876d72b73da59819a3388e1c5e8e05c3999f1afa"}, - {file = "websockets-13.0-cp38-cp38-win_amd64.whl", hash = "sha256:f66e00e42f25ca7e91076366303e11c82572ca87cc5aae51e6e9c094f315ab41"}, - {file = "websockets-13.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:94c1c02721139fe9940b38d28fb15b4b782981d800d5f40f9966264fbf23dcc8"}, - {file = "websockets-13.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:bd4ba86513430513e2aa25a441bb538f6f83734dc368a2c5d18afdd39097aa33"}, - {file = "websockets-13.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:a1ab8f0e0cadc5be5f3f9fa11a663957fecbf483d434762c8dfb8aa44948944a"}, - {file = "websockets-13.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3670def5d3dfd5af6f6e2b3b243ea8f1f72d8da1ef927322f0703f85c90d9603"}, - {file = "websockets-13.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6058b6be92743358885ad6dcdecb378fde4a4c74d4dd16a089d07580c75a0e80"}, - {file = "websockets-13.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:516062a0a8ef5ecbfa4acbaec14b199fc070577834f9fe3d40800a99f92523ca"}, - {file = "websockets-13.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:da7e918d82e7bdfc6f66d31febe1b2e28a1ca3387315f918de26f5e367f61572"}, - {file = "websockets-13.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:9cc7f35dcb49a4e32db82a849fcc0714c4d4acc9d2273aded2d61f87d7f660b7"}, - {file = "websockets-13.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:f5737c53eb2c8ed8f64b50d3dafd3c1dae739f78aa495a288421ac1b3de82717"}, - {file = "websockets-13.0-cp39-cp39-win32.whl", hash = "sha256:265e1f0d3f788ce8ef99dca591a1aec5263b26083ca0934467ad9a1d1181067c"}, - {file = "websockets-13.0-cp39-cp39-win_amd64.whl", hash = "sha256:4d70c89e3d3b347a7c4d3c33f8d323f0584c9ceb69b82c2ef8a174ca84ea3d4a"}, - {file = "websockets-13.0-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:602cbd010d8c21c8475f1798b705bb18567eb189c533ab5ef568bc3033fdf417"}, - {file = "websockets-13.0-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:bf8eb5dca4f484a60f5327b044e842e0d7f7cdbf02ea6dc4a4f811259f1f1f0b"}, - {file = "websockets-13.0-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:89d795c1802d99a643bf689b277e8604c14b5af1bc0a31dade2cd7a678087212"}, - {file = "websockets-13.0-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:788bc841d250beccff67a20a5a53a15657a60111ef9c0c0a97fbdd614fae0fe2"}, - {file = "websockets-13.0-pp310-pypy310_pp73-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7334752052532c156d28b8eaf3558137e115c7871ea82adff69b6d94a7bee273"}, - {file = "websockets-13.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:e7a1963302947332c3039e3f66209ec73b1626f8a0191649e0713c391e9f5b0d"}, - {file = "websockets-13.0-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:2e1cf4e1eb84b4fd74a47688e8b0940c89a04ad9f6937afa43d468e71128cd68"}, - {file = "websockets-13.0-pp38-pypy38_pp73-macosx_11_0_arm64.whl", hash = "sha256:c026ee729c4ce55708a14b839ba35086dfae265fc12813b62d34ce33f4980c1c"}, - {file = "websockets-13.0-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f5f9d23fbbf96eefde836d9692670bfc89e2d159f456d499c5efcf6a6281c1af"}, - {file = "websockets-13.0-pp38-pypy38_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6ad684cb7efce227d756bae3e8484f2e56aa128398753b54245efdfbd1108f2c"}, - {file = "websockets-13.0-pp38-pypy38_pp73-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e1e10b3fbed7be4a59831d3a939900e50fcd34d93716e433d4193a4d0d1d335d"}, - {file = "websockets-13.0-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:d42a818e634f789350cd8fb413a3f5eec1cf0400a53d02062534c41519f5125c"}, - {file = "websockets-13.0-pp39-pypy39_pp73-macosx_10_15_x86_64.whl", hash = "sha256:e5ba5e9b332267d0f2c33ede390061850f1ac3ee6cd1bdcf4c5ea33ead971966"}, - {file = "websockets-13.0-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:f9af457ed593e35f467140d8b61d425495b127744a9d65d45a366f8678449a23"}, - {file = "websockets-13.0-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bcea3eb58c09c3a31cc83b45c06d5907f02ddaf10920aaa6443975310f699b95"}, - {file = "websockets-13.0-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c210d1460dc8d326ffdef9703c2f83269b7539a1690ad11ae04162bc1878d33d"}, - {file = "websockets-13.0-pp39-pypy39_pp73-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b32f38bc81170fd56d0482d505b556e52bf9078b36819a8ba52624bd6667e39e"}, - {file = "websockets-13.0-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:81a11a1ddd5320429db47c04d35119c3e674d215173d87aaeb06ae80f6e9031f"}, - {file = "websockets-13.0-py3-none-any.whl", hash = "sha256:dbbac01e80aee253d44c4f098ab3cc17c822518519e869b284cfbb8cd16cc9de"}, - {file = "websockets-13.0.tar.gz", hash = "sha256:b7bf950234a482b7461afdb2ec99eee3548ec4d53f418c7990bb79c620476602"}, + {file = "websockets-13.0.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:1841c9082a3ba4a05ea824cf6d99570a6a2d8849ef0db16e9c826acb28089e8f"}, + {file = "websockets-13.0.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:c5870b4a11b77e4caa3937142b650fbbc0914a3e07a0cf3131f35c0587489c1c"}, + {file = "websockets-13.0.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:f1d3d1f2eb79fe7b0fb02e599b2bf76a7619c79300fc55f0b5e2d382881d4f7f"}, + {file = "websockets-13.0.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:15c7d62ee071fa94a2fc52c2b472fed4af258d43f9030479d9c4a2de885fd543"}, + {file = "websockets-13.0.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6724b554b70d6195ba19650fef5759ef11346f946c07dbbe390e039bcaa7cc3d"}, + {file = "websockets-13.0.1-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:56a952fa2ae57a42ba7951e6b2605e08a24801a4931b5644dfc68939e041bc7f"}, + {file = "websockets-13.0.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:17118647c0ea14796364299e942c330d72acc4b248e07e639d34b75067b3cdd8"}, + {file = "websockets-13.0.1-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:64a11aae1de4c178fa653b07d90f2fb1a2ed31919a5ea2361a38760192e1858b"}, + {file = "websockets-13.0.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:0617fd0b1d14309c7eab6ba5deae8a7179959861846cbc5cb528a7531c249448"}, + {file = "websockets-13.0.1-cp310-cp310-win32.whl", hash = "sha256:11f9976ecbc530248cf162e359a92f37b7b282de88d1d194f2167b5e7ad80ce3"}, + {file = "websockets-13.0.1-cp310-cp310-win_amd64.whl", hash = "sha256:c3c493d0e5141ec055a7d6809a28ac2b88d5b878bb22df8c621ebe79a61123d0"}, + {file = "websockets-13.0.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:699ba9dd6a926f82a277063603fc8d586b89f4cb128efc353b749b641fcddda7"}, + {file = "websockets-13.0.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:cf2fae6d85e5dc384bf846f8243ddaa9197f3a1a70044f59399af001fd1f51d4"}, + {file = "websockets-13.0.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:52aed6ef21a0f1a2a5e310fb5c42d7555e9c5855476bbd7173c3aa3d8a0302f2"}, + {file = "websockets-13.0.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8eb2b9a318542153674c6e377eb8cb9ca0fc011c04475110d3477862f15d29f0"}, + {file = "websockets-13.0.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5df891c86fe68b2c38da55b7aea7095beca105933c697d719f3f45f4220a5e0e"}, + {file = "websockets-13.0.1-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fac2d146ff30d9dd2fcf917e5d147db037a5c573f0446c564f16f1f94cf87462"}, + {file = "websockets-13.0.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:b8ac5b46fd798bbbf2ac6620e0437c36a202b08e1f827832c4bf050da081b501"}, + {file = "websockets-13.0.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:46af561eba6f9b0848b2c9d2427086cabadf14e0abdd9fde9d72d447df268418"}, + {file = "websockets-13.0.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:b5a06d7f60bc2fc378a333978470dfc4e1415ee52f5f0fce4f7853eb10c1e9df"}, + {file = "websockets-13.0.1-cp311-cp311-win32.whl", hash = "sha256:556e70e4f69be1082e6ef26dcb70efcd08d1850f5d6c5f4f2bcb4e397e68f01f"}, + {file = "websockets-13.0.1-cp311-cp311-win_amd64.whl", hash = "sha256:67494e95d6565bf395476e9d040037ff69c8b3fa356a886b21d8422ad86ae075"}, + {file = "websockets-13.0.1-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:f9c9e258e3d5efe199ec23903f5da0eeaad58cf6fccb3547b74fd4750e5ac47a"}, + {file = "websockets-13.0.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:6b41a1b3b561f1cba8321fb32987552a024a8f67f0d05f06fcf29f0090a1b956"}, + {file = "websockets-13.0.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:f73e676a46b0fe9426612ce8caeca54c9073191a77c3e9d5c94697aef99296af"}, + {file = "websockets-13.0.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1f613289f4a94142f914aafad6c6c87903de78eae1e140fa769a7385fb232fdf"}, + {file = "websockets-13.0.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0f52504023b1480d458adf496dc1c9e9811df4ba4752f0bc1f89ae92f4f07d0c"}, + {file = "websockets-13.0.1-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:139add0f98206cb74109faf3611b7783ceafc928529c62b389917a037d4cfdf4"}, + {file = "websockets-13.0.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:47236c13be337ef36546004ce8c5580f4b1150d9538b27bf8a5ad8edf23ccfab"}, + {file = "websockets-13.0.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:c44ca9ade59b2e376612df34e837013e2b273e6c92d7ed6636d0556b6f4db93d"}, + {file = "websockets-13.0.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:9bbc525f4be3e51b89b2a700f5746c2a6907d2e2ef4513a8daafc98198b92237"}, + {file = "websockets-13.0.1-cp312-cp312-win32.whl", hash = "sha256:3624fd8664f2577cf8de996db3250662e259bfbc870dd8ebdcf5d7c6ac0b5185"}, + {file = "websockets-13.0.1-cp312-cp312-win_amd64.whl", hash = "sha256:0513c727fb8adffa6d9bf4a4463b2bade0186cbd8c3604ae5540fae18a90cb99"}, + {file = "websockets-13.0.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:1ee4cc030a4bdab482a37462dbf3ffb7e09334d01dd37d1063be1136a0d825fa"}, + {file = "websockets-13.0.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:dbb0b697cc0655719522406c059eae233abaa3243821cfdfab1215d02ac10231"}, + {file = "websockets-13.0.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:acbebec8cb3d4df6e2488fbf34702cbc37fc39ac7abf9449392cefb3305562e9"}, + {file = "websockets-13.0.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:63848cdb6fcc0bf09d4a155464c46c64ffdb5807ede4fb251da2c2692559ce75"}, + {file = "websockets-13.0.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:872afa52a9f4c414d6955c365b6588bc4401272c629ff8321a55f44e3f62b553"}, + {file = "websockets-13.0.1-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:05e70fec7c54aad4d71eae8e8cab50525e899791fc389ec6f77b95312e4e9920"}, + {file = "websockets-13.0.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:e82db3756ccb66266504f5a3de05ac6b32f287faacff72462612120074103329"}, + {file = "websockets-13.0.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:4e85f46ce287f5c52438bb3703d86162263afccf034a5ef13dbe4318e98d86e7"}, + {file = "websockets-13.0.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:f3fea72e4e6edb983908f0db373ae0732b275628901d909c382aae3b592589f2"}, + {file = "websockets-13.0.1-cp313-cp313-win32.whl", hash = "sha256:254ecf35572fca01a9f789a1d0f543898e222f7b69ecd7d5381d8d8047627bdb"}, + {file = "websockets-13.0.1-cp313-cp313-win_amd64.whl", hash = "sha256:ca48914cdd9f2ccd94deab5bcb5ac98025a5ddce98881e5cce762854a5de330b"}, + {file = "websockets-13.0.1-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:b74593e9acf18ea5469c3edaa6b27fa7ecf97b30e9dabd5a94c4c940637ab96e"}, + {file = "websockets-13.0.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:132511bfd42e77d152c919147078460c88a795af16b50e42a0bd14f0ad71ddd2"}, + {file = "websockets-13.0.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:165bedf13556f985a2aa064309baa01462aa79bf6112fbd068ae38993a0e1f1b"}, + {file = "websockets-13.0.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e801ca2f448850685417d723ec70298feff3ce4ff687c6f20922c7474b4746ae"}, + {file = "websockets-13.0.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:30d3a1f041360f029765d8704eae606781e673e8918e6b2c792e0775de51352f"}, + {file = "websockets-13.0.1-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:67648f5e50231b5a7f6d83b32f9c525e319f0ddc841be0de64f24928cd75a603"}, + {file = "websockets-13.0.1-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:4f0426d51c8f0926a4879390f53c7f5a855e42d68df95fff6032c82c888b5f36"}, + {file = "websockets-13.0.1-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:ef48e4137e8799998a343706531e656fdec6797b80efd029117edacb74b0a10a"}, + {file = "websockets-13.0.1-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:249aab278810bee585cd0d4de2f08cfd67eed4fc75bde623be163798ed4db2eb"}, + {file = "websockets-13.0.1-cp38-cp38-win32.whl", hash = "sha256:06c0a667e466fcb56a0886d924b5f29a7f0886199102f0a0e1c60a02a3751cb4"}, + {file = "websockets-13.0.1-cp38-cp38-win_amd64.whl", hash = "sha256:1f3cf6d6ec1142412d4535adabc6bd72a63f5f148c43fe559f06298bc21953c9"}, + {file = "websockets-13.0.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:1fa082ea38d5de51dd409434edc27c0dcbd5fed2b09b9be982deb6f0508d25bc"}, + {file = "websockets-13.0.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:4a365bcb7be554e6e1f9f3ed64016e67e2fa03d7b027a33e436aecf194febb63"}, + {file = "websockets-13.0.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:10a0dc7242215d794fb1918f69c6bb235f1f627aaf19e77f05336d147fce7c37"}, + {file = "websockets-13.0.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:59197afd478545b1f73367620407b0083303569c5f2d043afe5363676f2697c9"}, + {file = "websockets-13.0.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7d20516990d8ad557b5abeb48127b8b779b0b7e6771a265fa3e91767596d7d97"}, + {file = "websockets-13.0.1-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a1a2e272d067030048e1fe41aa1ec8cfbbaabce733b3d634304fa2b19e5c897f"}, + {file = "websockets-13.0.1-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:ad327ac80ba7ee61da85383ca8822ff808ab5ada0e4a030d66703cc025b021c4"}, + {file = "websockets-13.0.1-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:518f90e6dd089d34eaade01101fd8a990921c3ba18ebbe9b0165b46ebff947f0"}, + {file = "websockets-13.0.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:68264802399aed6fe9652e89761031acc734fc4c653137a5911c2bfa995d6d6d"}, + {file = "websockets-13.0.1-cp39-cp39-win32.whl", hash = "sha256:a5dc0c42ded1557cc7c3f0240b24129aefbad88af4f09346164349391dea8e58"}, + {file = "websockets-13.0.1-cp39-cp39-win_amd64.whl", hash = "sha256:b448a0690ef43db5ef31b3a0d9aea79043882b4632cfc3eaab20105edecf6097"}, + {file = "websockets-13.0.1-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:faef9ec6354fe4f9a2c0bbb52fb1ff852effc897e2a4501e25eb3a47cb0a4f89"}, + {file = "websockets-13.0.1-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:03d3f9ba172e0a53e37fa4e636b86cc60c3ab2cfee4935e66ed1d7acaa4625ad"}, + {file = "websockets-13.0.1-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d450f5a7a35662a9b91a64aefa852f0c0308ee256122f5218a42f1d13577d71e"}, + {file = "websockets-13.0.1-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3f55b36d17ac50aa8a171b771e15fbe1561217510c8768af3d546f56c7576cdc"}, + {file = "websockets-13.0.1-pp310-pypy310_pp73-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:14b9c006cac63772b31abbcd3e3abb6228233eec966bf062e89e7fa7ae0b7333"}, + {file = "websockets-13.0.1-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:b79915a1179a91f6c5f04ece1e592e2e8a6bd245a0e45d12fd56b2b59e559a32"}, + {file = "websockets-13.0.1-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:f40de079779acbcdbb6ed4c65af9f018f8b77c5ec4e17a4b737c05c2db554491"}, + {file = "websockets-13.0.1-pp38-pypy38_pp73-macosx_11_0_arm64.whl", hash = "sha256:80e4ba642fc87fa532bac07e5ed7e19d56940b6af6a8c61d4429be48718a380f"}, + {file = "websockets-13.0.1-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2a02b0161c43cc9e0232711eff846569fad6ec836a7acab16b3cf97b2344c060"}, + {file = "websockets-13.0.1-pp38-pypy38_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6aa74a45d4cdc028561a7d6ab3272c8b3018e23723100b12e58be9dfa5a24491"}, + {file = "websockets-13.0.1-pp38-pypy38_pp73-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:00fd961943b6c10ee6f0b1130753e50ac5dcd906130dcd77b0003c3ab797d026"}, + {file = "websockets-13.0.1-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:d93572720d781331fb10d3da9ca1067817d84ad1e7c31466e9f5e59965618096"}, + {file = "websockets-13.0.1-pp39-pypy39_pp73-macosx_10_15_x86_64.whl", hash = "sha256:71e6e5a3a3728886caee9ab8752e8113670936a193284be9d6ad2176a137f376"}, + {file = "websockets-13.0.1-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:c4a6343e3b0714e80da0b0893543bf9a5b5fa71b846ae640e56e9abc6fbc4c83"}, + {file = "websockets-13.0.1-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1a678532018e435396e37422a95e3ab87f75028ac79570ad11f5bf23cd2a7d8c"}, + {file = "websockets-13.0.1-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d6716c087e4aa0b9260c4e579bb82e068f84faddb9bfba9906cb87726fa2e870"}, + {file = "websockets-13.0.1-pp39-pypy39_pp73-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e33505534f3f673270dd67f81e73550b11de5b538c56fe04435d63c02c3f26b5"}, + {file = "websockets-13.0.1-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:acab3539a027a85d568c2573291e864333ec9d912675107d6efceb7e2be5d980"}, + {file = "websockets-13.0.1-py3-none-any.whl", hash = "sha256:b80f0c51681c517604152eb6a572f5a9378f877763231fddb883ba2f968e8817"}, + {file = "websockets-13.0.1.tar.gz", hash = "sha256:4d6ece65099411cfd9a48d13701d7438d9c34f479046b34c50ff60bb8834e43e"}, ] [[package]] From 091673f56e4858e9debaa6dc7065be1fc7316cbb Mon Sep 17 00:00:00 2001 From: Niels Date: Mon, 2 Sep 2024 18:26:53 +0200 Subject: [PATCH 23/44] Add docker-compose to workflow --- .github/workflows/main.yml | 3 +++ .gitignore | 1 + 2 files changed, 4 insertions(+) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index c8317c28..052daeae 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -59,6 +59,9 @@ jobs: python-version: ${{ matrix.python-version }} cache: 'poetry' + - name: Setup docker-compose + uses: KengoTODA/actions-setup-docker-compose@v1.2.2 + - name: Run integration tests run: | cd integration-test && ./run_tests.sh diff --git a/.gitignore b/.gitignore index b5e58dea..58d8bd11 100644 --- a/.gitignore +++ b/.gitignore @@ -3,6 +3,7 @@ cov_html docs/build dist +.mypy_cache # IDE .idea From a8f5ce0d990578cd3f74953f2d299cc932d77dc8 Mon Sep 17 00:00:00 2001 From: Niels Date: Mon, 2 Sep 2024 18:29:27 +0200 Subject: [PATCH 24/44] Fix docker-compose version --- .github/workflows/main.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 052daeae..733ceecf 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -61,6 +61,8 @@ jobs: - name: Setup docker-compose uses: KengoTODA/actions-setup-docker-compose@v1.2.2 + with: + version: '2.14.2' - name: Run integration tests run: | From b829608e13809e569fa27bc6c5f8f478dbfc7b31 Mon Sep 17 00:00:00 2001 From: Niels Date: Mon, 2 Sep 2024 18:33:57 +0200 Subject: [PATCH 25/44] Use v6 chain context from pycardano itself --- integration-test/test/base.py | 3 +-- pycardano/backend/__init__.py | 1 + 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/integration-test/test/base.py b/integration-test/test/base.py index 24e56c36..794962df 100644 --- a/integration-test/test/base.py +++ b/integration-test/test/base.py @@ -2,7 +2,6 @@ import os -import ogmios as python_ogmios from retry import retry from pycardano import * @@ -22,7 +21,7 @@ class TestBase: # TODO: Bring back kupo test KUPO_URL = "http://localhost:1442" - chain_context = python_ogmios.OgmiosV5ChainContext( + chain_context = OgmiosV6ChainContext( host="localhost", port=1337, network=Network.TESTNET ) diff --git a/pycardano/backend/__init__.py b/pycardano/backend/__init__.py index 5c10a07a..617d36c1 100644 --- a/pycardano/backend/__init__.py +++ b/pycardano/backend/__init__.py @@ -4,3 +4,4 @@ from .blockfrost import * from .cardano_cli import * from .ogmios_v5 import * +from .ogmios_v6 import * From b0eb69cd456cf1d4d446b7748e2b15943d3fc9f3 Mon Sep 17 00:00:00 2001 From: Niels Date: Mon, 2 Sep 2024 18:48:44 +0200 Subject: [PATCH 26/44] Fix --- pycardano/backend/ogmios_v6.py | 86 ++++++++++++++++++---------------- 1 file changed, 46 insertions(+), 40 deletions(-) diff --git a/pycardano/backend/ogmios_v6.py b/pycardano/backend/ogmios_v6.py index 0e07680e..0e9e6d22 100644 --- a/pycardano/backend/ogmios_v6.py +++ b/pycardano/backend/ogmios_v6.py @@ -2,21 +2,22 @@ from typing import Optional, Union, Dict, List from cachetools import Cache, LRUCache, TTLCache, func -from ogmios.client import Client +from ogmios.client import Client as OgmiosClient from ogmios.datatypes import ( - ProtocolParameters, - Era, - Tip, - Utxo, - Address, - TxOutputReference, + ProtocolParameters as OgmiosProtocolParameters, + Era as OgmiosEra, + Tip as OgmiosTip, + Utxo as OgmiosUtxo, + Address as OgmiosAddress, + TxOutputReference as OgmiosTxOutputReference, ) -from ogmios.utils import get_current_era, GenesisParameters +from ogmios.utils import get_current_era, GenesisParameters as OgmiosGenesisParameters from pycardano.backend.kupo import KupoChainContextExtension from pycardano.backend.base import ( ChainContext, - ProtocolParameters as pycProtocolParameters, + ProtocolParameters, + GenesisParameters, ) from pycardano.network import Network from pycardano.transaction import ( @@ -27,7 +28,7 @@ MultiAsset, AssetName, Asset, - Address as pyc_Address, + Address, ) from pycardano.plutus import ( PLUTUS_V1_COST_MODEL, @@ -47,12 +48,12 @@ class OgmiosV6ChainContext(ChainContext): """Ogmios chain context for use with PyCardano""" _network: Network - _client: Client + _client: OgmiosClient _service_name: str _last_known_block_slot: int _last_chain_tip_fetch: float _genesis_param: Optional[GenesisParameters] - _protocol_param: Optional[ProtocolParameters] + _protocol_param: Optional[OgmiosProtocolParameters] _utxo_cache: Cache _datum_cache: Cache @@ -86,28 +87,30 @@ def __init__( ) self._datum_cache = LRUCache(maxsize=datum_cache_size) - def _query_current_era(self) -> Era: - with Client(self.host, self.port, self.secure) as client: + def _query_current_era(self) -> OgmiosEra: + with OgmiosClient(self.host, self.port, self.secure) as client: return get_current_era(client) def _query_current_epoch(self) -> int: - with Client(self.host, self.port, self.secure) as client: + with OgmiosClient(self.host, self.port, self.secure) as client: epoch, _ = client.query_epoch.execute() return epoch - def _query_chain_tip(self) -> Tip: - with Client(self.host, self.port, self.secure) as client: + def _query_chain_tip(self) -> OgmiosTip: + with OgmiosClient(self.host, self.port, self.secure) as client: tip, _ = client.query_network_tip.execute() return tip - def _query_utxos_by_address(self, address: pyc_Address) -> List[Utxo]: - with Client(self.host, self.port, self.secure) as client: + def _query_utxos_by_address(self, address: Address) -> List[OgmiosUtxo]: + with OgmiosClient(self.host, self.port, self.secure) as client: utxos, _ = client.query_utxo.execute([address]) return utxos - def _query_utxos_by_tx_id(self, tx_id: str, index: int) -> List[Utxo]: - with Client(self.host, self.port, self.secure) as client: - utxos, _ = client.query_utxo.execute([TxOutputReference(tx_id, index)]) + def _query_utxos_by_tx_id(self, tx_id: str, index: int) -> List[OgmiosUtxo]: + with OgmiosClient(self.host, self.port, self.secure) as client: + utxos, _ = client.query_utxo.execute( + [OgmiosTxOutputReference(tx_id, index)] + ) return utxos def _is_chain_tip_updated(self): @@ -128,15 +131,15 @@ def _fraction_parser(fraction: str) -> float: return int(x) / int(y) @property - def protocol_param(self) -> pycProtocolParameters: + def protocol_param(self) -> ProtocolParameters: if not self._protocol_param or self._is_chain_tip_updated(): self._protocol_param = self._fetch_protocol_param() return self._protocol_param def _fetch_protocol_param(self) -> ProtocolParameters: - with Client(self.host, self.port, self.secure) as client: + with OgmiosClient(self.host, self.port, self.secure) as client: protocol_parameters, _ = client.query_protocol_parameters.execute() - pyc_protocol_params = pycProtocolParameters( + pyc_protocol_params = ProtocolParameters( min_fee_constant=protocol_parameters.min_fee_constant.lovelace, min_fee_coefficient=protocol_parameters.min_fee_coefficient, min_pool_cost=protocol_parameters.min_stake_pool_cost.lovelace, @@ -185,22 +188,25 @@ def _fetch_protocol_param(self) -> ProtocolParameters: @property def genesis_param(self) -> GenesisParameters: if not self._genesis_param or self._is_chain_tip_updated(): - self._genesis_param = self._fetch_genesis_param() + # TODO transform to PyCardano GenesisParameters? + self._genesis_param = self._fetch_genesis_param() # type: ignore[assignment] # Update the refetch interval if we haven't calculated it yet if ( self._refetch_chain_tip_interval == DEFAULT_REFETCH_INTERVAL + and self._genesis_param is not None and self._genesis_param.slot_length is not None and self._genesis_param.active_slots_coefficient is not None ): - self._refetch_chain_tip_interval = self._genesis_param.slot_length.get( - "milliseconds" - ) / eval(self._genesis_param.active_slots_coefficient) - return self._genesis_param + self._refetch_chain_tip_interval = ( + self._genesis_param.slot_length + / float(self._genesis_param.active_slots_coefficient) + ) + return self._genesis_param # type: ignore[return-value] - def _fetch_genesis_param(self) -> GenesisParameters: - with Client(self.host, self.port, self.secure) as client: - return GenesisParameters(client, self._query_current_era()) + def _fetch_genesis_param(self) -> OgmiosGenesisParameters: + with OgmiosClient(self.host, self.port, self.secure) as client: + return OgmiosGenesisParameters(client, self._query_current_era()) @property def network(self) -> Network: @@ -221,7 +227,7 @@ def _utxos(self, address: str) -> List[UTxO]: if key in self._utxo_cache: return self._utxo_cache[key] - utxos = self._utxos_ogmios(Address(address=address)) + utxos = self._utxos_ogmios(OgmiosAddress(address=address)) self._utxo_cache[key] = utxos @@ -231,7 +237,7 @@ def _check_utxo_unspent(self, tx_id: str, index: int) -> bool: results = self._query_utxos_by_tx_id(tx_id, index) return len(results) > 0 - def _utxos_ogmios(self, address: pyc_Address) -> List[Utxo]: + def _utxos_ogmios(self, address: Address) -> List[OgmiosUtxo]: """Get all UTxOs associated with an address with Ogmios. Args: @@ -248,7 +254,7 @@ def _utxos_ogmios(self, address: pyc_Address) -> List[Utxo]: return utxos - def _utxo_from_ogmios_result(self, utxo: Utxo) -> UTxO: + def _utxo_from_ogmios_result(self, utxo: OgmiosUtxo) -> UTxO: """Convert an Ogmios UTxO result to a PyCardano UTxO.""" tx_in = TransactionInput.from_primitive([utxo.tx_id, utxo.index]) lovelace_amount = utxo.value.get("ada").get("lovelace", 0) @@ -269,7 +275,7 @@ def _utxo_from_ogmios_result(self, utxo: Utxo) -> UTxO: datum = RawCBOR(bytes.fromhex(utxo.datum)) if set(utxo.value.keys()) == {"ada"}: tx_out = TransactionOutput( - pyc_Address.from_primitive(utxo.address), + Address.from_primitive(utxo.address), amount=lovelace_amount, datum_hash=datum_hash, datum=datum, @@ -285,7 +291,7 @@ def _utxo_from_ogmios_result(self, utxo: Utxo) -> UTxO: multi_assets.setdefault(policy, Asset())[token_name] = quantity tx_out = TransactionOutput( - pyc_Address.from_primitive(utxo.address), + Address.from_primitive(utxo.address), amount=Value(lovelace_amount, multi_assets), datum_hash=datum_hash, datum=datum, @@ -303,13 +309,13 @@ def utxo_by_tx_id(self, tx_id: str, index: int) -> Optional[UTxO]: def submit_tx_cbor(self, cbor: Union[bytes, str]): if isinstance(cbor, bytes): cbor = cbor.hex() - with Client(self.host, self.port, self.secure) as client: + with OgmiosClient(self.host, self.port, self.secure) as client: client.submit_transaction.execute(cbor) def evaluate_tx_cbor(self, cbor: Union[bytes, str]) -> Dict[str, ExecutionUnits]: if isinstance(cbor, bytes): cbor = cbor.hex() - with Client(self.host, self.port, self.secure) as client: + with OgmiosClient(self.host, self.port, self.secure) as client: result, _ = client.evaluate_transaction.execute(cbor) result_dict = {} for res in result: From 94be3e39e337e6164cacf3f4ced82a502420319f Mon Sep 17 00:00:00 2001 From: Niels Date: Mon, 2 Sep 2024 20:44:31 +0200 Subject: [PATCH 27/44] Add PlutusV3 in a few places --- pycardano/backend/blockfrost.py | 19 +++++++++++++++---- pycardano/backend/kupo.py | 12 ++++++++++-- 2 files changed, 25 insertions(+), 6 deletions(-) diff --git a/pycardano/backend/blockfrost.py b/pycardano/backend/blockfrost.py index 40c9ccc7..2bd9f629 100644 --- a/pycardano/backend/blockfrost.py +++ b/pycardano/backend/blockfrost.py @@ -20,7 +20,13 @@ from pycardano.hash import SCRIPT_HASH_SIZE, DatumHash, ScriptHash from pycardano.nativescript import NativeScript from pycardano.network import Network -from pycardano.plutus import ExecutionUnits, PlutusV1Script, PlutusV2Script, script_hash +from pycardano.plutus import ( + ExecutionUnits, + PlutusV1Script, + PlutusV2Script, + script_hash, + PlutusV3Script, +) from pycardano.serialization import RawCBOR from pycardano.transaction import ( Asset, @@ -37,8 +43,8 @@ def _try_fix_script( - scripth: str, script: Union[PlutusV1Script, PlutusV2Script] -) -> Union[PlutusV1Script, PlutusV2Script]: + scripth: str, script: Union[PlutusV1Script, PlutusV2Script, PlutusV3Script] +) -> Union[PlutusV1Script, PlutusV2Script, PlutusV3Script]: if str(script_hash(script)) == scripth: return script else: @@ -170,7 +176,7 @@ def protocol_param(self) -> ProtocolParameters: def _get_script( self, script_hash: str - ) -> Union[PlutusV1Script, PlutusV2Script, NativeScript]: + ) -> Union[PlutusV1Script, PlutusV2Script, PlutusV3Script, NativeScript]: script_type = self.api.script(script_hash).type if script_type == "plutusV1": v1script = PlutusV1Script( @@ -182,6 +188,11 @@ def _get_script( bytes.fromhex(self.api.script_cbor(script_hash).cbor) ) return _try_fix_script(script_hash, v2script) + elif script_type == "plutusV3": + v3script = PlutusV3Script( + bytes.fromhex(self.api.script_cbor(script_hash).cbor) + ) + return _try_fix_script(script_hash, v3script) else: script_json: JsonDict = self.api.script_json( script_hash, return_type="json" diff --git a/pycardano/backend/kupo.py b/pycardano/backend/kupo.py index f4fa5078..36fa409e 100644 --- a/pycardano/backend/kupo.py +++ b/pycardano/backend/kupo.py @@ -8,7 +8,12 @@ from pycardano.backend.blockfrost import _try_fix_script from pycardano.hash import DatumHash, ScriptHash from pycardano.network import Network -from pycardano.plutus import ExecutionUnits, PlutusV1Script, PlutusV2Script +from pycardano.plutus import ( + ExecutionUnits, + PlutusV1Script, + PlutusV2Script, + PlutusV3Script, +) from pycardano.serialization import RawCBOR from pycardano.transaction import ( Asset, @@ -172,7 +177,10 @@ def _utxos_kupo(self, address: str) -> List[UTxO]: if script_hash: kupo_script_url = self._kupo_url + "/scripts/" + script_hash script = requests.get(kupo_script_url).json() - if script["language"] == "plutus:v2": + if script["language"] == "plutus:v3": + script = PlutusV3Script(bytes.fromhex(script["script"])) + script = _try_fix_script(script_hash, script) + elif script["language"] == "plutus:v2": script = PlutusV2Script(bytes.fromhex(script["script"])) script = _try_fix_script(script_hash, script) elif script["language"] == "plutus:v1": From 37d71e3eeb482249fbb1b0ea9b208ac65203f80a Mon Sep 17 00:00:00 2001 From: Niels Date: Mon, 2 Sep 2024 21:06:24 +0200 Subject: [PATCH 28/44] Combine coverages --- .github/workflows/main.yml | 7 +++++++ .gitignore | 1 + integration-test/run_tests.sh | 2 +- 3 files changed, 9 insertions(+), 1 deletion(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 8b0e73f0..ca083162 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -68,6 +68,13 @@ jobs: run: | cd integration-test && ./run_tests.sh + - name: "Upload coverage to Codecov" + if: ${{ matrix.python-version == '3.11' }} + uses: codecov/codecov-action@v4 + with: + fail_ci_if_error: true + token: ${{ secrets.CODECOV_TOKEN }} + - name: Dump docker logs if: failure() run: | diff --git a/.gitignore b/.gitignore index 58d8bd11..c14a0292 100644 --- a/.gitignore +++ b/.gitignore @@ -4,6 +4,7 @@ cov_html docs/build dist .mypy_cache +coverage.xml # IDE .idea diff --git a/integration-test/run_tests.sh b/integration-test/run_tests.sh index 82790b4f..906eb979 100755 --- a/integration-test/run_tests.sh +++ b/integration-test/run_tests.sh @@ -77,7 +77,7 @@ export POOL_ID=$(cat "$ROOT"/keys/pool/pool.id) # Wait for stake pool to start producing blocks sleep 30 -poetry run pytest -m "not (CardanoCLI)" -s -vv -n 4 "$ROOT"/test +poetry run pytest -m "not (CardanoCLI)" -s -vv -n 4 "$ROOT"/test --cov=pycardano --cov-config=../.coveragerc --cov-report=xml:../coverage.xml # Cleanup docker compose -f docker-compose-chang.yml down --volumes --remove-orphans \ No newline at end of file From 7243cd9e6e91caa8175898fcc870d3669e3af8ca Mon Sep 17 00:00:00 2001 From: Jerry Date: Mon, 2 Sep 2024 17:38:43 -0700 Subject: [PATCH 29/44] Support redeemer map --- pycardano/backend/blockfrost.py | 2 +- pycardano/plutus.py | 58 ++++++++++++++++++++++++- pycardano/txbuilder.py | 50 +++++++++++++++++----- pycardano/utils.py | 6 +-- pycardano/witness.py | 5 ++- test/pycardano/test_plutus.py | 64 ++++++++++++++++++++++++++++ test/pycardano/test_txbuilder.py | 73 ++++++++++++++++++++++++++++---- 7 files changed, 232 insertions(+), 26 deletions(-) diff --git a/pycardano/backend/blockfrost.py b/pycardano/backend/blockfrost.py index 2bd9f629..a1287f4e 100644 --- a/pycardano/backend/blockfrost.py +++ b/pycardano/backend/blockfrost.py @@ -24,8 +24,8 @@ ExecutionUnits, PlutusV1Script, PlutusV2Script, - script_hash, PlutusV3Script, + script_hash, ) from pycardano.serialization import RawCBOR from pycardano.transaction import ( diff --git a/pycardano/plutus.py b/pycardano/plutus.py index 700b49d5..87172c63 100644 --- a/pycardano/plutus.py +++ b/pycardano/plutus.py @@ -8,12 +8,13 @@ from dataclasses import dataclass, field, fields from enum import Enum from hashlib import sha256 -from typing import Any, Optional, Type, Union +from typing import Any, List, Optional, Type, Union import cbor2 from cbor2 import CBORTag from nacl.encoding import RawEncoder from nacl.hash import blake2b +from typeguard import typechecked from pycardano.exception import DeserializeException, InvalidArgumentException from pycardano.hash import DATUM_HASH_SIZE, SCRIPT_HASH_SIZE, DatumHash, ScriptHash @@ -44,6 +45,10 @@ "PlutusV3Script", "RawPlutusData", "Redeemer", + "RedeemerKey", + "RedeemerValue", + "RedeemerMap", + "Redeemers", "ScriptType", "datum_hash", "plutus_script_hash", @@ -993,6 +998,57 @@ def from_primitive(cls: Type[Redeemer], values: list) -> Redeemer: return redeemer +@dataclass(repr=False) +class RedeemerKey(ArrayCBORSerializable): + tag: RedeemerTag + + index: int = field(default=0) + + @classmethod + @limit_primitive_type(list, tuple) + def from_primitive(cls: Type[RedeemerKey], values: list) -> RedeemerKey: + tag = RedeemerTag.from_primitive(values[0]) + index = values[1] + return cls(tag, index) + + def __eq__(self, other): + if not isinstance(other, RedeemerKey): + return False + return self.tag == other.tag and self.index == other.index + + def __hash__(self): + return hash(self.to_cbor()) + + +@dataclass(repr=False) +class RedeemerValue(ArrayCBORSerializable): + data: Any + + ex_units: ExecutionUnits + + @classmethod + @limit_primitive_type(list) + def from_primitive(cls: Type[RedeemerValue], values: list) -> RedeemerValue: + if isinstance(values[0], CBORTag) and cls is RedeemerValue: + values[0] = RawPlutusData.from_primitive(values[0]) + return super(RedeemerValue, cls).from_primitive([values[0], values[1]]) + + def __eq__(self, other): + if not isinstance(other, RedeemerValue): + return False + return self.data == other.data and self.ex_units == other.ex_units + + +@typechecked +class RedeemerMap(DictCBORSerializable): + KEY_TYPE = RedeemerKey + + VALUE_TYPE = RedeemerValue + + +Redeemers = Union[List[Redeemer], RedeemerMap] + + def plutus_script_hash( script: Union[bytes, PlutusV1Script, PlutusV2Script] ) -> ScriptHash: diff --git a/pycardano/txbuilder.py b/pycardano/txbuilder.py index 13cbd119..7ff0be3d 100644 --- a/pycardano/txbuilder.py +++ b/pycardano/txbuilder.py @@ -4,6 +4,7 @@ from dataclasses import dataclass, field, fields from typing import Dict, List, Optional, Set, Tuple, Union +from pycardano import RedeemerMap from pycardano.address import Address, AddressType from pycardano.backend.base import ChainContext from pycardano.certificate import ( @@ -42,7 +43,10 @@ PlutusV2Script, PlutusV3Script, Redeemer, + RedeemerKey, + Redeemers, RedeemerTag, + RedeemerValue, ScriptType, datum_hash, script_hash, @@ -186,7 +190,7 @@ def _consolidate_redeemer(self, redeemer): raise InvalidArgumentException( f"All redeemers need to provide execution units if the firstly " f"added redeemer specifies execution units. \n" - f"Added redeemers: {self.redeemers} \n" + f"Added redeemers: {self._redeemer_list} \n" f"New redeemer: {redeemer}" ) if self._should_estimate_execution_units: @@ -194,7 +198,7 @@ def _consolidate_redeemer(self, redeemer): raise InvalidArgumentException( f"No redeemer should provide execution units if the firstly " f"added redeemer didn't provide execution units. \n" - f"Added redeemers: {self.redeemers} \n" + f"Added redeemers: {self._redeemer_list} \n" f"New redeemer: {redeemer}" ) else: @@ -485,16 +489,32 @@ def datums(self) -> Dict[DatumHash, Datum]: return self._datums @property - def redeemers(self) -> List[Redeemer]: + def _redeemer_list(self) -> List[Redeemer]: return ( [r for r in self._inputs_to_redeemers.values() if r is not None] + [r for _, r in self._minting_script_to_redeemers if r is not None] + [r for _, r in self._withdrawal_script_to_redeemers if r is not None] ) + def redeemers(self) -> RedeemerMap: + redeemers = RedeemerMap() + for r in self._redeemer_list: + if r.tag is None: + raise InvalidArgumentException( + f"Redeemer tag is not set. Redeemer: {r}" + ) + if r.ex_units is None: + raise InvalidArgumentException( + f"Execution units are not set. Redeemer: {r}" + ) + k = RedeemerKey(r.tag, r.index) + v = RedeemerValue(r.data, r.ex_units) + redeemers[k] = v + return redeemers + @property def script_data_hash(self) -> Optional[ScriptDataHash]: - if self.datums or self.redeemers: + if self.datums or self._redeemer_list: cost_models = {} for s in self.all_scripts: if isinstance(s, PlutusV1Script) or type(s) is bytes: @@ -512,7 +532,7 @@ def script_data_hash(self) -> Optional[ScriptDataHash]: "PlutusV3", {} ) return script_data_hash( - self.redeemers, list(self.datums.values()), CostModels(cost_models) + self.redeemers(), list(self.datums.values()), CostModels(cost_models) ) else: return None @@ -878,7 +898,7 @@ def _set_redeemer_index(self): script_staking_credential.to_primitive() ) - self.redeemers.sort(key=lambda r: r.index) + self._redeemer_list.sort(key=lambda r: r.index) def _build_tx_body(self) -> TransactionBody: tx_body = TransactionBody( @@ -946,13 +966,16 @@ def _build_full_fake_tx(self) -> Transaction: ) return tx - def build_witness_set(self, remove_dup_script=False) -> TransactionWitnessSet: + def build_witness_set( + self, remove_dup_script: bool = False, post_chang: bool = True + ) -> TransactionWitnessSet: """Build a transaction witness set, excluding verification key witnesses. This function is especially useful when the transaction involves Plutus scripts. Args: remove_dup_script (bool): Whether to remove scripts, that are already attached to inputs, from the witness set. + post_chang (bool): Whether to use chang serialization for the witness. Returns: TransactionWitnessSet: A transaction witness set without verification key witnesses. @@ -990,12 +1013,19 @@ def build_witness_set(self, remove_dup_script=False) -> TransactionWitnessSet: f"Unsupported script type: {type(script)}" ) + redeemers: Optional[Redeemers] = None + if self._redeemer_list: + if not post_chang: + redeemers = self._redeemer_list + else: + redeemers = self.redeemers() + return TransactionWitnessSet( native_scripts=native_scripts if native_scripts else None, plutus_v1_script=plutus_v1_scripts if plutus_v1_scripts else None, plutus_v2_script=plutus_v2_scripts if plutus_v2_scripts else None, plutus_v3_script=plutus_v3_scripts if plutus_v3_scripts else None, - redeemer=self.redeemers if self.redeemers else None, + redeemer=redeemers, plutus_data=list(self.datums.values()) if self.datums else None, ) @@ -1009,7 +1039,7 @@ def _ensure_no_input_exclusion_conflict(self): def _estimate_fee(self): plutus_execution_units = ExecutionUnits(0, 0) - for redeemer in self.redeemers: + for redeemer in self._redeemer_list: plutus_execution_units += redeemer.ex_units ref_script_size = 0 @@ -1357,7 +1387,7 @@ def _update_execution_units( estimated_execution_units = self._estimate_execution_units( change_address, merge_change, collateral_change_address ) - for r in self.redeemers: + for r in self._redeemer_list: assert ( r.tag is not None ), "Expected tag of redeemer to be set, but found None" diff --git a/pycardano/utils.py b/pycardano/utils.py index 036b5019..bac81a74 100644 --- a/pycardano/utils.py +++ b/pycardano/utils.py @@ -11,7 +11,7 @@ from pycardano.backend.base import ChainContext from pycardano.hash import SCRIPT_DATA_HASH_SIZE, SCRIPT_HASH_SIZE, ScriptDataHash -from pycardano.plutus import COST_MODELS, CostModels, Datum, Redeemer +from pycardano.plutus import COST_MODELS, CostModels, Datum, Redeemers from pycardano.serialization import default_encoder from pycardano.transaction import MultiAsset, TransactionOutput, Value @@ -231,14 +231,14 @@ def min_lovelace_post_alonzo(output: TransactionOutput, context: ChainContext) - def script_data_hash( - redeemers: List[Redeemer], + redeemers: Redeemers, datums: List[Datum], cost_models: Optional[Union[CostModels, Dict]] = None, ) -> ScriptDataHash: """Calculate plutus script data hash Args: - redeemers (List[Redeemer]): Redeemers to include. + redeemers (Redeemers): Redeemers to include. datums (List[Datum]): Datums to include. cost_models (Optional[CostModels]): Cost models. diff --git a/pycardano/witness.py b/pycardano/witness.py index 3a38f757..35e874c6 100644 --- a/pycardano/witness.py +++ b/pycardano/witness.py @@ -13,6 +13,7 @@ PlutusV3Script, RawPlutusData, Redeemer, + Redeemers, ) from pycardano.serialization import ( ArrayCBORSerializable, @@ -76,9 +77,9 @@ class TransactionWitnessSet(MapCBORSerializable): metadata={"optional": True, "key": 4, "object_hook": list_hook(RawPlutusData)}, ) - redeemer: Optional[List[Redeemer]] = field( + redeemer: Optional[Redeemers] = field( default=None, - metadata={"optional": True, "key": 5, "object_hook": list_hook(Redeemer)}, + metadata={"optional": True, "key": 5}, ) plutus_v2_script: Optional[List[PlutusV2Script]] = field( diff --git a/test/pycardano/test_plutus.py b/test/pycardano/test_plutus.py index b90a480d..f339a9f5 100644 --- a/test/pycardano/test_plutus.py +++ b/test/pycardano/test_plutus.py @@ -17,7 +17,10 @@ PlutusData, RawPlutusData, Redeemer, + RedeemerKey, + RedeemerMap, RedeemerTag, + RedeemerValue, Unit, id_map, plutus_script_hash, @@ -520,3 +523,64 @@ class B(PlutusData): ) assert B.from_cbor(cbor).to_cbor_hex() == cbor + + +def test_redeemer_key(): + # Test creation and equality + key1 = RedeemerKey(RedeemerTag.SPEND, 0) + key2 = RedeemerKey(RedeemerTag.SPEND, 0) + key3 = RedeemerKey(RedeemerTag.MINT, 1) + + assert key1 == key2 + assert key1 != key3 + + # Test hashing + assert hash(key1) == hash(key2) + assert hash(key1) != hash(key3) + + # Test serialization and deserialization + serialized = key1.to_primitive() + deserialized = RedeemerKey.from_primitive(serialized) + assert key1 == deserialized + + +def test_redeemer_value(): + # Test creation + data = RawPlutusData(42) + ex_units = ExecutionUnits(10, 20) + value = RedeemerValue(data, ex_units) + + assert value.data == data + assert value.ex_units == ex_units + + # Test serialization and deserialization + serialized = value.to_primitive() + deserialized = RedeemerValue.from_primitive(serialized) + assert value.data.data == deserialized.data + assert value.ex_units == deserialized.ex_units + + +def test_redeemer_map(): + # Test creation and adding items + redeemer_map = RedeemerMap() + key1 = RedeemerKey(RedeemerTag.SPEND, 0) + value1 = RedeemerValue(42, ExecutionUnits(10, 20)) + key2 = RedeemerKey(RedeemerTag.MINT, 1) + value2 = RedeemerValue(b"test", ExecutionUnits(30, 40)) + + redeemer_map[key1] = value1 + redeemer_map[key2] = value2 + + assert len(redeemer_map) == 2 + assert redeemer_map[key1] == value1 + assert redeemer_map[key2] == value2 + + # Test serialization and deserialization + serialized = redeemer_map.to_cbor() + deserialized = RedeemerMap.from_cbor(serialized) + + assert len(deserialized) == 2 + assert deserialized[key1].data == value1.data + assert deserialized[key1].ex_units == value1.ex_units + assert deserialized[key2].data == value2.data + assert deserialized[key2].ex_units == value2.ex_units diff --git a/test/pycardano/test_txbuilder.py b/test/pycardano/test_txbuilder.py index 134047f3..31b8b7df 100644 --- a/test/pycardano/test_txbuilder.py +++ b/test/pycardano/test_txbuilder.py @@ -3,10 +3,12 @@ from dataclasses import replace from fractions import Fraction from test.pycardano.test_key import SK +from test.pycardano.util import check_two_way_cbor from unittest.mock import patch import pytest +from pycardano import RedeemerKey, RedeemerMap, RedeemerValue from pycardano.address import Address from pycardano.certificate import ( PoolRegistration, @@ -56,7 +58,7 @@ ) from pycardano.txbuilder import TransactionBuilder from pycardano.utils import fee -from pycardano.witness import VerificationKeyWitness +from pycardano.witness import TransactionWitnessSet, VerificationKeyWitness def test_tx_builder(chain_context): @@ -570,11 +572,14 @@ def test_add_script_input(chain_context): ) tx_builder.add_output(TransactionOutput(receiver, 5000000)) tx_builder.build(change_address=receiver) - witness = tx_builder.build_witness_set() + witness = tx_builder.build_witness_set(post_chang=False) assert [datum] == witness.plutus_data assert [redeemer1, redeemer2] == witness.redeemer assert [plutus_script] == witness.plutus_v1_script + # Test deserialization + TransactionWitnessSet.from_cbor(witness.to_cbor_hex()) + def test_add_script_input_no_script(chain_context): tx_builder = TransactionBuilder(chain_context) @@ -598,7 +603,7 @@ def test_add_script_input_no_script(chain_context): ) tx_builder.add_output(TransactionOutput(receiver, 5000000)) tx_builder.build(change_address=receiver) - witness = tx_builder.build_witness_set(remove_dup_script=True) + witness = tx_builder.build_witness_set(remove_dup_script=True, post_chang=False) assert [datum] == witness.plutus_data assert [redeemer] == witness.redeemer assert witness.plutus_v1_script is None @@ -666,7 +671,7 @@ def test_add_script_input_find_script(chain_context): ) tx_builder.add_output(TransactionOutput(receiver, 5000000)) tx_body = tx_builder.build(change_address=receiver) - witness = tx_builder.build_witness_set() + witness = tx_builder.build_witness_set(post_chang=False) assert [datum] == witness.plutus_data assert [redeemer] == witness.redeemer assert witness.plutus_v1_script is None @@ -705,7 +710,7 @@ def test_add_script_input_with_script_from_specified_utxo(chain_context): ) tx_builder.add_output(TransactionOutput(receiver, 5000000)) tx_body = tx_builder.build(change_address=receiver) - witness = tx_builder.build_witness_set() + witness = tx_builder.build_witness_set(post_chang=False) assert [datum] == witness.plutus_data assert [redeemer] == witness.redeemer assert witness.plutus_v2_script is None @@ -976,7 +981,7 @@ def test_add_minting_script_from_specified_utxo(chain_context): tx_builder.add_output(TransactionOutput(receiver, 5000000)) tx_builder.mint = mint tx_body = tx_builder.build(change_address=receiver) - witness = tx_builder.build_witness_set() + witness = tx_builder.build_witness_set(post_chang=False) assert witness.plutus_data is None assert [redeemer] == witness.redeemer assert witness.plutus_v2_script is None @@ -1105,7 +1110,7 @@ def test_add_minting_script(chain_context): ) tx_builder.add_output(TransactionOutput(receiver, Value(5000000, mint))) tx_builder.build(change_address=receiver) - witness = tx_builder.build_witness_set() + witness = tx_builder.build_witness_set(post_chang=False) assert [plutus_script] == witness.plutus_v1_script @@ -1127,7 +1132,7 @@ def test_add_minting_script_only(chain_context): ) tx_builder.add_output(TransactionOutput(receiver, Value(5000000, mint))) tx_builder.build(change_address=receiver) - witness = tx_builder.build_witness_set() + witness = tx_builder.build_witness_set(post_chang=False) assert [plutus_script] == witness.plutus_v1_script @@ -1231,7 +1236,7 @@ def test_estimate_execution_unit(chain_context): ) tx_builder.add_output(TransactionOutput(receiver, 5000000)) tx_builder.build(change_address=receiver) - witness = tx_builder.build_witness_set() + witness = tx_builder.build_witness_set(post_chang=False) assert [datum] == witness.plutus_data assert [redeemer1] == witness.redeemer assert redeemer1.ex_units is not None @@ -1810,3 +1815,53 @@ def test_build_witness_set_mixed_scripts(chain_context): assert len(witness_set.plutus_v1_script) == 2 assert len(witness_set.plutus_v2_script) == 1 assert len(witness_set.plutus_v3_script) == 1 + + +def test_add_script_input_post_chang(chain_context): + tx_builder = TransactionBuilder(chain_context) + tx_in1 = TransactionInput.from_primitive( + ["18cbe6cadecd3f89b60e08e68e5e6c7d72d730aaa1ad21431590f7e6643438ef", 0] + ) + tx_in2 = TransactionInput.from_primitive( + ["18cbe6cadecd3f89b60e08e68e5e6c7d72d730aaa1ad21431590f7e6643438ef", 1] + ) + plutus_script = PlutusV1Script(b"dummy test script") + script_hash = plutus_script_hash(plutus_script) + script_address = Address(script_hash) + datum = PlutusData() + utxo1 = UTxO( + tx_in1, TransactionOutput(script_address, 10000000, datum_hash=datum.hash()) + ) + mint = MultiAsset.from_primitive({script_hash.payload: {b"TestToken": 1}}) + UTxO( + tx_in2, + TransactionOutput( + script_address, Value(10000000, mint), datum_hash=datum.hash() + ), + ) + redeemer1 = Redeemer(PlutusData(), ExecutionUnits(1000000, 1000000)) + redeemer2 = Redeemer(PlutusData(), ExecutionUnits(5000000, 1000000)) + tx_builder.mint = mint + tx_builder.add_script_input(utxo1, plutus_script, datum, redeemer1) + tx_builder.add_minting_script(plutus_script, redeemer2) + receiver = Address.from_primitive( + "addr_test1vrm9x2zsux7va6w892g38tvchnzahvcd9tykqf3ygnmwtaqyfg52x" + ) + tx_builder.add_output(TransactionOutput(receiver, 5000000)) + tx_builder.build(change_address=receiver) + witness = tx_builder.build_witness_set() + assert [datum] == witness.plutus_data + assert [plutus_script] == witness.plutus_v1_script + + expected_redeemer_map = RedeemerMap( + { + RedeemerKey(RedeemerTag.SPEND, 0): RedeemerValue( + PlutusData(), ExecutionUnits(1000000, 1000000) + ), + RedeemerKey(RedeemerTag.MINT, 0): RedeemerValue( + PlutusData(), ExecutionUnits(5000000, 1000000) + ), + } + ) + + assert expected_redeemer_map == witness.redeemer From fb57ed4c42ba5a8a0a5071e3f1dfee76950f4c42 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20M=C3=BCndler?= Date: Sun, 8 Sep 2024 01:54:02 +0200 Subject: [PATCH 30/44] Automatically reduce 0 and empty multiassets (#372) * Add tests where we try to submit empty or zero multi-assets * Add tests for empty multiassets * Fix min_utxo could be none * Automatically reduce multiassets and assets * Formatting * Fix failing test due to now empty multiasset * Formatting * A bit more comprehensive on testing * formatting * Remove policy id where it is not needed * Reduce code duplication, include normalization for any serialization * Fix * Remove redundant line * Fix fee too low User can potentially provide signing keys that are not required by the finalized transaction. For example, if a transaction include a minting script and signing key for the script, but the minted value is 0, the signature of the minting script isn't required. This commit will auto detect such cases and skip the signing of this key. * Fix test --------- Co-authored-by: Jerry --- .../test/test_zero_empty_asset.py | 205 ++++++++++++++++++ pycardano/transaction.py | 57 ++++- pycardano/txbuilder.py | 19 +- pycardano/utils.py | 2 +- test/pycardano/test_transaction.py | 91 ++++++++ test/pycardano/test_txbuilder.py | 1 + test/pycardano/test_util.py | 3 +- 7 files changed, 369 insertions(+), 9 deletions(-) create mode 100644 integration-test/test/test_zero_empty_asset.py diff --git a/integration-test/test/test_zero_empty_asset.py b/integration-test/test/test_zero_empty_asset.py new file mode 100644 index 00000000..71ca83c0 --- /dev/null +++ b/integration-test/test/test_zero_empty_asset.py @@ -0,0 +1,205 @@ +import pathlib +import tempfile + +import pytest +from retry import retry + +from pycardano import * + +from .base import TEST_RETRIES, TestBase + + +class TestZeroEmptyAsset(TestBase): + @retry(tries=TEST_RETRIES, backoff=1.5, delay=6, jitter=(0, 4)) + @pytest.mark.post_chang + def test_submit_zero_and_empty(self): + address = Address(self.payment_vkey.hash(), network=self.NETWORK) + + # Load payment keys or create them if they don't exist + def load_or_create_key_pair(base_dir, base_name): + skey_path = base_dir / f"{base_name}.skey" + vkey_path = base_dir / f"{base_name}.vkey" + + if skey_path.exists(): + skey = PaymentSigningKey.load(str(skey_path)) + vkey = PaymentVerificationKey.from_signing_key(skey) + else: + key_pair = PaymentKeyPair.generate() + key_pair.signing_key.save(str(skey_path)) + key_pair.verification_key.save(str(vkey_path)) + skey = key_pair.signing_key + vkey = key_pair.verification_key + return skey, vkey + + tempdir = tempfile.TemporaryDirectory() + PROJECT_ROOT = tempdir.name + + root = pathlib.Path(PROJECT_ROOT) + # Create the directory if it doesn't exist + root.mkdir(parents=True, exist_ok=True) + """Generate keys""" + key_dir = root / "keys" + key_dir.mkdir(exist_ok=True) + + # Generate policy keys, which will be used when minting NFT + policy_skey, policy_vkey = load_or_create_key_pair(key_dir, "policy") + + """Create policy""" + # A policy that requires a signature from the policy key we generated above + pub_key_policy_1 = ScriptPubkey(policy_vkey.hash()) + + # A policy that requires a signature from the extended payment key + pub_key_policy_2 = ScriptPubkey(self.extended_payment_vkey.hash()) + + # Combine two policies using ScriptAll policy + policy = ScriptAll([pub_key_policy_1, pub_key_policy_2]) + + # Calculate policy ID, which is the hash of the policy + policy_id = policy.hash() + + """Define NFT""" + my_nft = MultiAsset.from_primitive( + { + policy_id.payload: { + b"MY_NFT_1": 1, # Name of our NFT1 # Quantity of this NFT + b"MY_NFT_2": 1, # Name of our NFT2 # Quantity of this NFT + } + } + ) + + native_scripts = [policy] + + """Create metadata""" + # We need to create a metadata for our NFTs, so they could be displayed correctly by blockchain explorer + metadata = { + 721: { # 721 refers to the metadata label registered for NFT standard here: + # https://github.com/cardano-foundation/CIPs/blob/master/CIP-0010/registry.json#L14-L17 + policy_id.payload.hex(): { + "MY_NFT_1": { + "description": "This is my first NFT thanks to PyCardano", + "name": "PyCardano NFT example token 1", + "id": 1, + "image": "ipfs://QmRhTTbUrPYEw3mJGGhQqQST9k86v1DPBiTTWJGKDJsVFw", + }, + "MY_NFT_2": { + "description": "This is my second NFT thanks to PyCardano", + "name": "PyCardano NFT example token 2", + "id": 2, + "image": "ipfs://QmRhTTbUrPYEw3mJGGhQqQST9k86v1DPBiTTWJGKDJsVFw", + }, + } + } + } + + # Place metadata in AuxiliaryData, the format acceptable by a transaction. + auxiliary_data = AuxiliaryData(AlonzoMetadata(metadata=Metadata(metadata))) + + """Build mint transaction""" + + # Create a transaction builder + builder = TransactionBuilder(self.chain_context) + + # Add our own address as the input address + builder.add_input_address(address) + + # Set nft we want to mint + builder.mint = my_nft + + # Set native script + builder.native_scripts = native_scripts + + # Set transaction metadata + builder.auxiliary_data = auxiliary_data + + # Calculate the minimum amount of lovelace that need to hold the NFT we are going to mint + min_val = min_lovelace_pre_alonzo(Value(0, my_nft), self.chain_context) + + # Send the NFT to our own address + nft_output = TransactionOutput(address, Value(min_val, my_nft)) + builder.add_output(nft_output) + + # Build and sign transaction + signed_tx = builder.build_and_sign( + [self.payment_skey, self.extended_payment_skey, policy_skey], address + ) + + print("############### Transaction created ###############") + print(signed_tx) + print(signed_tx.to_cbor_hex()) + + # Submit signed transaction to the network + print("############### Submitting transaction ###############") + self.chain_context.submit_tx(signed_tx) + + self.assert_output(address, nft_output) + + """Build transaction with 0 nft""" + + # Create a transaction builder + builder = TransactionBuilder(self.chain_context) + + # Add our own address as the input address + builder.add_input_address(address) + + # Calculate the minimum amount of lovelace that need to hold the NFT we are going to mint + min_val = min_lovelace_pre_alonzo(Value(0), self.chain_context) + + # Send the NFT to our own address + nft_output = TransactionOutput( + address, + Value( + min_val, + MultiAsset.from_primitive( + {policy_vkey.hash().payload: {b"MY_NFT_1": 0}} + ), + ), + ) + builder.add_output(nft_output) + + # Build and sign transaction + signed_tx = builder.build_and_sign( + [self.payment_skey, self.extended_payment_skey], address + ) + + print("############### Transaction created ###############") + print(signed_tx) + print(signed_tx.to_cbor_hex()) + + # Submit signed transaction to the network + print("############### Submitting transaction ###############") + self.chain_context.submit_tx(signed_tx) + + self.assert_output(address, nft_output) + + """Build transaction with empty multi-asset""" + + # Create a transaction builder + builder = TransactionBuilder(self.chain_context) + + # Add our own address as the input address + builder.add_input_address(address) + + # Calculate the minimum amount of lovelace that need to hold the NFT we are going to mint + min_val = min_lovelace_pre_alonzo(Value(0), self.chain_context) + + # Send the NFT to our own address + nft_output = TransactionOutput( + address, + Value(min_val, MultiAsset.from_primitive({policy_vkey.hash().payload: {}})), + ) + builder.add_output(nft_output) + + # Build and sign transaction + signed_tx = builder.build_and_sign( + [self.payment_skey, self.extended_payment_skey], address + ) + + print("############### Transaction created ###############") + print(signed_tx) + print(signed_tx.to_cbor_hex()) + + # Submit signed transaction to the network + print("############### Submitting transaction ###############") + self.chain_context.submit_tx(signed_tx) + + self.assert_output(address, nft_output) diff --git a/pycardano/transaction.py b/pycardano/transaction.py index 1d10799a..6c060101 100644 --- a/pycardano/transaction.py +++ b/pycardano/transaction.py @@ -38,10 +38,12 @@ from pycardano.serialization import ( ArrayCBORSerializable, CBORSerializable, + DictBase, DictCBORSerializable, MapCBORSerializable, Primitive, default_encoder, + limit_primitive_type, list_hook, ) from pycardano.types import typechecked @@ -87,6 +89,13 @@ class Asset(DictCBORSerializable): VALUE_TYPE = int + def normalize(self) -> Asset: + """Normalize the Asset by removing zero values.""" + for k, v in list(self.items()): + if v == 0: + self.pop(k) + return self + def union(self, other: Asset) -> Asset: return self + other @@ -94,18 +103,18 @@ def __add__(self, other: Asset) -> Asset: new_asset = deepcopy(self) for n in other: new_asset[n] = new_asset.get(n, 0) + other[n] - return new_asset + return new_asset.normalize() def __iadd__(self, other: Asset) -> Asset: new_item = self + other self.update(new_item) - return self + return self.normalize() def __sub__(self, other: Asset) -> Asset: new_asset = deepcopy(self) for n in other: new_asset[n] = new_asset.get(n, 0) - other[n] - return new_asset + return new_asset.normalize() def __eq__(self, other): if not isinstance(other, Asset): @@ -124,6 +133,20 @@ def __le__(self, other: Asset) -> bool: return False return True + @classmethod + @limit_primitive_type(dict) + def from_primitive(cls: Type[DictBase], value: dict) -> DictBase: + res = super().from_primitive(value) + # pop zero values + for n, v in list(res.items()): + if v == 0: + res.pop(n) + return res + + def to_shallow_primitive(self) -> dict: + x = deepcopy(self).normalize() + return super(self.__class__, x).to_shallow_primitive() + @typechecked class MultiAsset(DictCBORSerializable): @@ -134,22 +157,30 @@ class MultiAsset(DictCBORSerializable): def union(self, other: MultiAsset) -> MultiAsset: return self + other + def normalize(self) -> MultiAsset: + """Normalize the MultiAsset by removing zero values.""" + for k, v in list(self.items()): + v.normalize() + if len(v) == 0: + self.pop(k) + return self + def __add__(self, other): new_multi_asset = deepcopy(self) for p in other: new_multi_asset[p] = new_multi_asset.get(p, Asset()) + other[p] - return new_multi_asset + return new_multi_asset.normalize() def __iadd__(self, other): new_item = self + other self.update(new_item) - return self + return self.normalize() def __sub__(self, other: MultiAsset) -> MultiAsset: new_multi_asset = deepcopy(self) for p in other: new_multi_asset[p] = new_multi_asset.get(p, Asset()) - other[p] - return new_multi_asset + return new_multi_asset.normalize() def __eq__(self, other): if not isinstance(other, MultiAsset): @@ -209,6 +240,20 @@ def count(self, criteria=Callable[[ScriptHash, AssetName, int], bool]) -> int: return count + @classmethod + @limit_primitive_type(dict) + def from_primitive(cls: Type[DictBase], value: dict) -> DictBase: + res = super().from_primitive(value) + # pop empty values + for n, v in list(res.items()): + if not v: + res.pop(n) + return res + + def to_shallow_primitive(self) -> dict: + x = deepcopy(self).normalize() + return super(self.__class__, x).to_shallow_primitive() + @typechecked @dataclass(repr=False) diff --git a/pycardano/txbuilder.py b/pycardano/txbuilder.py index 7ff0be3d..256d9962 100644 --- a/pycardano/txbuilder.py +++ b/pycardano/txbuilder.py @@ -928,12 +928,16 @@ def _build_tx_body(self) -> TransactionBody: ) return tx_body - def _build_fake_vkey_witnesses(self) -> List[VerificationKeyWitness]: + def _build_required_vkeys(self) -> Set[VerificationKeyHash]: vkey_hashes = self._input_vkey_hashes() vkey_hashes.update(self._required_signer_vkey_hashes()) vkey_hashes.update(self._native_scripts_vkey_hashes()) vkey_hashes.update(self._certificate_vkey_hashes()) vkey_hashes.update(self._withdrawal_vkey_hashes()) + return vkey_hashes + + def _build_fake_vkey_witnesses(self) -> List[VerificationKeyWitness]: + vkey_hashes = self._build_required_vkeys() witness_count = self.witness_override or len(vkey_hashes) @@ -1441,6 +1445,7 @@ def build_and_sign( auto_validity_start_offset: Optional[int] = None, auto_ttl_offset: Optional[int] = None, auto_required_signers: Optional[bool] = None, + force_skeys: Optional[bool] = False, ) -> Transaction: """Build a transaction body from all constraints set through the builder and sign the transaction with provided signing keys. @@ -1462,6 +1467,10 @@ def build_and_sign( auto_required_signers (Optional[bool]): Automatically add all pubkeyhashes of transaction inputs and the given signers to required signatories (default only for Smart Contract transactions). Manually set required signers will always take precedence. + force_skeys (Optional[bool]): Whether to force the use of signing keys for signing the transaction. + Default is False, which means that provided signing keys will only be used to sign the transaction if + they are actually required by the transaction. This is useful to reduce tx fees by not including + unnecessary signatures. If set to True, all provided signing keys will be used to sign the transaction. Returns: Transaction: A signed transaction. @@ -1483,7 +1492,15 @@ def build_and_sign( witness_set = self.build_witness_set(True) witness_set.vkey_witnesses = [] + required_vkeys = self._build_required_vkeys() + for signing_key in set(signing_keys): + vkey_hash = signing_key.to_verification_key().hash() + if not force_skeys and vkey_hash not in required_vkeys: + logger.warn( + f"Verification key hash {vkey_hash} is not required for this tx." + ) + continue signature = signing_key.sign(tx_body.hash()) witness_set.vkey_witnesses.append( VerificationKeyWitness(signing_key.to_verification_key(), signature) diff --git a/pycardano/utils.py b/pycardano/utils.py index bac81a74..17a400ff 100644 --- a/pycardano/utils.py +++ b/pycardano/utils.py @@ -184,7 +184,7 @@ def min_lovelace_pre_alonzo( int: Minimum required lovelace amount for this transaction output. """ if amount is None or isinstance(amount, int) or not amount.multi_asset: - return context.protocol_param.min_utxo + return context.protocol_param.min_utxo or 1_000_000 b_size = bundle_size(amount.multi_asset) utxo_entry_size = 27 diff --git a/test/pycardano/test_transaction.py b/test/pycardano/test_transaction.py index e7cc0c33..5ec6f51e 100644 --- a/test/pycardano/test_transaction.py +++ b/test/pycardano/test_transaction.py @@ -482,3 +482,94 @@ def test_out_of_bound_asset(): # Not okay only when minting with pytest.raises(InvalidDataException): tx.to_cbor_hex() + + +def test_zero_value(): + nft_output = Value( + 10000000, + MultiAsset.from_primitive( + { + bytes.fromhex( + "a39a5998f2822dfc9111e447038c3cfffa883ed1b9e357be9cd60dfe" + ): {b"MY_NFT_1": 0} + } + ), + ) + assert len(nft_output.multi_asset) == 0 + + +def test_empty_multiasset(): + nft_output = Value( + 10000000, + MultiAsset.from_primitive( + { + bytes.fromhex( + "a39a5998f2822dfc9111e447038c3cfffa883ed1b9e357be9cd60dfe" + ): {} + } + ), + ) + assert len(nft_output.multi_asset) == 0 + + +def test_add_empty(): + nft_output = Value( + 10000000, + MultiAsset.from_primitive( + { + bytes.fromhex( + "a39a5998f2822dfc9111e447038c3cfffa883ed1b9e357be9cd60dfe" + ): {b"MY_NFT_1": 100} + } + ), + ) - Value( + 5, + MultiAsset.from_primitive( + { + bytes.fromhex( + "a39a5998f2822dfc9111e447038c3cfffa883ed1b9e357be9cd60dfe" + ): {b"MY_NFT_1": 100} + } + ), + ) + assert len(nft_output.multi_asset) == 0 + + +def test_zero_value_pop(): + policy = bytes.fromhex("a39a5998f2822dfc9111e447038c3cfffa883ed1b9e357be9cd60dfe") + nft_output = Value( + 10000000, + MultiAsset.from_primitive({policy: {b"MY_NFT_1": 0, b"MY_NFT_2": 1}}), + ) + assert len(nft_output.multi_asset) == 1 + assert len(nft_output.multi_asset[ScriptHash(policy)]) == 1 + + +def test_empty_multiasset_pop(): + nft_output = Value( + 10000000, + MultiAsset.from_primitive( + { + bytes.fromhex( + "a39a5998f2822dfc9111e447038c3cfffa883ed1b9e357be9cd60dfe" + ): {}, + bytes.fromhex( + "b39a5998f2822dfc9111e447038c3cfffa883ed1b9e357be9cd60dfe" + ): {b"MY_NFT_1": 1}, + } + ), + ) + assert len(nft_output.multi_asset) == 1 + + +def test_add_empty_pop(): + policy = bytes.fromhex("a39a5998f2822dfc9111e447038c3cfffa883ed1b9e357be9cd60dfe") + nft_output = Value( + 10000000, + MultiAsset.from_primitive({policy: {b"MY_NFT_1": 100, b"MY_NFT_2": 100}}), + ) - Value( + 5, + MultiAsset.from_primitive({policy: {b"MY_NFT_1": 100}}), + ) + assert len(nft_output.multi_asset) == 1 + assert len(nft_output.multi_asset[ScriptHash(policy)]) == 1 diff --git a/test/pycardano/test_txbuilder.py b/test/pycardano/test_txbuilder.py index 31b8b7df..027acc99 100644 --- a/test/pycardano/test_txbuilder.py +++ b/test/pycardano/test_txbuilder.py @@ -1202,6 +1202,7 @@ def test_build_and_sign(chain_context): tx = tx_builder2.build_and_sign( [SK], change_address=sender_address, + force_skeys=True, ) assert tx.transaction_witness_set.vkey_witnesses == [ diff --git a/test/pycardano/test_util.py b/test/pycardano/test_util.py index 444546af..17b4f647 100644 --- a/test/pycardano/test_util.py +++ b/test/pycardano/test_util.py @@ -88,7 +88,8 @@ def test_min_lovelace_multi_asset_6(self, chain_context): { b"1" * SCRIPT_HASH_SIZE: { - i.to_bytes(1, byteorder="big"): 1000000 * i for i in range(32) + i.to_bytes(1, byteorder="big"): 1000000 * i + for i in range(1, 33) }, b"2" * SCRIPT_HASH_SIZE: { From 11dc71f145a7f8cc4be44be691d4e0ca13c4a6b3 Mon Sep 17 00:00:00 2001 From: Jerry Date: Sun, 8 Sep 2024 10:24:18 -0700 Subject: [PATCH 31/44] Using log.warning --- pycardano/txbuilder.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pycardano/txbuilder.py b/pycardano/txbuilder.py index 256d9962..6764a6d9 100644 --- a/pycardano/txbuilder.py +++ b/pycardano/txbuilder.py @@ -1497,7 +1497,7 @@ def build_and_sign( for signing_key in set(signing_keys): vkey_hash = signing_key.to_verification_key().hash() if not force_skeys and vkey_hash not in required_vkeys: - logger.warn( + logger.warning( f"Verification key hash {vkey_hash} is not required for this tx." ) continue From 66218b17c92fcd23c3760218f55661481b919564 Mon Sep 17 00:00:00 2001 From: Jerry Date: Sun, 8 Sep 2024 10:42:12 -0700 Subject: [PATCH 32/44] Restore OgmiosChainBackend and fix docs --- docs/requirements.txt | 52 +++++++++++++--------- docs/source/api/pycardano.backend.base.rst | 7 ++- pycardano/backend/ogmios_v5.py | 3 +- pycardano/backend/ogmios_v6.py | 7 ++- 4 files changed, 46 insertions(+), 23 deletions(-) diff --git a/docs/requirements.txt b/docs/requirements.txt index 22ce70ae..980587a1 100644 --- a/docs/requirements.txt +++ b/docs/requirements.txt @@ -1,35 +1,39 @@ alabaster==0.7.13 ; python_full_version >= "3.8.1" and python_full_version < "4.0.0" +annotated-types==0.7.0 ; python_full_version >= "3.8.1" and python_full_version < "4.0.0" asn1crypto==1.5.1 ; python_full_version >= "3.8.1" and python_full_version < "4.0.0" -attrs==23.2.0 ; python_full_version >= "3.8.1" and python_full_version < "4.0.0" -babel==2.15.0 ; python_full_version >= "3.8.1" and python_full_version < "4.0.0" -black==24.4.2 ; python_full_version >= "3.8.1" and python_full_version < "4.0.0" +attrs==24.2.0 ; python_full_version >= "3.8.1" and python_full_version < "4.0.0" +babel==2.16.0 ; python_full_version >= "3.8.1" and python_full_version < "4.0.0" +black==24.8.0 ; python_full_version >= "3.8.1" and python_full_version < "4.0.0" blinker==1.8.2 ; python_full_version >= "3.8.1" and python_full_version < "4.0.0" blockfrost-python==0.5.3 ; python_full_version >= "3.8.1" and python_version < "4" -cachetools==5.3.3 ; python_full_version >= "3.8.1" and python_full_version < "4.0.0" -cbor2==5.6.3 ; python_full_version >= "3.8.1" and python_full_version < "4.0.0" -certifi==2024.2.2 ; python_full_version >= "3.8.1" and python_version < "4" +cachetools==5.5.0 ; python_full_version >= "3.8.1" and python_full_version < "4.0.0" +cardano-tools==2.1.0 ; python_full_version >= "3.8.1" and python_version < "4.0" +cbor2==5.6.4 ; python_full_version >= "3.8.1" and python_full_version < "4.0.0" +certifi==2024.8.30 ; python_full_version >= "3.8.1" and python_version < "4" certvalidator==0.11.1 ; python_full_version >= "3.8.1" and python_full_version < "4.0.0" -cffi==1.16.0 ; python_full_version >= "3.8.1" and python_full_version < "4.0.0" +cffi==1.17.0 ; python_full_version >= "3.8.1" and python_full_version < "4.0.0" charset-normalizer==3.3.2 ; python_full_version >= "3.8.1" and python_version < "4" click==8.1.7 ; python_full_version >= "3.8.1" and python_full_version < "4.0.0" colorama==0.4.6 ; python_full_version >= "3.8.1" and python_full_version < "4.0.0" and (sys_platform == "win32" or platform_system == "Windows") +coloredlogs==15.0.1 ; python_full_version >= "3.8.1" and python_full_version < "4.0.0" cose==0.9.dev8 ; python_full_version >= "3.8.1" and python_full_version < "4.0.0" -coverage[toml]==7.5.3 ; python_full_version >= "3.8.1" and python_full_version < "4.0.0" -cryptography==42.0.7 ; python_full_version >= "3.8.1" and python_full_version < "4.0.0" +coverage[toml]==7.6.1 ; python_full_version >= "3.8.1" and python_full_version < "4.0.0" +cryptography==43.0.0 ; python_full_version >= "3.8.1" and python_full_version < "4.0.0" decorator==5.1.1 ; python_full_version >= "3.8.1" and python_full_version < "4.0.0" docker==7.1.0 ; python_full_version >= "3.8.1" and python_full_version < "4.0.0" docutils==0.19 ; python_full_version >= "3.8.1" and python_full_version < "4.0.0" ecdsa==0.19.0 ; python_full_version >= "3.8.1" and python_full_version < "4.0.0" ecpy==1.2.5 ; python_full_version >= "3.8.1" and python_full_version < "4.0.0" -exceptiongroup==1.2.1 ; python_full_version >= "3.8.1" and python_version < "3.11" +exceptiongroup==1.2.2 ; python_full_version >= "3.8.1" and python_version < "3.11" execnet==2.1.1 ; python_full_version >= "3.8.1" and python_full_version < "4.0.0" -flake8==7.0.0 ; python_full_version >= "3.8.1" and python_full_version < "4.0.0" +flake8==7.1.1 ; python_full_version >= "3.8.1" and python_full_version < "4.0.0" flask==2.3.3 ; python_full_version >= "3.8.1" and python_full_version < "4.0.0" frozendict==2.4.4 ; python_full_version >= "3.8.1" and python_full_version < "4.0.0" frozenlist==1.4.1 ; python_full_version >= "3.8.1" and python_full_version < "4.0.0" -idna==3.7 ; python_full_version >= "3.8.1" and python_version < "4" +humanfriendly==10.0 ; python_full_version >= "3.8.1" and python_full_version < "4.0.0" +idna==3.8 ; python_full_version >= "3.8.1" and python_version < "4" imagesize==1.4.1 ; python_full_version >= "3.8.1" and python_full_version < "4.0.0" -importlib-metadata==7.1.0 ; python_full_version >= "3.8.1" and python_version < "3.10" +importlib-metadata==8.4.0 ; python_full_version >= "3.8.1" and python_version < "3.10" iniconfig==2.0.0 ; python_full_version >= "3.8.1" and python_full_version < "4.0.0" isort==5.13.2 ; python_full_version >= "3.8.1" and python_full_version < "4.0.0" itsdangerous==2.2.0 ; python_full_version >= "3.8.1" and python_full_version < "4.0.0" @@ -39,21 +43,28 @@ mccabe==0.7.0 ; python_full_version >= "3.8.1" and python_full_version < "4.0.0" mnemonic==0.21 ; python_full_version >= "3.8.1" and python_full_version < "4.0.0" mypy-extensions==1.0.0 ; python_full_version >= "3.8.1" and python_full_version < "4.0.0" mypy==1.4.1 ; python_full_version >= "3.8.1" and python_full_version < "4.0.0" +ogmios @ git+https://gitlab.com/viperscience/ogmios-python.git@0b713e78839341d92828340a5552ef8dd1c6224b ; python_full_version >= "3.8.1" and python_full_version < "4.0.0" +orjson==3.10.7 ; python_full_version >= "3.8.1" and python_full_version < "4.0.0" oscrypto==1.3.0 ; python_full_version >= "3.8.1" and python_full_version < "4.0.0" -packaging==24.0 ; python_full_version >= "3.8.1" and python_full_version < "4.0.0" +packaging==24.1 ; python_full_version >= "3.8.1" and python_full_version < "4.0.0" pathspec==0.12.1 ; python_full_version >= "3.8.1" and python_full_version < "4.0.0" +pexpect==4.9.0 ; python_full_version >= "3.8.1" and python_version < "4.0" platformdirs==4.2.2 ; python_full_version >= "3.8.1" and python_full_version < "4.0.0" pluggy==1.5.0 ; python_full_version >= "3.8.1" and python_full_version < "4.0.0" pprintpp==0.4.0 ; python_full_version >= "3.8.1" and python_full_version < "4.0.0" +ptyprocess==0.7.0 ; python_full_version >= "3.8.1" and python_version < "4.0" py==1.11.0 ; python_full_version >= "3.8.1" and python_full_version < "4.0.0" -pycodestyle==2.11.1 ; python_full_version >= "3.8.1" and python_full_version < "4.0.0" +pycodestyle==2.12.1 ; python_full_version >= "3.8.1" and python_full_version < "4.0.0" pycparser==2.22 ; python_full_version >= "3.8.1" and python_full_version < "4.0.0" +pydantic-core==2.20.1 ; python_full_version >= "3.8.1" and python_full_version < "4.0.0" +pydantic==2.8.2 ; python_full_version >= "3.8.1" and python_full_version < "4.0.0" pyflakes==3.2.0 ; python_full_version >= "3.8.1" and python_full_version < "4.0.0" pygments==2.18.0 ; python_full_version >= "3.8.1" and python_full_version < "4.0.0" pynacl==1.5.0 ; python_full_version >= "3.8.1" and python_full_version < "4.0.0" +pyreadline3==3.4.1 ; sys_platform == "win32" and python_full_version >= "3.8.1" and python_full_version < "4.0.0" pytest-cov==5.0.0 ; python_full_version >= "3.8.1" and python_full_version < "4.0.0" pytest-xdist==3.6.1 ; python_full_version >= "3.8.1" and python_full_version < "4.0.0" -pytest==8.2.1 ; python_full_version >= "3.8.1" and python_full_version < "4.0.0" +pytest==8.3.2 ; python_full_version >= "3.8.1" and python_full_version < "4.0.0" pytz==2024.1 ; python_full_version >= "3.8.1" and python_version < "3.9" pywin32==306 ; python_full_version >= "3.8.1" and python_full_version < "4.0.0" and sys_platform == "win32" requests==2.32.3 ; python_full_version >= "3.8.1" and python_version < "4" @@ -74,8 +85,9 @@ sphinxcontrib-serializinghtml==1.1.5 ; python_full_version >= "3.8.1" and python tomli==2.0.1 ; python_full_version >= "3.8.1" and python_full_version <= "3.11.0a6" typeguard==4.3.0 ; python_full_version >= "3.8.1" and python_full_version < "4.0.0" types-requests==2.31.0.10 ; python_full_version >= "3.8.1" and python_full_version < "4.0.0" -typing-extensions==4.12.0 ; python_full_version >= "3.8.1" and python_full_version < "4.0.0" -urllib3==2.2.1 ; python_full_version >= "3.8.1" and python_version < "4" +typing-extensions==4.12.2 ; python_full_version >= "3.8.1" and python_full_version < "4.0.0" +urllib3==2.2.2 ; python_full_version >= "3.8.1" and python_version < "4" websocket-client==1.8.0 ; python_full_version >= "3.8.1" and python_full_version < "4.0.0" -werkzeug==3.0.3 ; python_full_version >= "3.8.1" and python_full_version < "4.0.0" -zipp==3.19.1 ; python_full_version >= "3.8.1" and python_version < "3.10" +websockets==13.0.1 ; python_full_version >= "3.8.1" and python_full_version < "4.0.0" +werkzeug==3.0.4 ; python_full_version >= "3.8.1" and python_full_version < "4.0.0" +zipp==3.20.1 ; python_full_version >= "3.8.1" and python_version < "3.10" diff --git a/docs/source/api/pycardano.backend.base.rst b/docs/source/api/pycardano.backend.base.rst index 91e70e5f..039007d7 100644 --- a/docs/source/api/pycardano.backend.base.rst +++ b/docs/source/api/pycardano.backend.base.rst @@ -11,7 +11,12 @@ Backend :undoc-members: :show-inheritance: -.. automodule:: pycardano.backend.ogmios +.. automodule:: pycardano.backend.ogmios_v6 + :members: + :undoc-members: + :show-inheritance: + +.. automodule:: pycardano.backend.ogmios_v5 :members: :undoc-members: :show-inheritance: diff --git a/pycardano/backend/ogmios_v5.py b/pycardano/backend/ogmios_v5.py index 74802ef9..7e049087 100644 --- a/pycardano/backend/ogmios_v5.py +++ b/pycardano/backend/ogmios_v5.py @@ -31,7 +31,7 @@ ) from pycardano.types import JsonDict -__all__ = ["OgmiosV5ChainContext"] +__all__ = ["OgmiosV5ChainContext", "KupoOgmiosV5ChainContext"] class OgmiosQueryType(str, Enum): @@ -41,6 +41,7 @@ class OgmiosQueryType(str, Enum): class OgmiosV5ChainContext(ChainContext): + """Legacy Ogmios Chain Context for Ogmios v5""" _ws_url: str _network: Network _service_name: str diff --git a/pycardano/backend/ogmios_v6.py b/pycardano/backend/ogmios_v6.py index 7b8f45dc..7caba138 100644 --- a/pycardano/backend/ogmios_v6.py +++ b/pycardano/backend/ogmios_v6.py @@ -39,7 +39,7 @@ ALONZO_COINS_PER_UTXO_WORD = 34482 DEFAULT_REFETCH_INTERVAL = 1000 -__all__ = ["OgmiosV6ChainContext"] +__all__ = ["OgmiosV6ChainContext", "OgmiosChainContext", "KupoOgmiosV6ChainContext"] class OgmiosV6ChainContext(ChainContext): @@ -357,6 +357,11 @@ def _parse_cost_models(self, plutus_cost_models): return cost_models +class OgmiosChainContext(OgmiosV6ChainContext): + """An alias of OgmiosV6ChainContext for backwards compatibility.""" + pass + + def KupoOgmiosV6ChainContext( host: str, port: int, From 080737dd89fbff0e9e8885391b1bed8b26f8a60f Mon Sep 17 00:00:00 2001 From: Jerry Date: Sun, 8 Sep 2024 11:05:21 -0700 Subject: [PATCH 33/44] Format --- pycardano/backend/ogmios_v5.py | 1 + pycardano/backend/ogmios_v6.py | 1 + 2 files changed, 2 insertions(+) diff --git a/pycardano/backend/ogmios_v5.py b/pycardano/backend/ogmios_v5.py index 7e049087..fea3a70b 100644 --- a/pycardano/backend/ogmios_v5.py +++ b/pycardano/backend/ogmios_v5.py @@ -42,6 +42,7 @@ class OgmiosQueryType(str, Enum): class OgmiosV5ChainContext(ChainContext): """Legacy Ogmios Chain Context for Ogmios v5""" + _ws_url: str _network: Network _service_name: str diff --git a/pycardano/backend/ogmios_v6.py b/pycardano/backend/ogmios_v6.py index 7caba138..7e60f845 100644 --- a/pycardano/backend/ogmios_v6.py +++ b/pycardano/backend/ogmios_v6.py @@ -359,6 +359,7 @@ def _parse_cost_models(self, plutus_cost_models): class OgmiosChainContext(OgmiosV6ChainContext): """An alias of OgmiosV6ChainContext for backwards compatibility.""" + pass From 05b150d940dfa929d106ec9982eefb4475ec9f54 Mon Sep 17 00:00:00 2001 From: Jerry Date: Sun, 8 Sep 2024 10:23:52 -0700 Subject: [PATCH 34/44] Blockfrost for chang --- poetry.lock | 431 ++++++++++++++++---------------- pycardano/backend/blockfrost.py | 6 + pyproject.toml | 4 +- 3 files changed, 228 insertions(+), 213 deletions(-) diff --git a/poetry.lock b/poetry.lock index 3127a37a..29717e91 100644 --- a/poetry.lock +++ b/poetry.lock @@ -131,13 +131,13 @@ files = [ [[package]] name = "blockfrost-python" -version = "0.5.3" +version = "0.6.0" description = "The official Python SDK for Blockfrost API v0.1.37" optional = false -python-versions = ">=3.7, <4" +python-versions = "<4,>=3.7" files = [ - {file = "blockfrost-python-0.5.3.tar.gz", hash = "sha256:3154b99867e7714c90064c9e1a37e3b7af97c107b64549dd0d424aaa3209017e"}, - {file = "blockfrost_python-0.5.3-py3-none-any.whl", hash = "sha256:b0e73f09f1ff06977c85ccd63f6afe7ec30fa1b5c48e94a15d8bc8cf1f61997b"}, + {file = "blockfrost_python-0.6.0-py3-none-any.whl", hash = "sha256:c88840b8034b30dc06c637ccd14806e472d830d63522d2a667d9263640a354f4"}, + {file = "blockfrost_python-0.6.0.tar.gz", hash = "sha256:764b795617aadfd712b2a214fa6bd26cca33f0008340e0225126d18be040b112"}, ] [package.dependencies] @@ -248,78 +248,78 @@ oscrypto = ">=0.16.1" [[package]] name = "cffi" -version = "1.17.0" +version = "1.17.1" description = "Foreign Function Interface for Python calling C code." optional = false python-versions = ">=3.8" files = [ - {file = "cffi-1.17.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:f9338cc05451f1942d0d8203ec2c346c830f8e86469903d5126c1f0a13a2bcbb"}, - {file = "cffi-1.17.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:a0ce71725cacc9ebf839630772b07eeec220cbb5f03be1399e0457a1464f8e1a"}, - {file = "cffi-1.17.0-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c815270206f983309915a6844fe994b2fa47e5d05c4c4cef267c3b30e34dbe42"}, - {file = "cffi-1.17.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d6bdcd415ba87846fd317bee0774e412e8792832e7805938987e4ede1d13046d"}, - {file = "cffi-1.17.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8a98748ed1a1df4ee1d6f927e151ed6c1a09d5ec21684de879c7ea6aa96f58f2"}, - {file = "cffi-1.17.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:0a048d4f6630113e54bb4b77e315e1ba32a5a31512c31a273807d0027a7e69ab"}, - {file = "cffi-1.17.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:24aa705a5f5bd3a8bcfa4d123f03413de5d86e497435693b638cbffb7d5d8a1b"}, - {file = "cffi-1.17.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:856bf0924d24e7f93b8aee12a3a1095c34085600aa805693fb7f5d1962393206"}, - {file = "cffi-1.17.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:4304d4416ff032ed50ad6bb87416d802e67139e31c0bde4628f36a47a3164bfa"}, - {file = "cffi-1.17.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:331ad15c39c9fe9186ceaf87203a9ecf5ae0ba2538c9e898e3a6967e8ad3db6f"}, - {file = "cffi-1.17.0-cp310-cp310-win32.whl", hash = "sha256:669b29a9eca6146465cc574659058ed949748f0809a2582d1f1a324eb91054dc"}, - {file = "cffi-1.17.0-cp310-cp310-win_amd64.whl", hash = "sha256:48b389b1fd5144603d61d752afd7167dfd205973a43151ae5045b35793232aa2"}, - {file = "cffi-1.17.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:c5d97162c196ce54af6700949ddf9409e9833ef1003b4741c2b39ef46f1d9720"}, - {file = "cffi-1.17.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:5ba5c243f4004c750836f81606a9fcb7841f8874ad8f3bf204ff5e56332b72b9"}, - {file = "cffi-1.17.0-cp311-cp311-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:bb9333f58fc3a2296fb1d54576138d4cf5d496a2cc118422bd77835e6ae0b9cb"}, - {file = "cffi-1.17.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:435a22d00ec7d7ea533db494da8581b05977f9c37338c80bc86314bec2619424"}, - {file = "cffi-1.17.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d1df34588123fcc88c872f5acb6f74ae59e9d182a2707097f9e28275ec26a12d"}, - {file = "cffi-1.17.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:df8bb0010fdd0a743b7542589223a2816bdde4d94bb5ad67884348fa2c1c67e8"}, - {file = "cffi-1.17.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a8b5b9712783415695663bd463990e2f00c6750562e6ad1d28e072a611c5f2a6"}, - {file = "cffi-1.17.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:ffef8fd58a36fb5f1196919638f73dd3ae0db1a878982b27a9a5a176ede4ba91"}, - {file = "cffi-1.17.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:4e67d26532bfd8b7f7c05d5a766d6f437b362c1bf203a3a5ce3593a645e870b8"}, - {file = "cffi-1.17.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:45f7cd36186db767d803b1473b3c659d57a23b5fa491ad83c6d40f2af58e4dbb"}, - {file = "cffi-1.17.0-cp311-cp311-win32.whl", hash = "sha256:a9015f5b8af1bb6837a3fcb0cdf3b874fe3385ff6274e8b7925d81ccaec3c5c9"}, - {file = "cffi-1.17.0-cp311-cp311-win_amd64.whl", hash = "sha256:b50aaac7d05c2c26dfd50c3321199f019ba76bb650e346a6ef3616306eed67b0"}, - {file = "cffi-1.17.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:aec510255ce690d240f7cb23d7114f6b351c733a74c279a84def763660a2c3bc"}, - {file = "cffi-1.17.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:2770bb0d5e3cc0e31e7318db06efcbcdb7b31bcb1a70086d3177692a02256f59"}, - {file = "cffi-1.17.0-cp312-cp312-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:db9a30ec064129d605d0f1aedc93e00894b9334ec74ba9c6bdd08147434b33eb"}, - {file = "cffi-1.17.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a47eef975d2b8b721775a0fa286f50eab535b9d56c70a6e62842134cf7841195"}, - {file = "cffi-1.17.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f3e0992f23bbb0be00a921eae5363329253c3b86287db27092461c887b791e5e"}, - {file = "cffi-1.17.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:6107e445faf057c118d5050560695e46d272e5301feffda3c41849641222a828"}, - {file = "cffi-1.17.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:eb862356ee9391dc5a0b3cbc00f416b48c1b9a52d252d898e5b7696a5f9fe150"}, - {file = "cffi-1.17.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:c1c13185b90bbd3f8b5963cd8ce7ad4ff441924c31e23c975cb150e27c2bf67a"}, - {file = "cffi-1.17.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:17c6d6d3260c7f2d94f657e6872591fe8733872a86ed1345bda872cfc8c74885"}, - {file = "cffi-1.17.0-cp312-cp312-win32.whl", hash = "sha256:c3b8bd3133cd50f6b637bb4322822c94c5ce4bf0d724ed5ae70afce62187c492"}, - {file = "cffi-1.17.0-cp312-cp312-win_amd64.whl", hash = "sha256:dca802c8db0720ce1c49cce1149ff7b06e91ba15fa84b1d59144fef1a1bc7ac2"}, - {file = "cffi-1.17.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:6ce01337d23884b21c03869d2f68c5523d43174d4fc405490eb0091057943118"}, - {file = "cffi-1.17.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:cab2eba3830bf4f6d91e2d6718e0e1c14a2f5ad1af68a89d24ace0c6b17cced7"}, - {file = "cffi-1.17.0-cp313-cp313-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:14b9cbc8f7ac98a739558eb86fabc283d4d564dafed50216e7f7ee62d0d25377"}, - {file = "cffi-1.17.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b00e7bcd71caa0282cbe3c90966f738e2db91e64092a877c3ff7f19a1628fdcb"}, - {file = "cffi-1.17.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:41f4915e09218744d8bae14759f983e466ab69b178de38066f7579892ff2a555"}, - {file = "cffi-1.17.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e4760a68cab57bfaa628938e9c2971137e05ce48e762a9cb53b76c9b569f1204"}, - {file = "cffi-1.17.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:011aff3524d578a9412c8b3cfaa50f2c0bd78e03eb7af7aa5e0df59b158efb2f"}, - {file = "cffi-1.17.0-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:a003ac9edc22d99ae1286b0875c460351f4e101f8c9d9d2576e78d7e048f64e0"}, - {file = "cffi-1.17.0-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:ef9528915df81b8f4c7612b19b8628214c65c9b7f74db2e34a646a0a2a0da2d4"}, - {file = "cffi-1.17.0-cp313-cp313-win32.whl", hash = "sha256:70d2aa9fb00cf52034feac4b913181a6e10356019b18ef89bc7c12a283bf5f5a"}, - {file = "cffi-1.17.0-cp313-cp313-win_amd64.whl", hash = "sha256:b7b6ea9e36d32582cda3465f54c4b454f62f23cb083ebc7a94e2ca6ef011c3a7"}, - {file = "cffi-1.17.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:964823b2fc77b55355999ade496c54dde161c621cb1f6eac61dc30ed1b63cd4c"}, - {file = "cffi-1.17.0-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:516a405f174fd3b88829eabfe4bb296ac602d6a0f68e0d64d5ac9456194a5b7e"}, - {file = "cffi-1.17.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dec6b307ce928e8e112a6bb9921a1cb00a0e14979bf28b98e084a4b8a742bd9b"}, - {file = "cffi-1.17.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e4094c7b464cf0a858e75cd14b03509e84789abf7b79f8537e6a72152109c76e"}, - {file = "cffi-1.17.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2404f3de742f47cb62d023f0ba7c5a916c9c653d5b368cc966382ae4e57da401"}, - {file = "cffi-1.17.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3aa9d43b02a0c681f0bfbc12d476d47b2b2b6a3f9287f11ee42989a268a1833c"}, - {file = "cffi-1.17.0-cp38-cp38-win32.whl", hash = "sha256:0bb15e7acf8ab35ca8b24b90af52c8b391690ef5c4aec3d31f38f0d37d2cc499"}, - {file = "cffi-1.17.0-cp38-cp38-win_amd64.whl", hash = "sha256:93a7350f6706b31f457c1457d3a3259ff9071a66f312ae64dc024f049055f72c"}, - {file = "cffi-1.17.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:1a2ddbac59dc3716bc79f27906c010406155031a1c801410f1bafff17ea304d2"}, - {file = "cffi-1.17.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:6327b572f5770293fc062a7ec04160e89741e8552bf1c358d1a23eba68166759"}, - {file = "cffi-1.17.0-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:dbc183e7bef690c9abe5ea67b7b60fdbca81aa8da43468287dae7b5c046107d4"}, - {file = "cffi-1.17.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5bdc0f1f610d067c70aa3737ed06e2726fd9d6f7bfee4a351f4c40b6831f4e82"}, - {file = "cffi-1.17.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:6d872186c1617d143969defeadac5a904e6e374183e07977eedef9c07c8953bf"}, - {file = "cffi-1.17.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:0d46ee4764b88b91f16661a8befc6bfb24806d885e27436fdc292ed7e6f6d058"}, - {file = "cffi-1.17.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6f76a90c345796c01d85e6332e81cab6d70de83b829cf1d9762d0a3da59c7932"}, - {file = "cffi-1.17.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:0e60821d312f99d3e1569202518dddf10ae547e799d75aef3bca3a2d9e8ee693"}, - {file = "cffi-1.17.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:eb09b82377233b902d4c3fbeeb7ad731cdab579c6c6fda1f763cd779139e47c3"}, - {file = "cffi-1.17.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:24658baf6224d8f280e827f0a50c46ad819ec8ba380a42448e24459daf809cf4"}, - {file = "cffi-1.17.0-cp39-cp39-win32.whl", hash = "sha256:0fdacad9e0d9fc23e519efd5ea24a70348305e8d7d85ecbb1a5fa66dc834e7fb"}, - {file = "cffi-1.17.0-cp39-cp39-win_amd64.whl", hash = "sha256:7cbc78dc018596315d4e7841c8c3a7ae31cc4d638c9b627f87d52e8abaaf2d29"}, - {file = "cffi-1.17.0.tar.gz", hash = "sha256:f3157624b7558b914cb039fd1af735e5e8049a87c817cc215109ad1c8779df76"}, + {file = "cffi-1.17.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:df8b1c11f177bc2313ec4b2d46baec87a5f3e71fc8b45dab2ee7cae86d9aba14"}, + {file = "cffi-1.17.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:8f2cdc858323644ab277e9bb925ad72ae0e67f69e804f4898c070998d50b1a67"}, + {file = "cffi-1.17.1-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:edae79245293e15384b51f88b00613ba9f7198016a5948b5dddf4917d4d26382"}, + {file = "cffi-1.17.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:45398b671ac6d70e67da8e4224a065cec6a93541bb7aebe1b198a61b58c7b702"}, + {file = "cffi-1.17.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ad9413ccdeda48c5afdae7e4fa2192157e991ff761e7ab8fdd8926f40b160cc3"}, + {file = "cffi-1.17.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5da5719280082ac6bd9aa7becb3938dc9f9cbd57fac7d2871717b1feb0902ab6"}, + {file = "cffi-1.17.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2bb1a08b8008b281856e5971307cc386a8e9c5b625ac297e853d36da6efe9c17"}, + {file = "cffi-1.17.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:045d61c734659cc045141be4bae381a41d89b741f795af1dd018bfb532fd0df8"}, + {file = "cffi-1.17.1-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:6883e737d7d9e4899a8a695e00ec36bd4e5e4f18fabe0aca0efe0a4b44cdb13e"}, + {file = "cffi-1.17.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:6b8b4a92e1c65048ff98cfe1f735ef8f1ceb72e3d5f0c25fdb12087a23da22be"}, + {file = "cffi-1.17.1-cp310-cp310-win32.whl", hash = "sha256:c9c3d058ebabb74db66e431095118094d06abf53284d9c81f27300d0e0d8bc7c"}, + {file = "cffi-1.17.1-cp310-cp310-win_amd64.whl", hash = "sha256:0f048dcf80db46f0098ccac01132761580d28e28bc0f78ae0d58048063317e15"}, + {file = "cffi-1.17.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:a45e3c6913c5b87b3ff120dcdc03f6131fa0065027d0ed7ee6190736a74cd401"}, + {file = "cffi-1.17.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:30c5e0cb5ae493c04c8b42916e52ca38079f1b235c2f8ae5f4527b963c401caf"}, + {file = "cffi-1.17.1-cp311-cp311-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f75c7ab1f9e4aca5414ed4d8e5c0e303a34f4421f8a0d47a4d019ceff0ab6af4"}, + {file = "cffi-1.17.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a1ed2dd2972641495a3ec98445e09766f077aee98a1c896dcb4ad0d303628e41"}, + {file = "cffi-1.17.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:46bf43160c1a35f7ec506d254e5c890f3c03648a4dbac12d624e4490a7046cd1"}, + {file = "cffi-1.17.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a24ed04c8ffd54b0729c07cee15a81d964e6fee0e3d4d342a27b020d22959dc6"}, + {file = "cffi-1.17.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:610faea79c43e44c71e1ec53a554553fa22321b65fae24889706c0a84d4ad86d"}, + {file = "cffi-1.17.1-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:a9b15d491f3ad5d692e11f6b71f7857e7835eb677955c00cc0aefcd0669adaf6"}, + {file = "cffi-1.17.1-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:de2ea4b5833625383e464549fec1bc395c1bdeeb5f25c4a3a82b5a8c756ec22f"}, + {file = "cffi-1.17.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:fc48c783f9c87e60831201f2cce7f3b2e4846bf4d8728eabe54d60700b318a0b"}, + {file = "cffi-1.17.1-cp311-cp311-win32.whl", hash = "sha256:85a950a4ac9c359340d5963966e3e0a94a676bd6245a4b55bc43949eee26a655"}, + {file = "cffi-1.17.1-cp311-cp311-win_amd64.whl", hash = "sha256:caaf0640ef5f5517f49bc275eca1406b0ffa6aa184892812030f04c2abf589a0"}, + {file = "cffi-1.17.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:805b4371bf7197c329fcb3ead37e710d1bca9da5d583f5073b799d5c5bd1eee4"}, + {file = "cffi-1.17.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:733e99bc2df47476e3848417c5a4540522f234dfd4ef3ab7fafdf555b082ec0c"}, + {file = "cffi-1.17.1-cp312-cp312-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1257bdabf294dceb59f5e70c64a3e2f462c30c7ad68092d01bbbfb1c16b1ba36"}, + {file = "cffi-1.17.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:da95af8214998d77a98cc14e3a3bd00aa191526343078b530ceb0bd710fb48a5"}, + {file = "cffi-1.17.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d63afe322132c194cf832bfec0dc69a99fb9bb6bbd550f161a49e9e855cc78ff"}, + {file = "cffi-1.17.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f79fc4fc25f1c8698ff97788206bb3c2598949bfe0fef03d299eb1b5356ada99"}, + {file = "cffi-1.17.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b62ce867176a75d03a665bad002af8e6d54644fad99a3c70905c543130e39d93"}, + {file = "cffi-1.17.1-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:386c8bf53c502fff58903061338ce4f4950cbdcb23e2902d86c0f722b786bbe3"}, + {file = "cffi-1.17.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:4ceb10419a9adf4460ea14cfd6bc43d08701f0835e979bf821052f1805850fe8"}, + {file = "cffi-1.17.1-cp312-cp312-win32.whl", hash = "sha256:a08d7e755f8ed21095a310a693525137cfe756ce62d066e53f502a83dc550f65"}, + {file = "cffi-1.17.1-cp312-cp312-win_amd64.whl", hash = "sha256:51392eae71afec0d0c8fb1a53b204dbb3bcabcb3c9b807eedf3e1e6ccf2de903"}, + {file = "cffi-1.17.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:f3a2b4222ce6b60e2e8b337bb9596923045681d71e5a082783484d845390938e"}, + {file = "cffi-1.17.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:0984a4925a435b1da406122d4d7968dd861c1385afe3b45ba82b750f229811e2"}, + {file = "cffi-1.17.1-cp313-cp313-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d01b12eeeb4427d3110de311e1774046ad344f5b1a7403101878976ecd7a10f3"}, + {file = "cffi-1.17.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:706510fe141c86a69c8ddc029c7910003a17353970cff3b904ff0686a5927683"}, + {file = "cffi-1.17.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:de55b766c7aa2e2a3092c51e0483d700341182f08e67c63630d5b6f200bb28e5"}, + {file = "cffi-1.17.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c59d6e989d07460165cc5ad3c61f9fd8f1b4796eacbd81cee78957842b834af4"}, + {file = "cffi-1.17.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dd398dbc6773384a17fe0d3e7eeb8d1a21c2200473ee6806bb5e6a8e62bb73dd"}, + {file = "cffi-1.17.1-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:3edc8d958eb099c634dace3c7e16560ae474aa3803a5df240542b305d14e14ed"}, + {file = "cffi-1.17.1-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:72e72408cad3d5419375fc87d289076ee319835bdfa2caad331e377589aebba9"}, + {file = "cffi-1.17.1-cp313-cp313-win32.whl", hash = "sha256:e03eab0a8677fa80d646b5ddece1cbeaf556c313dcfac435ba11f107ba117b5d"}, + {file = "cffi-1.17.1-cp313-cp313-win_amd64.whl", hash = "sha256:f6a16c31041f09ead72d69f583767292f750d24913dadacf5756b966aacb3f1a"}, + {file = "cffi-1.17.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:636062ea65bd0195bc012fea9321aca499c0504409f413dc88af450b57ffd03b"}, + {file = "cffi-1.17.1-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c7eac2ef9b63c79431bc4b25f1cd649d7f061a28808cbc6c47b534bd789ef964"}, + {file = "cffi-1.17.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e221cf152cff04059d011ee126477f0d9588303eb57e88923578ace7baad17f9"}, + {file = "cffi-1.17.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:31000ec67d4221a71bd3f67df918b1f88f676f1c3b535a7eb473255fdc0b83fc"}, + {file = "cffi-1.17.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:6f17be4345073b0a7b8ea599688f692ac3ef23ce28e5df79c04de519dbc4912c"}, + {file = "cffi-1.17.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0e2b1fac190ae3ebfe37b979cc1ce69c81f4e4fe5746bb401dca63a9062cdaf1"}, + {file = "cffi-1.17.1-cp38-cp38-win32.whl", hash = "sha256:7596d6620d3fa590f677e9ee430df2958d2d6d6de2feeae5b20e82c00b76fbf8"}, + {file = "cffi-1.17.1-cp38-cp38-win_amd64.whl", hash = "sha256:78122be759c3f8a014ce010908ae03364d00a1f81ab5c7f4a7a5120607ea56e1"}, + {file = "cffi-1.17.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:b2ab587605f4ba0bf81dc0cb08a41bd1c0a5906bd59243d56bad7668a6fc6c16"}, + {file = "cffi-1.17.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:28b16024becceed8c6dfbc75629e27788d8a3f9030691a1dbf9821a128b22c36"}, + {file = "cffi-1.17.1-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1d599671f396c4723d016dbddb72fe8e0397082b0a77a4fab8028923bec050e8"}, + {file = "cffi-1.17.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ca74b8dbe6e8e8263c0ffd60277de77dcee6c837a3d0881d8c1ead7268c9e576"}, + {file = "cffi-1.17.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f7f5baafcc48261359e14bcd6d9bff6d4b28d9103847c9e136694cb0501aef87"}, + {file = "cffi-1.17.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:98e3969bcff97cae1b2def8ba499ea3d6f31ddfdb7635374834cf89a1a08ecf0"}, + {file = "cffi-1.17.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cdf5ce3acdfd1661132f2a9c19cac174758dc2352bfe37d98aa7512c6b7178b3"}, + {file = "cffi-1.17.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:9755e4345d1ec879e3849e62222a18c7174d65a6a92d5b346b1863912168b595"}, + {file = "cffi-1.17.1-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:f1e22e8c4419538cb197e4dd60acc919d7696e5ef98ee4da4e01d3f8cfa4cc5a"}, + {file = "cffi-1.17.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:c03e868a0b3bc35839ba98e74211ed2b05d2119be4e8a0f224fba9384f1fe02e"}, + {file = "cffi-1.17.1-cp39-cp39-win32.whl", hash = "sha256:e31ae45bc2e29f6b2abd0de1cc3b9d5205aa847cafaecb8af1476a609a2f6eb7"}, + {file = "cffi-1.17.1-cp39-cp39-win_amd64.whl", hash = "sha256:d016c76bdd850f3c626af19b0542c9677ba156e4ee4fccfdd7848803533ef662"}, + {file = "cffi-1.17.1.tar.gz", hash = "sha256:1c39c6016c32bc48dd54561950ebd6836e1670f2ae46128f67cf49e789c52824"}, ] [package.dependencies] @@ -573,38 +573,38 @@ toml = ["tomli"] [[package]] name = "cryptography" -version = "43.0.0" +version = "43.0.1" description = "cryptography is a package which provides cryptographic recipes and primitives to Python developers." optional = false python-versions = ">=3.7" files = [ - {file = "cryptography-43.0.0-cp37-abi3-macosx_10_9_universal2.whl", hash = "sha256:64c3f16e2a4fc51c0d06af28441881f98c5d91009b8caaff40cf3548089e9c74"}, - {file = "cryptography-43.0.0-cp37-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3dcdedae5c7710b9f97ac6bba7e1052b95c7083c9d0e9df96e02a1932e777895"}, - {file = "cryptography-43.0.0-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3d9a1eca329405219b605fac09ecfc09ac09e595d6def650a437523fcd08dd22"}, - {file = "cryptography-43.0.0-cp37-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:ea9e57f8ea880eeea38ab5abf9fbe39f923544d7884228ec67d666abd60f5a47"}, - {file = "cryptography-43.0.0-cp37-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:9a8d6802e0825767476f62aafed40532bd435e8a5f7d23bd8b4f5fd04cc80ecf"}, - {file = "cryptography-43.0.0-cp37-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:cc70b4b581f28d0a254d006f26949245e3657d40d8857066c2ae22a61222ef55"}, - {file = "cryptography-43.0.0-cp37-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:4a997df8c1c2aae1e1e5ac49c2e4f610ad037fc5a3aadc7b64e39dea42249431"}, - {file = "cryptography-43.0.0-cp37-abi3-win32.whl", hash = "sha256:6e2b11c55d260d03a8cf29ac9b5e0608d35f08077d8c087be96287f43af3ccdc"}, - {file = "cryptography-43.0.0-cp37-abi3-win_amd64.whl", hash = "sha256:31e44a986ceccec3d0498e16f3d27b2ee5fdf69ce2ab89b52eaad1d2f33d8778"}, - {file = "cryptography-43.0.0-cp39-abi3-macosx_10_9_universal2.whl", hash = "sha256:7b3f5fe74a5ca32d4d0f302ffe6680fcc5c28f8ef0dc0ae8f40c0f3a1b4fca66"}, - {file = "cryptography-43.0.0-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ac1955ce000cb29ab40def14fd1bbfa7af2017cca696ee696925615cafd0dce5"}, - {file = "cryptography-43.0.0-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:299d3da8e00b7e2b54bb02ef58d73cd5f55fb31f33ebbf33bd00d9aa6807df7e"}, - {file = "cryptography-43.0.0-cp39-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:ee0c405832ade84d4de74b9029bedb7b31200600fa524d218fc29bfa371e97f5"}, - {file = "cryptography-43.0.0-cp39-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:cb013933d4c127349b3948aa8aaf2f12c0353ad0eccd715ca789c8a0f671646f"}, - {file = "cryptography-43.0.0-cp39-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:fdcb265de28585de5b859ae13e3846a8e805268a823a12a4da2597f1f5afc9f0"}, - {file = "cryptography-43.0.0-cp39-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:2905ccf93a8a2a416f3ec01b1a7911c3fe4073ef35640e7ee5296754e30b762b"}, - {file = "cryptography-43.0.0-cp39-abi3-win32.whl", hash = "sha256:47ca71115e545954e6c1d207dd13461ab81f4eccfcb1345eac874828b5e3eaaf"}, - {file = "cryptography-43.0.0-cp39-abi3-win_amd64.whl", hash = "sha256:0663585d02f76929792470451a5ba64424acc3cd5227b03921dab0e2f27b1709"}, - {file = "cryptography-43.0.0-pp310-pypy310_pp73-macosx_10_9_x86_64.whl", hash = "sha256:2c6d112bf61c5ef44042c253e4859b3cbbb50df2f78fa8fae6747a7814484a70"}, - {file = "cryptography-43.0.0-pp310-pypy310_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:844b6d608374e7d08f4f6e6f9f7b951f9256db41421917dfb2d003dde4cd6b66"}, - {file = "cryptography-43.0.0-pp310-pypy310_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:51956cf8730665e2bdf8ddb8da0056f699c1a5715648c1b0144670c1ba00b48f"}, - {file = "cryptography-43.0.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:aae4d918f6b180a8ab8bf6511a419473d107df4dbb4225c7b48c5c9602c38c7f"}, - {file = "cryptography-43.0.0-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:232ce02943a579095a339ac4b390fbbe97f5b5d5d107f8a08260ea2768be8cc2"}, - {file = "cryptography-43.0.0-pp39-pypy39_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:5bcb8a5620008a8034d39bce21dc3e23735dfdb6a33a06974739bfa04f853947"}, - {file = "cryptography-43.0.0-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:08a24a7070b2b6804c1940ff0f910ff728932a9d0e80e7814234269f9d46d069"}, - {file = "cryptography-43.0.0-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:e9c5266c432a1e23738d178e51c2c7a5e2ddf790f248be939448c0ba2021f9d1"}, - {file = "cryptography-43.0.0.tar.gz", hash = "sha256:b88075ada2d51aa9f18283532c9f60e72170041bba88d7f37e49cbb10275299e"}, + {file = "cryptography-43.0.1-cp37-abi3-macosx_10_9_universal2.whl", hash = "sha256:8385d98f6a3bf8bb2d65a73e17ed87a3ba84f6991c155691c51112075f9ffc5d"}, + {file = "cryptography-43.0.1-cp37-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:27e613d7077ac613e399270253259d9d53872aaf657471473ebfc9a52935c062"}, + {file = "cryptography-43.0.1-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:68aaecc4178e90719e95298515979814bda0cbada1256a4485414860bd7ab962"}, + {file = "cryptography-43.0.1-cp37-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:de41fd81a41e53267cb020bb3a7212861da53a7d39f863585d13ea11049cf277"}, + {file = "cryptography-43.0.1-cp37-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:f98bf604c82c416bc829e490c700ca1553eafdf2912a91e23a79d97d9801372a"}, + {file = "cryptography-43.0.1-cp37-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:61ec41068b7b74268fa86e3e9e12b9f0c21fcf65434571dbb13d954bceb08042"}, + {file = "cryptography-43.0.1-cp37-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:014f58110f53237ace6a408b5beb6c427b64e084eb451ef25a28308270086494"}, + {file = "cryptography-43.0.1-cp37-abi3-win32.whl", hash = "sha256:2bd51274dcd59f09dd952afb696bf9c61a7a49dfc764c04dd33ef7a6b502a1e2"}, + {file = "cryptography-43.0.1-cp37-abi3-win_amd64.whl", hash = "sha256:666ae11966643886c2987b3b721899d250855718d6d9ce41b521252a17985f4d"}, + {file = "cryptography-43.0.1-cp39-abi3-macosx_10_9_universal2.whl", hash = "sha256:ac119bb76b9faa00f48128b7f5679e1d8d437365c5d26f1c2c3f0da4ce1b553d"}, + {file = "cryptography-43.0.1-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1bbcce1a551e262dfbafb6e6252f1ae36a248e615ca44ba302df077a846a8806"}, + {file = "cryptography-43.0.1-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:58d4e9129985185a06d849aa6df265bdd5a74ca6e1b736a77959b498e0505b85"}, + {file = "cryptography-43.0.1-cp39-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:d03a475165f3134f773d1388aeb19c2d25ba88b6a9733c5c590b9ff7bbfa2e0c"}, + {file = "cryptography-43.0.1-cp39-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:511f4273808ab590912a93ddb4e3914dfd8a388fed883361b02dea3791f292e1"}, + {file = "cryptography-43.0.1-cp39-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:80eda8b3e173f0f247f711eef62be51b599b5d425c429b5d4ca6a05e9e856baa"}, + {file = "cryptography-43.0.1-cp39-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:38926c50cff6f533f8a2dae3d7f19541432610d114a70808f0926d5aaa7121e4"}, + {file = "cryptography-43.0.1-cp39-abi3-win32.whl", hash = "sha256:a575913fb06e05e6b4b814d7f7468c2c660e8bb16d8d5a1faf9b33ccc569dd47"}, + {file = "cryptography-43.0.1-cp39-abi3-win_amd64.whl", hash = "sha256:d75601ad10b059ec832e78823b348bfa1a59f6b8d545db3a24fd44362a1564cb"}, + {file = "cryptography-43.0.1-pp310-pypy310_pp73-macosx_10_9_x86_64.whl", hash = "sha256:ea25acb556320250756e53f9e20a4177515f012c9eaea17eb7587a8c4d8ae034"}, + {file = "cryptography-43.0.1-pp310-pypy310_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:c1332724be35d23a854994ff0b66530119500b6053d0bd3363265f7e5e77288d"}, + {file = "cryptography-43.0.1-pp310-pypy310_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:fba1007b3ef89946dbbb515aeeb41e30203b004f0b4b00e5e16078b518563289"}, + {file = "cryptography-43.0.1-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:5b43d1ea6b378b54a1dc99dd8a2b5be47658fe9a7ce0a58ff0b55f4b43ef2b84"}, + {file = "cryptography-43.0.1-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:88cce104c36870d70c49c7c8fd22885875d950d9ee6ab54df2745f83ba0dc365"}, + {file = "cryptography-43.0.1-pp39-pypy39_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:9d3cdb25fa98afdd3d0892d132b8d7139e2c087da1712041f6b762e4f807cc96"}, + {file = "cryptography-43.0.1-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:e710bf40870f4db63c3d7d929aa9e09e4e7ee219e703f949ec4073b4294f6172"}, + {file = "cryptography-43.0.1-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:7c05650fe8023c5ed0d46793d4b7d7e6cd9c04e68eabe5b0aeea836e37bdcec2"}, + {file = "cryptography-43.0.1.tar.gz", hash = "sha256:203e92a75716d8cfb491dc47c79e17d0d9207ccffcbcb35f598fbe463ae3444d"}, ] [package.dependencies] @@ -617,7 +617,7 @@ nox = ["nox"] pep8test = ["check-sdist", "click", "mypy", "ruff"] sdist = ["build"] ssh = ["bcrypt (>=3.1.5)"] -test = ["certifi", "cryptography-vectors (==43.0.0)", "pretend", "pytest (>=6.2.0)", "pytest-benchmark", "pytest-cov", "pytest-xdist"] +test = ["certifi", "cryptography-vectors (==43.0.1)", "pretend", "pytest (>=6.2.0)", "pytest-benchmark", "pytest-cov", "pytest-xdist"] test-randomorder = ["pytest-randomly"] [[package]] @@ -1146,12 +1146,14 @@ files = [ [[package]] name = "ogmios" -version = "1.1.1" +version = "1.2.1" description = "Ogmios is a lightweight bridge interface for cardano-node. It offers a WebSockets API that enables local clients to speak Ouroboros' mini-protocols via JSON/RPC. ogmios-python is an Ogmios client written in Python designed for ease of use." optional = false python-versions = ">=3.8" -files = [] -develop = false +files = [ + {file = "ogmios-1.2.1-py3-none-any.whl", hash = "sha256:a0e1d87f9fd7b224556b30349d8abce2fcff3ce1c9a92e292f9a5c13f1e140ce"}, + {file = "ogmios-1.2.1.tar.gz", hash = "sha256:07d7086ca8ddb4ca38e9c61edda53ff4acc0d156d15ea056eac11cd05390d9ec"}, +] [package.dependencies] cachetools = "*" @@ -1159,18 +1161,13 @@ cardano-tools = "*" coloredlogs = "*" orjson = "*" pydantic = ">=2.0" +setuptools = ">=69.5.1" websockets = "*" [package.extras] dev = ["black", "datamodel-code-generator", "flake8-pyproject", "isort", "sphinx", "sphinx-rtd-theme"] testing = ["coverage[toml] (>=6.5)", "pycardano", "pytest"] -[package.source] -type = "git" -url = "https://gitlab.com/viperscience/ogmios-python.git" -reference = "HEAD" -resolved_reference = "0b713e78839341d92828340a5552ef8dd1c6224b" - [[package]] name = "orjson" version = "3.10.7" @@ -1289,19 +1286,19 @@ ptyprocess = ">=0.5" [[package]] name = "platformdirs" -version = "4.2.2" +version = "4.3.2" description = "A small Python package for determining appropriate platform-specific dirs, e.g. a `user data dir`." optional = false python-versions = ">=3.8" files = [ - {file = "platformdirs-4.2.2-py3-none-any.whl", hash = "sha256:2d7a1657e36a80ea911db832a8a6ece5ee53d8de21edd5cc5879af6530b1bfee"}, - {file = "platformdirs-4.2.2.tar.gz", hash = "sha256:38b7b51f512eed9e84a22788b4bce1de17c0adb134d6becb09836e37d8654cd3"}, + {file = "platformdirs-4.3.2-py3-none-any.whl", hash = "sha256:eb1c8582560b34ed4ba105009a4badf7f6f85768b30126f351328507b2beb617"}, + {file = "platformdirs-4.3.2.tar.gz", hash = "sha256:9e5e27a08aa095dd127b9f2e764d74254f482fef22b0970773bfba79d091ab8c"}, ] [package.extras] -docs = ["furo (>=2023.9.10)", "proselint (>=0.13)", "sphinx (>=7.2.6)", "sphinx-autodoc-typehints (>=1.25.2)"] -test = ["appdirs (==1.4.4)", "covdefaults (>=2.3)", "pytest (>=7.4.3)", "pytest-cov (>=4.1)", "pytest-mock (>=3.12)"] -type = ["mypy (>=1.8)"] +docs = ["furo (>=2024.8.6)", "proselint (>=0.14)", "sphinx (>=8.0.2)", "sphinx-autodoc-typehints (>=2.4)"] +test = ["appdirs (==1.4.4)", "covdefaults (>=2.3)", "pytest (>=8.3.2)", "pytest-cov (>=5)", "pytest-mock (>=3.14)"] +type = ["mypy (>=1.11.2)"] [[package]] name = "pluggy" @@ -1375,122 +1372,123 @@ files = [ [[package]] name = "pydantic" -version = "2.8.2" +version = "2.9.0" description = "Data validation using Python type hints" optional = false python-versions = ">=3.8" files = [ - {file = "pydantic-2.8.2-py3-none-any.whl", hash = "sha256:73ee9fddd406dc318b885c7a2eab8a6472b68b8fb5ba8150949fc3db939f23c8"}, - {file = "pydantic-2.8.2.tar.gz", hash = "sha256:6f62c13d067b0755ad1c21a34bdd06c0c12625a22b0fc09c6b149816604f7c2a"}, + {file = "pydantic-2.9.0-py3-none-any.whl", hash = "sha256:f66a7073abd93214a20c5f7b32d56843137a7a2e70d02111f3be287035c45370"}, + {file = "pydantic-2.9.0.tar.gz", hash = "sha256:c7a8a9fdf7d100afa49647eae340e2d23efa382466a8d177efcd1381e9be5598"}, ] [package.dependencies] annotated-types = ">=0.4.0" -pydantic-core = "2.20.1" +pydantic-core = "2.23.2" typing-extensions = [ {version = ">=4.12.2", markers = "python_version >= \"3.13\""}, {version = ">=4.6.1", markers = "python_version < \"3.13\""}, ] +tzdata = {version = "*", markers = "python_version >= \"3.9\""} [package.extras] email = ["email-validator (>=2.0.0)"] [[package]] name = "pydantic-core" -version = "2.20.1" +version = "2.23.2" description = "Core functionality for Pydantic validation and serialization" optional = false python-versions = ">=3.8" files = [ - {file = "pydantic_core-2.20.1-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:3acae97ffd19bf091c72df4d726d552c473f3576409b2a7ca36b2f535ffff4a3"}, - {file = "pydantic_core-2.20.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:41f4c96227a67a013e7de5ff8f20fb496ce573893b7f4f2707d065907bffdbd6"}, - {file = "pydantic_core-2.20.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5f239eb799a2081495ea659d8d4a43a8f42cd1fe9ff2e7e436295c38a10c286a"}, - {file = "pydantic_core-2.20.1-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:53e431da3fc53360db73eedf6f7124d1076e1b4ee4276b36fb25514544ceb4a3"}, - {file = "pydantic_core-2.20.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f1f62b2413c3a0e846c3b838b2ecd6c7a19ec6793b2a522745b0869e37ab5bc1"}, - {file = "pydantic_core-2.20.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5d41e6daee2813ecceea8eda38062d69e280b39df793f5a942fa515b8ed67953"}, - {file = "pydantic_core-2.20.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3d482efec8b7dc6bfaedc0f166b2ce349df0011f5d2f1f25537ced4cfc34fd98"}, - {file = "pydantic_core-2.20.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:e93e1a4b4b33daed65d781a57a522ff153dcf748dee70b40c7258c5861e1768a"}, - {file = "pydantic_core-2.20.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:e7c4ea22b6739b162c9ecaaa41d718dfad48a244909fe7ef4b54c0b530effc5a"}, - {file = "pydantic_core-2.20.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:4f2790949cf385d985a31984907fecb3896999329103df4e4983a4a41e13e840"}, - {file = "pydantic_core-2.20.1-cp310-none-win32.whl", hash = "sha256:5e999ba8dd90e93d57410c5e67ebb67ffcaadcea0ad973240fdfd3a135506250"}, - {file = "pydantic_core-2.20.1-cp310-none-win_amd64.whl", hash = "sha256:512ecfbefef6dac7bc5eaaf46177b2de58cdf7acac8793fe033b24ece0b9566c"}, - {file = "pydantic_core-2.20.1-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:d2a8fa9d6d6f891f3deec72f5cc668e6f66b188ab14bb1ab52422fe8e644f312"}, - {file = "pydantic_core-2.20.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:175873691124f3d0da55aeea1d90660a6ea7a3cfea137c38afa0a5ffabe37b88"}, - {file = "pydantic_core-2.20.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:37eee5b638f0e0dcd18d21f59b679686bbd18917b87db0193ae36f9c23c355fc"}, - {file = "pydantic_core-2.20.1-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:25e9185e2d06c16ee438ed39bf62935ec436474a6ac4f9358524220f1b236e43"}, - {file = "pydantic_core-2.20.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:150906b40ff188a3260cbee25380e7494ee85048584998c1e66df0c7a11c17a6"}, - {file = "pydantic_core-2.20.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8ad4aeb3e9a97286573c03df758fc7627aecdd02f1da04516a86dc159bf70121"}, - {file = "pydantic_core-2.20.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d3f3ed29cd9f978c604708511a1f9c2fdcb6c38b9aae36a51905b8811ee5cbf1"}, - {file = "pydantic_core-2.20.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:b0dae11d8f5ded51699c74d9548dcc5938e0804cc8298ec0aa0da95c21fff57b"}, - {file = "pydantic_core-2.20.1-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:faa6b09ee09433b87992fb5a2859efd1c264ddc37280d2dd5db502126d0e7f27"}, - {file = "pydantic_core-2.20.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:9dc1b507c12eb0481d071f3c1808f0529ad41dc415d0ca11f7ebfc666e66a18b"}, - {file = "pydantic_core-2.20.1-cp311-none-win32.whl", hash = "sha256:fa2fddcb7107e0d1808086ca306dcade7df60a13a6c347a7acf1ec139aa6789a"}, - {file = "pydantic_core-2.20.1-cp311-none-win_amd64.whl", hash = "sha256:40a783fb7ee353c50bd3853e626f15677ea527ae556429453685ae32280c19c2"}, - {file = "pydantic_core-2.20.1-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:595ba5be69b35777474fa07f80fc260ea71255656191adb22a8c53aba4479231"}, - {file = "pydantic_core-2.20.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:a4f55095ad087474999ee28d3398bae183a66be4823f753cd7d67dd0153427c9"}, - {file = "pydantic_core-2.20.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f9aa05d09ecf4c75157197f27cdc9cfaeb7c5f15021c6373932bf3e124af029f"}, - {file = "pydantic_core-2.20.1-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:e97fdf088d4b31ff4ba35db26d9cc472ac7ef4a2ff2badeabf8d727b3377fc52"}, - {file = "pydantic_core-2.20.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:bc633a9fe1eb87e250b5c57d389cf28998e4292336926b0b6cdaee353f89a237"}, - {file = "pydantic_core-2.20.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d573faf8eb7e6b1cbbcb4f5b247c60ca8be39fe2c674495df0eb4318303137fe"}, - {file = "pydantic_core-2.20.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:26dc97754b57d2fd00ac2b24dfa341abffc380b823211994c4efac7f13b9e90e"}, - {file = "pydantic_core-2.20.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:33499e85e739a4b60c9dac710c20a08dc73cb3240c9a0e22325e671b27b70d24"}, - {file = "pydantic_core-2.20.1-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:bebb4d6715c814597f85297c332297c6ce81e29436125ca59d1159b07f423eb1"}, - {file = "pydantic_core-2.20.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:516d9227919612425c8ef1c9b869bbbee249bc91912c8aaffb66116c0b447ebd"}, - {file = "pydantic_core-2.20.1-cp312-none-win32.whl", hash = "sha256:469f29f9093c9d834432034d33f5fe45699e664f12a13bf38c04967ce233d688"}, - {file = "pydantic_core-2.20.1-cp312-none-win_amd64.whl", hash = "sha256:035ede2e16da7281041f0e626459bcae33ed998cca6a0a007a5ebb73414ac72d"}, - {file = "pydantic_core-2.20.1-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:0827505a5c87e8aa285dc31e9ec7f4a17c81a813d45f70b1d9164e03a813a686"}, - {file = "pydantic_core-2.20.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:19c0fa39fa154e7e0b7f82f88ef85faa2a4c23cc65aae2f5aea625e3c13c735a"}, - {file = "pydantic_core-2.20.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4aa223cd1e36b642092c326d694d8bf59b71ddddc94cdb752bbbb1c5c91d833b"}, - {file = "pydantic_core-2.20.1-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:c336a6d235522a62fef872c6295a42ecb0c4e1d0f1a3e500fe949415761b8a19"}, - {file = "pydantic_core-2.20.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:7eb6a0587eded33aeefea9f916899d42b1799b7b14b8f8ff2753c0ac1741edac"}, - {file = "pydantic_core-2.20.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:70c8daf4faca8da5a6d655f9af86faf6ec2e1768f4b8b9d0226c02f3d6209703"}, - {file = "pydantic_core-2.20.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e9fa4c9bf273ca41f940bceb86922a7667cd5bf90e95dbb157cbb8441008482c"}, - {file = "pydantic_core-2.20.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:11b71d67b4725e7e2a9f6e9c0ac1239bbc0c48cce3dc59f98635efc57d6dac83"}, - {file = "pydantic_core-2.20.1-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:270755f15174fb983890c49881e93f8f1b80f0b5e3a3cc1394a255706cabd203"}, - {file = "pydantic_core-2.20.1-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:c81131869240e3e568916ef4c307f8b99583efaa60a8112ef27a366eefba8ef0"}, - {file = "pydantic_core-2.20.1-cp313-none-win32.whl", hash = "sha256:b91ced227c41aa29c672814f50dbb05ec93536abf8f43cd14ec9521ea09afe4e"}, - {file = "pydantic_core-2.20.1-cp313-none-win_amd64.whl", hash = "sha256:65db0f2eefcaad1a3950f498aabb4875c8890438bc80b19362cf633b87a8ab20"}, - {file = "pydantic_core-2.20.1-cp38-cp38-macosx_10_12_x86_64.whl", hash = "sha256:4745f4ac52cc6686390c40eaa01d48b18997cb130833154801a442323cc78f91"}, - {file = "pydantic_core-2.20.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:a8ad4c766d3f33ba8fd692f9aa297c9058970530a32c728a2c4bfd2616d3358b"}, - {file = "pydantic_core-2.20.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:41e81317dd6a0127cabce83c0c9c3fbecceae981c8391e6f1dec88a77c8a569a"}, - {file = "pydantic_core-2.20.1-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:04024d270cf63f586ad41fff13fde4311c4fc13ea74676962c876d9577bcc78f"}, - {file = "pydantic_core-2.20.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:eaad4ff2de1c3823fddf82f41121bdf453d922e9a238642b1dedb33c4e4f98ad"}, - {file = "pydantic_core-2.20.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:26ab812fa0c845df815e506be30337e2df27e88399b985d0bb4e3ecfe72df31c"}, - {file = "pydantic_core-2.20.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3c5ebac750d9d5f2706654c638c041635c385596caf68f81342011ddfa1e5598"}, - {file = "pydantic_core-2.20.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:2aafc5a503855ea5885559eae883978c9b6d8c8993d67766ee73d82e841300dd"}, - {file = "pydantic_core-2.20.1-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:4868f6bd7c9d98904b748a2653031fc9c2f85b6237009d475b1008bfaeb0a5aa"}, - {file = "pydantic_core-2.20.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:aa2f457b4af386254372dfa78a2eda2563680d982422641a85f271c859df1987"}, - {file = "pydantic_core-2.20.1-cp38-none-win32.whl", hash = "sha256:225b67a1f6d602de0ce7f6c1c3ae89a4aa25d3de9be857999e9124f15dab486a"}, - {file = "pydantic_core-2.20.1-cp38-none-win_amd64.whl", hash = "sha256:6b507132dcfc0dea440cce23ee2182c0ce7aba7054576efc65634f080dbe9434"}, - {file = "pydantic_core-2.20.1-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:b03f7941783b4c4a26051846dea594628b38f6940a2fdc0df00b221aed39314c"}, - {file = "pydantic_core-2.20.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:1eedfeb6089ed3fad42e81a67755846ad4dcc14d73698c120a82e4ccf0f1f9f6"}, - {file = "pydantic_core-2.20.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:635fee4e041ab9c479e31edda27fcf966ea9614fff1317e280d99eb3e5ab6fe2"}, - {file = "pydantic_core-2.20.1-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:77bf3ac639c1ff567ae3b47f8d4cc3dc20f9966a2a6dd2311dcc055d3d04fb8a"}, - {file = "pydantic_core-2.20.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:7ed1b0132f24beeec5a78b67d9388656d03e6a7c837394f99257e2d55b461611"}, - {file = "pydantic_core-2.20.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c6514f963b023aeee506678a1cf821fe31159b925c4b76fe2afa94cc70b3222b"}, - {file = "pydantic_core-2.20.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:10d4204d8ca33146e761c79f83cc861df20e7ae9f6487ca290a97702daf56006"}, - {file = "pydantic_core-2.20.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:2d036c7187b9422ae5b262badb87a20a49eb6c5238b2004e96d4da1231badef1"}, - {file = "pydantic_core-2.20.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:9ebfef07dbe1d93efb94b4700f2d278494e9162565a54f124c404a5656d7ff09"}, - {file = "pydantic_core-2.20.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:6b9d9bb600328a1ce523ab4f454859e9d439150abb0906c5a1983c146580ebab"}, - {file = "pydantic_core-2.20.1-cp39-none-win32.whl", hash = "sha256:784c1214cb6dd1e3b15dd8b91b9a53852aed16671cc3fbe4786f4f1db07089e2"}, - {file = "pydantic_core-2.20.1-cp39-none-win_amd64.whl", hash = "sha256:d2fe69c5434391727efa54b47a1e7986bb0186e72a41b203df8f5b0a19a4f669"}, - {file = "pydantic_core-2.20.1-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:a45f84b09ac9c3d35dfcf6a27fd0634d30d183205230a0ebe8373a0e8cfa0906"}, - {file = "pydantic_core-2.20.1-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:d02a72df14dfdbaf228424573a07af10637bd490f0901cee872c4f434a735b94"}, - {file = "pydantic_core-2.20.1-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d2b27e6af28f07e2f195552b37d7d66b150adbaa39a6d327766ffd695799780f"}, - {file = "pydantic_core-2.20.1-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:084659fac3c83fd674596612aeff6041a18402f1e1bc19ca39e417d554468482"}, - {file = "pydantic_core-2.20.1-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:242b8feb3c493ab78be289c034a1f659e8826e2233786e36f2893a950a719bb6"}, - {file = "pydantic_core-2.20.1-pp310-pypy310_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:38cf1c40a921d05c5edc61a785c0ddb4bed67827069f535d794ce6bcded919fc"}, - {file = "pydantic_core-2.20.1-pp310-pypy310_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:e0bbdd76ce9aa5d4209d65f2b27fc6e5ef1312ae6c5333c26db3f5ade53a1e99"}, - {file = "pydantic_core-2.20.1-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:254ec27fdb5b1ee60684f91683be95e5133c994cc54e86a0b0963afa25c8f8a6"}, - {file = "pydantic_core-2.20.1-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:407653af5617f0757261ae249d3fba09504d7a71ab36ac057c938572d1bc9331"}, - {file = "pydantic_core-2.20.1-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:c693e916709c2465b02ca0ad7b387c4f8423d1db7b4649c551f27a529181c5ad"}, - {file = "pydantic_core-2.20.1-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5b5ff4911aea936a47d9376fd3ab17e970cc543d1b68921886e7f64bd28308d1"}, - {file = "pydantic_core-2.20.1-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:177f55a886d74f1808763976ac4efd29b7ed15c69f4d838bbd74d9d09cf6fa86"}, - {file = "pydantic_core-2.20.1-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:964faa8a861d2664f0c7ab0c181af0bea66098b1919439815ca8803ef136fc4e"}, - {file = "pydantic_core-2.20.1-pp39-pypy39_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:4dd484681c15e6b9a977c785a345d3e378d72678fd5f1f3c0509608da24f2ac0"}, - {file = "pydantic_core-2.20.1-pp39-pypy39_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:f6d6cff3538391e8486a431569b77921adfcdef14eb18fbf19b7c0a5294d4e6a"}, - {file = "pydantic_core-2.20.1-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:a6d511cc297ff0883bc3708b465ff82d7560193169a8b93260f74ecb0a5e08a7"}, - {file = "pydantic_core-2.20.1.tar.gz", hash = "sha256:26ca695eeee5f9f1aeeb211ffc12f10bcb6f71e2989988fda61dabd65db878d4"}, + {file = "pydantic_core-2.23.2-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:7d0324a35ab436c9d768753cbc3c47a865a2cbc0757066cb864747baa61f6ece"}, + {file = "pydantic_core-2.23.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:276ae78153a94b664e700ac362587c73b84399bd1145e135287513442e7dfbc7"}, + {file = "pydantic_core-2.23.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:964c7aa318da542cdcc60d4a648377ffe1a2ef0eb1e996026c7f74507b720a78"}, + {file = "pydantic_core-2.23.2-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:1cf842265a3a820ebc6388b963ead065f5ce8f2068ac4e1c713ef77a67b71f7c"}, + {file = "pydantic_core-2.23.2-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ae90b9e50fe1bd115b24785e962b51130340408156d34d67b5f8f3fa6540938e"}, + {file = "pydantic_core-2.23.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8ae65fdfb8a841556b52935dfd4c3f79132dc5253b12c0061b96415208f4d622"}, + {file = "pydantic_core-2.23.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5c8aa40f6ca803f95b1c1c5aeaee6237b9e879e4dfb46ad713229a63651a95fb"}, + {file = "pydantic_core-2.23.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:c53100c8ee5a1e102766abde2158077d8c374bee0639201f11d3032e3555dfbc"}, + {file = "pydantic_core-2.23.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:d6b9dd6aa03c812017411734e496c44fef29b43dba1e3dd1fa7361bbacfc1354"}, + {file = "pydantic_core-2.23.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:b18cf68255a476b927910c6873d9ed00da692bb293c5b10b282bd48a0afe3ae2"}, + {file = "pydantic_core-2.23.2-cp310-none-win32.whl", hash = "sha256:e460475719721d59cd54a350c1f71c797c763212c836bf48585478c5514d2854"}, + {file = "pydantic_core-2.23.2-cp310-none-win_amd64.whl", hash = "sha256:5f3cf3721eaf8741cffaf092487f1ca80831202ce91672776b02b875580e174a"}, + {file = "pydantic_core-2.23.2-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:7ce8e26b86a91e305858e018afc7a6e932f17428b1eaa60154bd1f7ee888b5f8"}, + {file = "pydantic_core-2.23.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:7e9b24cca4037a561422bf5dc52b38d390fb61f7bfff64053ce1b72f6938e6b2"}, + {file = "pydantic_core-2.23.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:753294d42fb072aa1775bfe1a2ba1012427376718fa4c72de52005a3d2a22178"}, + {file = "pydantic_core-2.23.2-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:257d6a410a0d8aeb50b4283dea39bb79b14303e0fab0f2b9d617701331ed1515"}, + {file = "pydantic_core-2.23.2-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c8319e0bd6a7b45ad76166cc3d5d6a36c97d0c82a196f478c3ee5346566eebfd"}, + {file = "pydantic_core-2.23.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7a05c0240f6c711eb381ac392de987ee974fa9336071fb697768dfdb151345ce"}, + {file = "pydantic_core-2.23.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8d5b0ff3218858859910295df6953d7bafac3a48d5cd18f4e3ed9999efd2245f"}, + {file = "pydantic_core-2.23.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:96ef39add33ff58cd4c112cbac076726b96b98bb8f1e7f7595288dcfb2f10b57"}, + {file = "pydantic_core-2.23.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:0102e49ac7d2df3379ef8d658d3bc59d3d769b0bdb17da189b75efa861fc07b4"}, + {file = "pydantic_core-2.23.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:a6612c2a844043e4d10a8324c54cdff0042c558eef30bd705770793d70b224aa"}, + {file = "pydantic_core-2.23.2-cp311-none-win32.whl", hash = "sha256:caffda619099cfd4f63d48462f6aadbecee3ad9603b4b88b60cb821c1b258576"}, + {file = "pydantic_core-2.23.2-cp311-none-win_amd64.whl", hash = "sha256:6f80fba4af0cb1d2344869d56430e304a51396b70d46b91a55ed4959993c0589"}, + {file = "pydantic_core-2.23.2-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:4c83c64d05ffbbe12d4e8498ab72bdb05bcc1026340a4a597dc647a13c1605ec"}, + {file = "pydantic_core-2.23.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:6294907eaaccf71c076abdd1c7954e272efa39bb043161b4b8aa1cd76a16ce43"}, + {file = "pydantic_core-2.23.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4a801c5e1e13272e0909c520708122496647d1279d252c9e6e07dac216accc41"}, + {file = "pydantic_core-2.23.2-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:cc0c316fba3ce72ac3ab7902a888b9dc4979162d320823679da270c2d9ad0cad"}, + {file = "pydantic_core-2.23.2-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:6b06c5d4e8701ac2ba99a2ef835e4e1b187d41095a9c619c5b185c9068ed2a49"}, + {file = "pydantic_core-2.23.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:82764c0bd697159fe9947ad59b6db6d7329e88505c8f98990eb07e84cc0a5d81"}, + {file = "pydantic_core-2.23.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2b1a195efd347ede8bcf723e932300292eb13a9d2a3c1f84eb8f37cbbc905b7f"}, + {file = "pydantic_core-2.23.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:b7efb12e5071ad8d5b547487bdad489fbd4a5a35a0fc36a1941517a6ad7f23e0"}, + {file = "pydantic_core-2.23.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:5dd0ec5f514ed40e49bf961d49cf1bc2c72e9b50f29a163b2cc9030c6742aa73"}, + {file = "pydantic_core-2.23.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:820f6ee5c06bc868335e3b6e42d7ef41f50dfb3ea32fbd523ab679d10d8741c0"}, + {file = "pydantic_core-2.23.2-cp312-none-win32.whl", hash = "sha256:3713dc093d5048bfaedbba7a8dbc53e74c44a140d45ede020dc347dda18daf3f"}, + {file = "pydantic_core-2.23.2-cp312-none-win_amd64.whl", hash = "sha256:e1895e949f8849bc2757c0dbac28422a04be031204df46a56ab34bcf98507342"}, + {file = "pydantic_core-2.23.2-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:da43cbe593e3c87d07108d0ebd73771dc414488f1f91ed2e204b0370b94b37ac"}, + {file = "pydantic_core-2.23.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:64d094ea1aa97c6ded4748d40886076a931a8bf6f61b6e43e4a1041769c39dd2"}, + {file = "pydantic_core-2.23.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:084414ffe9a85a52940b49631321d636dadf3576c30259607b75516d131fecd0"}, + {file = "pydantic_core-2.23.2-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:043ef8469f72609c4c3a5e06a07a1f713d53df4d53112c6d49207c0bd3c3bd9b"}, + {file = "pydantic_core-2.23.2-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3649bd3ae6a8ebea7dc381afb7f3c6db237fc7cebd05c8ac36ca8a4187b03b30"}, + {file = "pydantic_core-2.23.2-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:6db09153d8438425e98cdc9a289c5fade04a5d2128faff8f227c459da21b9703"}, + {file = "pydantic_core-2.23.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5668b3173bb0b2e65020b60d83f5910a7224027232c9f5dc05a71a1deac9f960"}, + {file = "pydantic_core-2.23.2-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:1c7b81beaf7c7ebde978377dc53679c6cba0e946426fc7ade54251dfe24a7604"}, + {file = "pydantic_core-2.23.2-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:ae579143826c6f05a361d9546446c432a165ecf1c0b720bbfd81152645cb897d"}, + {file = "pydantic_core-2.23.2-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:19f1352fe4b248cae22a89268720fc74e83f008057a652894f08fa931e77dced"}, + {file = "pydantic_core-2.23.2-cp313-none-win32.whl", hash = "sha256:e1a79ad49f346aa1a2921f31e8dbbab4d64484823e813a002679eaa46cba39e1"}, + {file = "pydantic_core-2.23.2-cp313-none-win_amd64.whl", hash = "sha256:582871902e1902b3c8e9b2c347f32a792a07094110c1bca6c2ea89b90150caac"}, + {file = "pydantic_core-2.23.2-cp38-cp38-macosx_10_12_x86_64.whl", hash = "sha256:743e5811b0c377eb830150d675b0847a74a44d4ad5ab8845923d5b3a756d8100"}, + {file = "pydantic_core-2.23.2-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:6650a7bbe17a2717167e3e23c186849bae5cef35d38949549f1c116031b2b3aa"}, + {file = "pydantic_core-2.23.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:56e6a12ec8d7679f41b3750ffa426d22b44ef97be226a9bab00a03365f217b2b"}, + {file = "pydantic_core-2.23.2-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:810ca06cca91de9107718dc83d9ac4d2e86efd6c02cba49a190abcaf33fb0472"}, + {file = "pydantic_core-2.23.2-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:785e7f517ebb9890813d31cb5d328fa5eda825bb205065cde760b3150e4de1f7"}, + {file = "pydantic_core-2.23.2-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3ef71ec876fcc4d3bbf2ae81961959e8d62f8d74a83d116668409c224012e3af"}, + {file = "pydantic_core-2.23.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d50ac34835c6a4a0d456b5db559b82047403c4317b3bc73b3455fefdbdc54b0a"}, + {file = "pydantic_core-2.23.2-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:16b25a4a120a2bb7dab51b81e3d9f3cde4f9a4456566c403ed29ac81bf49744f"}, + {file = "pydantic_core-2.23.2-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:41ae8537ad371ec018e3c5da0eb3f3e40ee1011eb9be1da7f965357c4623c501"}, + {file = "pydantic_core-2.23.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:07049ec9306ec64e955b2e7c40c8d77dd78ea89adb97a2013d0b6e055c5ee4c5"}, + {file = "pydantic_core-2.23.2-cp38-none-win32.whl", hash = "sha256:086c5db95157dc84c63ff9d96ebb8856f47ce113c86b61065a066f8efbe80acf"}, + {file = "pydantic_core-2.23.2-cp38-none-win_amd64.whl", hash = "sha256:67b6655311b00581914aba481729971b88bb8bc7996206590700a3ac85e457b8"}, + {file = "pydantic_core-2.23.2-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:358331e21a897151e54d58e08d0219acf98ebb14c567267a87e971f3d2a3be59"}, + {file = "pydantic_core-2.23.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:c4d9f15ffe68bcd3898b0ad7233af01b15c57d91cd1667f8d868e0eacbfe3f87"}, + {file = "pydantic_core-2.23.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0123655fedacf035ab10c23450163c2f65a4174f2bb034b188240a6cf06bb123"}, + {file = "pydantic_core-2.23.2-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:e6e3ccebdbd6e53474b0bb7ab8b88e83c0cfe91484b25e058e581348ee5a01a5"}, + {file = "pydantic_core-2.23.2-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:fc535cb898ef88333cf317777ecdfe0faac1c2a3187ef7eb061b6f7ecf7e6bae"}, + {file = "pydantic_core-2.23.2-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:aab9e522efff3993a9e98ab14263d4e20211e62da088298089a03056980a3e69"}, + {file = "pydantic_core-2.23.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:05b366fb8fe3d8683b11ac35fa08947d7b92be78ec64e3277d03bd7f9b7cda79"}, + {file = "pydantic_core-2.23.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:7568f682c06f10f30ef643a1e8eec4afeecdafde5c4af1b574c6df079e96f96c"}, + {file = "pydantic_core-2.23.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:cdd02a08205dc90238669f082747612cb3c82bd2c717adc60f9b9ecadb540f80"}, + {file = "pydantic_core-2.23.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:1a2ab4f410f4b886de53b6bddf5dd6f337915a29dd9f22f20f3099659536b2f6"}, + {file = "pydantic_core-2.23.2-cp39-none-win32.whl", hash = "sha256:0448b81c3dfcde439551bb04a9f41d7627f676b12701865c8a2574bcea034437"}, + {file = "pydantic_core-2.23.2-cp39-none-win_amd64.whl", hash = "sha256:4cebb9794f67266d65e7e4cbe5dcf063e29fc7b81c79dc9475bd476d9534150e"}, + {file = "pydantic_core-2.23.2-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:e758d271ed0286d146cf7c04c539a5169a888dd0b57026be621547e756af55bc"}, + {file = "pydantic_core-2.23.2-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:f477d26183e94eaafc60b983ab25af2a809a1b48ce4debb57b343f671b7a90b6"}, + {file = "pydantic_core-2.23.2-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:da3131ef2b940b99106f29dfbc30d9505643f766704e14c5d5e504e6a480c35e"}, + {file = "pydantic_core-2.23.2-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:329a721253c7e4cbd7aad4a377745fbcc0607f9d72a3cc2102dd40519be75ed2"}, + {file = "pydantic_core-2.23.2-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:7706e15cdbf42f8fab1e6425247dfa98f4a6f8c63746c995d6a2017f78e619ae"}, + {file = "pydantic_core-2.23.2-pp310-pypy310_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:e64ffaf8f6e17ca15eb48344d86a7a741454526f3a3fa56bc493ad9d7ec63936"}, + {file = "pydantic_core-2.23.2-pp310-pypy310_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:dd59638025160056687d598b054b64a79183f8065eae0d3f5ca523cde9943940"}, + {file = "pydantic_core-2.23.2-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:12625e69b1199e94b0ae1c9a95d000484ce9f0182f9965a26572f054b1537e44"}, + {file = "pydantic_core-2.23.2-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:5d813fd871b3d5c3005157622ee102e8908ad6011ec915a18bd8fde673c4360e"}, + {file = "pydantic_core-2.23.2-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:1eb37f7d6a8001c0f86dc8ff2ee8d08291a536d76e49e78cda8587bb54d8b329"}, + {file = "pydantic_core-2.23.2-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7ce7eaf9a98680b4312b7cebcdd9352531c43db00fca586115845df388f3c465"}, + {file = "pydantic_core-2.23.2-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f087879f1ffde024dd2788a30d55acd67959dcf6c431e9d3682d1c491a0eb474"}, + {file = "pydantic_core-2.23.2-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:6ce883906810b4c3bd90e0ada1f9e808d9ecf1c5f0b60c6b8831d6100bcc7dd6"}, + {file = "pydantic_core-2.23.2-pp39-pypy39_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:a8031074a397a5925d06b590121f8339d34a5a74cfe6970f8a1124eb8b83f4ac"}, + {file = "pydantic_core-2.23.2-pp39-pypy39_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:23af245b8f2f4ee9e2c99cb3f93d0e22fb5c16df3f2f643f5a8da5caff12a653"}, + {file = "pydantic_core-2.23.2-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:c57e493a0faea1e4c38f860d6862ba6832723396c884fbf938ff5e9b224200e2"}, + {file = "pydantic_core-2.23.2.tar.gz", hash = "sha256:95d6bf449a1ac81de562d65d180af5d8c19672793c81877a2eda8fde5d08f2fd"}, ] [package.dependencies] @@ -1956,6 +1954,17 @@ files = [ {file = "typing_extensions-4.12.2.tar.gz", hash = "sha256:1a7ead55c7e559dd4dee8856e3a88b41225abfe1ce8df57b7c13915fe121ffb8"}, ] +[[package]] +name = "tzdata" +version = "2024.1" +description = "Provider of IANA time zone data" +optional = false +python-versions = ">=2" +files = [ + {file = "tzdata-2024.1-py2.py3-none-any.whl", hash = "sha256:9068bc196136463f5245e51efda838afa15aaeca9903f49050dfa2679db4d252"}, + {file = "tzdata-2024.1.tar.gz", hash = "sha256:2674120f8d891909751c38abcdfd386ac0a5a1127954fbc332af6b5ceae07efd"}, +] + [[package]] name = "urllib3" version = "2.2.2" @@ -2123,4 +2132,4 @@ type = ["pytest-mypy"] [metadata] lock-version = "2.0" python-versions = "^3.8.1" -content-hash = "3aae893b86526d474abf058543d34cced34f174e7dd0682efafba13dddcec59a" +content-hash = "6d51d31457690660a1333713b89e6247d2f25b91d1b4737b2c8de8c58f7843ec" diff --git a/pycardano/backend/blockfrost.py b/pycardano/backend/blockfrost.py index a1287f4e..3d5d1afe 100644 --- a/pycardano/backend/blockfrost.py +++ b/pycardano/backend/blockfrost.py @@ -171,6 +171,12 @@ def protocol_param(self) -> ProtocolParameters: cost_models={ k: v.to_dict() for k, v in params.cost_models.to_dict().items() }, + maximum_reference_scripts_size={"bytes": 200000}, + min_fee_reference_scripts={ + "base": params.min_fee_ref_script_cost_per_byte, + "range": 200000, + "multiplier": 1, + }, ) return self._protocol_param diff --git a/pyproject.toml b/pyproject.toml index 93967152..922ee9bd 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -25,7 +25,7 @@ python = "^3.8.1" PyNaCl = "^1.5.0" cbor2 = "^5.4.3" typeguard = "^4.3.0" -blockfrost-python = "0.5.3" +blockfrost-python = "0.6.0" websocket-client = "^1.4.1" cose = "0.9.dev8" pprintpp = "^0.4.0" @@ -35,7 +35,7 @@ frozendict = "^2.3.8" frozenlist = "^1.3.3" cachetools = "^5.3.0" docker = "^7.1.0" -ogmios = {git = "https://gitlab.com/viperscience/ogmios-python.git"} +ogmios = "1.2.1" requests = "^2.32.3" websockets = "^13.0" From 527fb6b77a058c2de6d5549c5eeaf27568e44ad3 Mon Sep 17 00:00:00 2001 From: Jerry Date: Mon, 16 Sep 2024 18:32:12 -0700 Subject: [PATCH 35/44] Fix max tx fee --- pycardano/txbuilder.py | 16 +++++++++------- pycardano/utils.py | 4 +++- test/pycardano/util.py | 2 +- 3 files changed, 13 insertions(+), 9 deletions(-) diff --git a/pycardano/txbuilder.py b/pycardano/txbuilder.py index 6764a6d9..e03cc321 100644 --- a/pycardano/txbuilder.py +++ b/pycardano/txbuilder.py @@ -1041,24 +1041,26 @@ def _ensure_no_input_exclusion_conflict(self): f"{intersection}." ) - def _estimate_fee(self): - plutus_execution_units = ExecutionUnits(0, 0) - for redeemer in self._redeemer_list: - plutus_execution_units += redeemer.ex_units - + def _ref_script_size(self): ref_script_size = 0 for s in self._reference_scripts: if isinstance(s, NativeScript): ref_script_size += len(s.to_cbor()) else: ref_script_size += len(s) + return ref_script_size + + def _estimate_fee(self): + plutus_execution_units = ExecutionUnits(0, 0) + for redeemer in self._redeemer_list: + plutus_execution_units += redeemer.ex_units estimated_fee = fee( self.context, len(self._build_full_fake_tx().to_cbor()), plutus_execution_units.steps, plutus_execution_units.mem, - ref_script_size, + self._ref_script_size(), ) if self.fee_buffer is not None: estimated_fee += self.fee_buffer @@ -1314,7 +1316,7 @@ def _set_collateral_return(self, collateral_return_address: Optional[Address]): return collateral_amount = ( - max_tx_fee(context=self.context) + max_tx_fee(context=self.context, ref_script_size=self._ref_script_size()) * self.context.protocol_param.collateral_percent // 100 ) diff --git a/pycardano/utils.py b/pycardano/utils.py index 17a400ff..7fa139f0 100644 --- a/pycardano/utils.py +++ b/pycardano/utils.py @@ -97,11 +97,12 @@ def fee( ) -def max_tx_fee(context: ChainContext) -> int: +def max_tx_fee(context: ChainContext, ref_script_size: int = 0) -> int: """Calculate the maximum possible transaction fee based on protocol parameters. Args: context (ChainContext): A chain context. + ref_script_size (int): Size of reference scripts in the transaction. Returns: int: Maximum possible tx fee in lovelace. @@ -111,6 +112,7 @@ def max_tx_fee(context: ChainContext) -> int: context.protocol_param.max_tx_size, context.protocol_param.max_tx_ex_steps, context.protocol_param.max_tx_ex_mem, + ref_script_size, ) diff --git a/test/pycardano/util.py b/test/pycardano/util.py index 5f965ac3..6b81ef74 100644 --- a/test/pycardano/util.py +++ b/test/pycardano/util.py @@ -46,7 +46,7 @@ class FixedChainContext(ChainContext): coins_per_utxo_word=34482, coins_per_utxo_byte=4310, cost_models={}, - min_fee_reference_scripts={"base": 25600, "range": 44, "multiplier": 1.2}, + min_fee_reference_scripts={"base": 44, "range": 25600, "multiplier": 1.2}, maximum_reference_scripts_size={"bytes": 200_000}, ) From 295a98774bda36d88286023a310b4cf08076719b Mon Sep 17 00:00:00 2001 From: Jerry Date: Mon, 16 Sep 2024 18:33:52 -0700 Subject: [PATCH 36/44] Update upload-artifact to v4 --- .github/workflows/main.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index ca083162..39bf7827 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -82,7 +82,7 @@ jobs: - name: Upload integration-test.log if: failure() - uses: actions/upload-artifact@v2 + uses: actions/upload-artifact@v4 with: name: integration-test.log path: integration-test/integration-test.log \ No newline at end of file From 348c5a6bdc3626056689e4f4b8e8ded03e7dc0a7 Mon Sep 17 00:00:00 2001 From: Deep Bhatt Date: Wed, 11 Sep 2024 03:27:03 -0400 Subject: [PATCH 37/44] Refactor Redeemer handling in TransactionWitnessSet --- pycardano/witness.py | 23 ++++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-) diff --git a/pycardano/witness.py b/pycardano/witness.py index 35e874c6..acceeb0f 100644 --- a/pycardano/witness.py +++ b/pycardano/witness.py @@ -14,6 +14,11 @@ RawPlutusData, Redeemer, Redeemers, + RedeemerMap, + RedeemerKey, + RedeemerValue, + ExecutionUnits, + RedeemerTag, ) from pycardano.serialization import ( ArrayCBORSerializable, @@ -116,11 +121,19 @@ def _get_plutus_v2_scripts(data: Any): return [PlutusV2Script(script) for script in data] if data else None def _get_redeemers(data: Any): - return ( - [Redeemer.from_primitive(redeemer) for redeemer in data] - if data - else None - ) + if not data: + return None + if isinstance(data, dict): + redeemer_map = RedeemerMap() + for (tag, index), value in data.items(): + key = RedeemerKey(RedeemerTag(tag), index) + redeemer_value = RedeemerValue(value[0], ExecutionUnits(*value[1])) + redeemer_map[key] = redeemer_value + return redeemer_map + elif isinstance(data, list): + return [Redeemer.from_primitive(redeemer) for redeemer in data] + else: + raise ValueError(f"Unexpected redeemer data format: {type(data)}") def _get_cls(data: Any): return cls( From 7727c728acbe9cf9d17ac09911a0a0e9da8036de Mon Sep 17 00:00:00 2001 From: Deep Bhatt Date: Tue, 17 Sep 2024 23:40:14 -0400 Subject: [PATCH 38/44] Add tests for TransactionBuilder redeemer handling --- test/pycardano/test_txbuilder.py | 65 ++++++++++++++++++++++++++++++++ 1 file changed, 65 insertions(+) diff --git a/test/pycardano/test_txbuilder.py b/test/pycardano/test_txbuilder.py index 027acc99..83f8aafc 100644 --- a/test/pycardano/test_txbuilder.py +++ b/test/pycardano/test_txbuilder.py @@ -1866,3 +1866,68 @@ def test_add_script_input_post_chang(chain_context): ) assert expected_redeemer_map == witness.redeemer + + +def test_transaction_witness_set_redeemers_list(chain_context): + """Test that TransactionBuilder correctly stores Redeemer list""" + tx_builder = TransactionBuilder(chain_context) + redeemer_data = [ + [0, 0, 42, [1000000, 2000000]], + [1, 1, "Hello", [3000000, 4000000]], + ] + tx_builder._redeemers = [Redeemer.from_primitive(r) for r in redeemer_data] + + assert tx_builder._redeemers is not None + assert len(tx_builder._redeemers) == 2 + assert tx_builder._redeemers[0].tag == RedeemerTag.SPEND + assert tx_builder._redeemers[0].index == 0 + assert tx_builder._redeemers[0].data == 42 + assert tx_builder._redeemers[0].ex_units == ExecutionUnits(1000000, 2000000) + assert tx_builder._redeemers[1].tag == RedeemerTag.MINT + assert tx_builder._redeemers[1].index == 1 + assert tx_builder._redeemers[1].data == "Hello" + assert tx_builder._redeemers[1].ex_units == ExecutionUnits(3000000, 4000000) + + +def test_transaction_witness_set_redeemers_dict(chain_context): + """Test that TransactionBuilder correctly stores RedeemerMap""" + tx_builder = TransactionBuilder(chain_context) + redeemer_data = { + (0, 0): [42, [1000000, 2000000]], + (1, 1): ["Hello", [3000000, 4000000]], + } + tx_builder._redeemers = RedeemerMap( + { + RedeemerKey(RedeemerTag(tag), index): RedeemerValue( + data, ExecutionUnits(*ex_units) + ) + for (tag, index), (data, ex_units) in redeemer_data.items() + } + ) + + assert tx_builder._redeemers is not None + assert isinstance(tx_builder._redeemers, RedeemerMap) + assert len(tx_builder._redeemers) == 2 + + key1 = RedeemerKey(RedeemerTag.SPEND, 0) + assert tx_builder._redeemers[key1].data == 42 + assert tx_builder._redeemers[key1].ex_units == ExecutionUnits(1000000, 2000000) + + key2 = RedeemerKey(RedeemerTag.MINT, 1) + assert tx_builder._redeemers[key2].data == "Hello" + assert tx_builder._redeemers[key2].ex_units == ExecutionUnits(3000000, 4000000) + + +def test_transaction_witness_set_redeemers_invalid_format(chain_context): + """Test that TransactionBuilder can store invalid redeemer data""" + tx_builder = TransactionBuilder(chain_context) + invalid_redeemer_data = "invalid_data" + tx_builder._redeemers = invalid_redeemer_data + assert tx_builder._redeemers == "invalid_data" + + +def test_transaction_witness_set_no_redeemers(chain_context): + """Test that build_witness_set() returns a WitnessSet with no Redeemer""" + tx_builder = TransactionBuilder(chain_context) + witness_set = tx_builder.build_witness_set() + assert witness_set.redeemer is None From 733f52fecf7e72ceb4cfdad703b85a29cd7ee3cd Mon Sep 17 00:00:00 2001 From: xxAVOGADROxx Date: Sat, 21 Sep 2024 01:45:46 -0500 Subject: [PATCH 39/44] Added unit test --- test/pycardano/test_txbuilder.py | 105 ++++++++++++++++++++++++++++++- 1 file changed, 104 insertions(+), 1 deletion(-) diff --git a/test/pycardano/test_txbuilder.py b/test/pycardano/test_txbuilder.py index 83f8aafc..cd05eff2 100644 --- a/test/pycardano/test_txbuilder.py +++ b/test/pycardano/test_txbuilder.py @@ -8,7 +8,7 @@ import pytest -from pycardano import RedeemerKey, RedeemerMap, RedeemerValue +from pycardano import AssetName, RedeemerKey, RedeemerMap, RedeemerValue from pycardano.address import Address from pycardano.certificate import ( PoolRegistration, @@ -1931,3 +1931,106 @@ def test_transaction_witness_set_no_redeemers(chain_context): tx_builder = TransactionBuilder(chain_context) witness_set = tx_builder.build_witness_set() assert witness_set.redeemer is None + + +def test_minting_and_burning_zero_quantity_assets(chain_context): + """ + Test the minting and burning of multiple assets using the TransactionBuilder. + + This test ensures that assets are correctly minted and burned under the same policy ID. + Specifically, it verifies that after burning certain assets (AssetName1, AssetName2, and AssetName3), + they are removed from the multi-asset map, and the correct amount of the minted asset (AssetName4) remains. + + Steps: + 1. Define a policy ID and several assets (AssetName1, AssetName2, AssetName3, and AssetName4) using the AssetName class. + 2. Simulate minting of 2 units of AssetName4 and burning 1 unit each of AssetName1, AssetName2, and AssetName3. + 3. Add corresponding UTXOs for each asset as inputs. + 4. Add minting instructions to the TransactionBuilder. + 5. Build the transaction and verify that the burnt assets are removed from the multi-asset map. + 6. Check that the correct quantity of AssetName4 is minted and included in the transaction outputs. + + Args: + chain_context: The blockchain context used for constructing and verifying the transaction. + + Assertions: + - AssetName1, AssetName2, and AssetName3 are not present in the multi-asset map after burning. + - AssetName4 has exactly 2 units minted. + """ + tx_builder = TransactionBuilder(chain_context) + + # Create change address + sender = "addr_test1vrm9x2zsux7va6w892g38tvchnzahvcd9tykqf3ygnmwtaqyfg52x" + sender_address = Address.from_primitive(sender) + + # Create four transaction inputs + tx_in1 = TransactionInput.from_primitive( + ["a6cbe6cadecd3f89b60e08e68e5e6c7d72d730aaa1ad21431590f7e6643438ef", 0] + ) + tx_in2 = TransactionInput.from_primitive( + ["b6cbe6cadecd3f89b60e08e68e5e6c7d72d730aaa1ad21431590f7e6643438ef", 1] + ) + tx_in3 = TransactionInput.from_primitive( + ["c6cbe6cadecd3f89b60e08e68e5e6c7d72d730aaa1ad21431590f7e6643438ef", 2] + ) + tx_in4 = TransactionInput.from_primitive( + ["d6cbe6cadecd3f89b60e08e68e5e6c7d72d730aaa1ad21431590f7e6643438ef", 3] + ) + # Define a policy ID and asset names + policy_id = plutus_script_hash(PlutusV1Script(b"dummy script")) + multi_asset1 = MultiAsset.from_primitive({policy_id.payload: {b"AssetName1": 1}}) + multi_asset2 = MultiAsset.from_primitive({policy_id.payload: {b"AssetName2": 2}}) + multi_asset3 = MultiAsset.from_primitive({policy_id.payload: {b"AssetName3": 1}}) + multi_asset4 = MultiAsset.from_primitive({policy_id.payload: {b"AssetName4": 3}}) + + # Simulate minting and burning of assets + mint = MultiAsset.from_primitive( + { + policy_id.payload: { + b"AssetName1": -1, + b"AssetName2": -2, + b"AssetName3": -1, + b"AssetName4": 2, + } + } + ) + + # Set UTXO for the inputs + utxo1 = UTxO( + tx_in1, TransactionOutput(Address(policy_id), Value(10000000, multi_asset1)) + ) + utxo2 = UTxO( + tx_in2, TransactionOutput(Address(policy_id), Value(10000000, multi_asset2)) + ) + utxo3 = UTxO( + tx_in3, TransactionOutput(Address(policy_id), Value(10000000, multi_asset3)) + ) + utxo4 = UTxO( + tx_in4, TransactionOutput(Address(policy_id), Value(10000000, multi_asset4)) + ) + + # Add UTXO inputs + tx_builder.add_input(utxo1) + tx_builder.add_input(utxo2) + tx_builder.add_input(utxo3) + tx_builder.add_input(utxo4) + + # Add the minting to the builder + tx_builder.mint = mint + + # Build the transaction + tx = tx_builder.build(change_address=sender_address) + + # Check that the transaction has outputs + assert tx.outputs + + # Loop through the transaction outputs to verify the multi-asset quantities + for output in tx.outputs: + multi_asset = output.amount.multi_asset + + # Ensure that AssetName1, Node2, and Node3 were burnt (removed) + assert AssetName(b"AssetName1") not in multi_asset.get(policy_id, {}) + assert AssetName(b"AssetName2") not in multi_asset.get(policy_id, {}) + assert AssetName(b"AssetName3") not in multi_asset.get(policy_id, {}) + + # Ensure that AssetName4 has 5 units after minting + assert multi_asset.get(policy_id, {}).get(AssetName(b"AssetName4"), 0) == 5 From 388ab977db7668eced63f3b4dbca386282de021a Mon Sep 17 00:00:00 2001 From: Niels Date: Sat, 21 Sep 2024 06:57:56 -0400 Subject: [PATCH 40/44] Run workflow for PRs to chang --- .github/workflows/main.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 39bf7827..955d49eb 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -4,7 +4,7 @@ on: push: branches: "**" pull_request: - branches: ["main"] + branches: ["main", "chang"] types: [opened, reopened, edited, synchronize] jobs: From fcda104a78e904d52196fdcbf0f1db03735f45ac Mon Sep 17 00:00:00 2001 From: Jerry Date: Sat, 21 Sep 2024 12:07:01 -0700 Subject: [PATCH 41/44] Allow users to configure the serialization format for redeemers --- pycardano/txbuilder.py | 51 ++++++++++++++++---------------- test/pycardano/test_txbuilder.py | 24 ++++++++++----- 2 files changed, 42 insertions(+), 33 deletions(-) diff --git a/pycardano/txbuilder.py b/pycardano/txbuilder.py index e03cc321..46650298 100644 --- a/pycardano/txbuilder.py +++ b/pycardano/txbuilder.py @@ -124,6 +124,9 @@ class TransactionBuilder: initial_stake_pool_registration: Optional[bool] = field(default=False) + use_redeemer_map: Optional[bool] = field(default=True) + """Whether to serialize redeemers as a map or a list. Default is True.""" + _inputs: List[UTxO] = field(init=False, default_factory=lambda: []) _potential_inputs: List[UTxO] = field(init=False, default_factory=lambda: []) @@ -496,21 +499,27 @@ def _redeemer_list(self) -> List[Redeemer]: + [r for _, r in self._withdrawal_script_to_redeemers if r is not None] ) - def redeemers(self) -> RedeemerMap: - redeemers = RedeemerMap() - for r in self._redeemer_list: - if r.tag is None: - raise InvalidArgumentException( - f"Redeemer tag is not set. Redeemer: {r}" - ) - if r.ex_units is None: - raise InvalidArgumentException( - f"Execution units are not set. Redeemer: {r}" - ) - k = RedeemerKey(r.tag, r.index) - v = RedeemerValue(r.data, r.ex_units) - redeemers[k] = v - return redeemers + def redeemers(self) -> Redeemers: + redeemer_list = self._redeemer_list + + # We have to serialize redeemers as a map if there are no redeemers + if self.use_redeemer_map or not redeemer_list: + redeemers = RedeemerMap() + for r in redeemer_list: + if r.tag is None: + raise InvalidArgumentException( + f"Redeemer tag is not set. Redeemer: {r}" + ) + if r.ex_units is None: + raise InvalidArgumentException( + f"Execution units are not set. Redeemer: {r}" + ) + k = RedeemerKey(r.tag, r.index) + v = RedeemerValue(r.data, r.ex_units) + redeemers[k] = v + return redeemers + else: + return redeemer_list @property def script_data_hash(self) -> Optional[ScriptDataHash]: @@ -971,7 +980,7 @@ def _build_full_fake_tx(self) -> Transaction: return tx def build_witness_set( - self, remove_dup_script: bool = False, post_chang: bool = True + self, remove_dup_script: bool = False ) -> TransactionWitnessSet: """Build a transaction witness set, excluding verification key witnesses. This function is especially useful when the transaction involves Plutus scripts. @@ -979,7 +988,6 @@ def build_witness_set( Args: remove_dup_script (bool): Whether to remove scripts, that are already attached to inputs, from the witness set. - post_chang (bool): Whether to use chang serialization for the witness. Returns: TransactionWitnessSet: A transaction witness set without verification key witnesses. @@ -1017,19 +1025,12 @@ def build_witness_set( f"Unsupported script type: {type(script)}" ) - redeemers: Optional[Redeemers] = None - if self._redeemer_list: - if not post_chang: - redeemers = self._redeemer_list - else: - redeemers = self.redeemers() - return TransactionWitnessSet( native_scripts=native_scripts if native_scripts else None, plutus_v1_script=plutus_v1_scripts if plutus_v1_scripts else None, plutus_v2_script=plutus_v2_scripts if plutus_v2_scripts else None, plutus_v3_script=plutus_v3_scripts if plutus_v3_scripts else None, - redeemer=redeemers, + redeemer=self.redeemers() if self._redeemer_list else None, plutus_data=list(self.datums.values()) if self.datums else None, ) diff --git a/test/pycardano/test_txbuilder.py b/test/pycardano/test_txbuilder.py index cd05eff2..f204db51 100644 --- a/test/pycardano/test_txbuilder.py +++ b/test/pycardano/test_txbuilder.py @@ -572,7 +572,8 @@ def test_add_script_input(chain_context): ) tx_builder.add_output(TransactionOutput(receiver, 5000000)) tx_builder.build(change_address=receiver) - witness = tx_builder.build_witness_set(post_chang=False) + tx_builder.use_redeemer_map = False + witness = tx_builder.build_witness_set() assert [datum] == witness.plutus_data assert [redeemer1, redeemer2] == witness.redeemer assert [plutus_script] == witness.plutus_v1_script @@ -603,7 +604,8 @@ def test_add_script_input_no_script(chain_context): ) tx_builder.add_output(TransactionOutput(receiver, 5000000)) tx_builder.build(change_address=receiver) - witness = tx_builder.build_witness_set(remove_dup_script=True, post_chang=False) + tx_builder.use_redeemer_map = False + witness = tx_builder.build_witness_set(remove_dup_script=True, ) assert [datum] == witness.plutus_data assert [redeemer] == witness.redeemer assert witness.plutus_v1_script is None @@ -671,7 +673,8 @@ def test_add_script_input_find_script(chain_context): ) tx_builder.add_output(TransactionOutput(receiver, 5000000)) tx_body = tx_builder.build(change_address=receiver) - witness = tx_builder.build_witness_set(post_chang=False) + tx_builder.use_redeemer_map = False + witness = tx_builder.build_witness_set() assert [datum] == witness.plutus_data assert [redeemer] == witness.redeemer assert witness.plutus_v1_script is None @@ -710,7 +713,8 @@ def test_add_script_input_with_script_from_specified_utxo(chain_context): ) tx_builder.add_output(TransactionOutput(receiver, 5000000)) tx_body = tx_builder.build(change_address=receiver) - witness = tx_builder.build_witness_set(post_chang=False) + tx_builder.use_redeemer_map = False + witness = tx_builder.build_witness_set() assert [datum] == witness.plutus_data assert [redeemer] == witness.redeemer assert witness.plutus_v2_script is None @@ -981,7 +985,8 @@ def test_add_minting_script_from_specified_utxo(chain_context): tx_builder.add_output(TransactionOutput(receiver, 5000000)) tx_builder.mint = mint tx_body = tx_builder.build(change_address=receiver) - witness = tx_builder.build_witness_set(post_chang=False) + tx_builder.use_redeemer_map = False + witness = tx_builder.build_witness_set() assert witness.plutus_data is None assert [redeemer] == witness.redeemer assert witness.plutus_v2_script is None @@ -1110,7 +1115,8 @@ def test_add_minting_script(chain_context): ) tx_builder.add_output(TransactionOutput(receiver, Value(5000000, mint))) tx_builder.build(change_address=receiver) - witness = tx_builder.build_witness_set(post_chang=False) + tx_builder.use_redeemer_map = False + witness = tx_builder.build_witness_set() assert [plutus_script] == witness.plutus_v1_script @@ -1132,7 +1138,8 @@ def test_add_minting_script_only(chain_context): ) tx_builder.add_output(TransactionOutput(receiver, Value(5000000, mint))) tx_builder.build(change_address=receiver) - witness = tx_builder.build_witness_set(post_chang=False) + tx_builder.use_redeemer_map = False + witness = tx_builder.build_witness_set() assert [plutus_script] == witness.plutus_v1_script @@ -1237,7 +1244,8 @@ def test_estimate_execution_unit(chain_context): ) tx_builder.add_output(TransactionOutput(receiver, 5000000)) tx_builder.build(change_address=receiver) - witness = tx_builder.build_witness_set(post_chang=False) + tx_builder.use_redeemer_map = False + witness = tx_builder.build_witness_set() assert [datum] == witness.plutus_data assert [redeemer1] == witness.redeemer assert redeemer1.ex_units is not None From 043578d05b31bbf475c4099e70487771e6bfd1f7 Mon Sep 17 00:00:00 2001 From: Jerry Date: Sat, 21 Sep 2024 12:09:29 -0700 Subject: [PATCH 42/44] Format --- pycardano/witness.py | 8 ++++---- test/pycardano/test_txbuilder.py | 4 +++- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/pycardano/witness.py b/pycardano/witness.py index acceeb0f..e47ccf3b 100644 --- a/pycardano/witness.py +++ b/pycardano/witness.py @@ -8,17 +8,17 @@ from pycardano.key import ExtendedVerificationKey, VerificationKey from pycardano.nativescript import NativeScript from pycardano.plutus import ( + ExecutionUnits, PlutusV1Script, PlutusV2Script, PlutusV3Script, RawPlutusData, Redeemer, - Redeemers, - RedeemerMap, RedeemerKey, - RedeemerValue, - ExecutionUnits, + RedeemerMap, + Redeemers, RedeemerTag, + RedeemerValue, ) from pycardano.serialization import ( ArrayCBORSerializable, diff --git a/test/pycardano/test_txbuilder.py b/test/pycardano/test_txbuilder.py index f204db51..9d5b08b3 100644 --- a/test/pycardano/test_txbuilder.py +++ b/test/pycardano/test_txbuilder.py @@ -605,7 +605,9 @@ def test_add_script_input_no_script(chain_context): tx_builder.add_output(TransactionOutput(receiver, 5000000)) tx_builder.build(change_address=receiver) tx_builder.use_redeemer_map = False - witness = tx_builder.build_witness_set(remove_dup_script=True, ) + witness = tx_builder.build_witness_set( + remove_dup_script=True, + ) assert [datum] == witness.plutus_data assert [redeemer] == witness.redeemer assert witness.plutus_v1_script is None From 46c453db0d1d521c2bc32a6e19ff59cbbaae2eb0 Mon Sep 17 00:00:00 2001 From: theeldermillenial Date: Sun, 22 Sep 2024 15:57:04 -0400 Subject: [PATCH 43/44] Set vkey witnesses to None when empty (#377) --- pycardano/txbuilder.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/pycardano/txbuilder.py b/pycardano/txbuilder.py index 46650298..1662a210 100644 --- a/pycardano/txbuilder.py +++ b/pycardano/txbuilder.py @@ -1509,4 +1509,7 @@ def build_and_sign( VerificationKeyWitness(signing_key.to_verification_key(), signature) ) + if len(witness_set.vkey_witnesses) == 0: + witness_set.vkey_witnesses = None + return Transaction(tx_body, witness_set, auxiliary_data=self.auxiliary_data) From ba73b10faf2676bfaee3370ff013ed45798cb63d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Seraquive?= Date: Sun, 22 Sep 2024 15:54:48 -0500 Subject: [PATCH 44/44] Fixed transaction imbalance when burning assets from the same policy (#376) * Fixed tx imbalance when burning multiple tokens * Added cases and format * Added unit test * Correct unit test * Removed redundant filtering zero-quantity asset * Improved name function (unit test) * Improved unit test * Fix __iadd__ in assets --------- Co-authored-by: Niels Co-authored-by: Jerry --- pycardano/transaction.py | 4 +- pycardano/txbuilder.py | 2 + test/pycardano/test_txbuilder.py | 72 ++++++++++++++++---------------- 3 files changed, 39 insertions(+), 39 deletions(-) diff --git a/pycardano/transaction.py b/pycardano/transaction.py index 6c060101..5d5c7c0e 100644 --- a/pycardano/transaction.py +++ b/pycardano/transaction.py @@ -107,7 +107,7 @@ def __add__(self, other: Asset) -> Asset: def __iadd__(self, other: Asset) -> Asset: new_item = self + other - self.update(new_item) + self.data = new_item.data return self.normalize() def __sub__(self, other: Asset) -> Asset: @@ -173,7 +173,7 @@ def __add__(self, other): def __iadd__(self, other): new_item = self + other - self.update(new_item) + self.data = new_item.data return self.normalize() def __sub__(self, other: MultiAsset) -> MultiAsset: diff --git a/pycardano/txbuilder.py b/pycardano/txbuilder.py index 1662a210..b2a7e854 100644 --- a/pycardano/txbuilder.py +++ b/pycardano/txbuilder.py @@ -556,8 +556,10 @@ def _calc_change( provided = Value() for i in inputs: provided += i.output.amount + if self.mint: provided.multi_asset += self.mint + if self.withdrawals: for v in self.withdrawals.values(): provided.coin += v diff --git a/test/pycardano/test_txbuilder.py b/test/pycardano/test_txbuilder.py index 9d5b08b3..2d0f9344 100644 --- a/test/pycardano/test_txbuilder.py +++ b/test/pycardano/test_txbuilder.py @@ -1943,28 +1943,23 @@ def test_transaction_witness_set_no_redeemers(chain_context): assert witness_set.redeemer is None -def test_minting_and_burning_zero_quantity_assets(chain_context): +def test_burning_all_assets_under_single_policy(chain_context): """ - Test the minting and burning of multiple assets using the TransactionBuilder. + Test burning all assets under a single policy with TransactionBuilder. - This test ensures that assets are correctly minted and burned under the same policy ID. - Specifically, it verifies that after burning certain assets (AssetName1, AssetName2, and AssetName3), - they are removed from the multi-asset map, and the correct amount of the minted asset (AssetName4) remains. + This test ensures that burning multiple assets (AssetName1, AssetName2, AssetName3, AssetName4) + under policy_id_1 removes them from the multi-asset map. Steps: - 1. Define a policy ID and several assets (AssetName1, AssetName2, AssetName3, and AssetName4) using the AssetName class. - 2. Simulate minting of 2 units of AssetName4 and burning 1 unit each of AssetName1, AssetName2, and AssetName3. - 3. Add corresponding UTXOs for each asset as inputs. - 4. Add minting instructions to the TransactionBuilder. - 5. Build the transaction and verify that the burnt assets are removed from the multi-asset map. - 6. Check that the correct quantity of AssetName4 is minted and included in the transaction outputs. + 1. Define assets under policy_id_1 and simulate burning 1 unit of each. + 2. Add UTXOs for the assets and burning instructions. + 3. Build the transaction and verify that all burned assets are removed. Args: - chain_context: The blockchain context used for constructing and verifying the transaction. + chain_context: The blockchain context. Assertions: - - AssetName1, AssetName2, and AssetName3 are not present in the multi-asset map after burning. - - AssetName4 has exactly 2 units minted. + - AssetName1, AssetName2, AssetName3, and AssetName4 are removed after burning. """ tx_builder = TransactionBuilder(chain_context) @@ -1986,43 +1981,48 @@ def test_minting_and_burning_zero_quantity_assets(chain_context): ["d6cbe6cadecd3f89b60e08e68e5e6c7d72d730aaa1ad21431590f7e6643438ef", 3] ) # Define a policy ID and asset names - policy_id = plutus_script_hash(PlutusV1Script(b"dummy script")) - multi_asset1 = MultiAsset.from_primitive({policy_id.payload: {b"AssetName1": 1}}) - multi_asset2 = MultiAsset.from_primitive({policy_id.payload: {b"AssetName2": 2}}) - multi_asset3 = MultiAsset.from_primitive({policy_id.payload: {b"AssetName3": 1}}) - multi_asset4 = MultiAsset.from_primitive({policy_id.payload: {b"AssetName4": 3}}) + policy_id_1 = plutus_script_hash(PlutusV1Script(b"dummy script1")) + multi_asset1 = MultiAsset.from_primitive({policy_id_1.payload: {b"AssetName1": 1}}) + multi_asset2 = MultiAsset.from_primitive({policy_id_1.payload: {b"AssetName2": 1}}) + multi_asset3 = MultiAsset.from_primitive( + { + policy_id_1.payload: {b"AssetName3": 1}, + } + ) + multi_asset4 = MultiAsset.from_primitive( + { + policy_id_1.payload: {b"AssetName4": 1}, + } + ) # Simulate minting and burning of assets mint = MultiAsset.from_primitive( { - policy_id.payload: { + policy_id_1.payload: { b"AssetName1": -1, - b"AssetName2": -2, + b"AssetName2": -1, b"AssetName3": -1, - b"AssetName4": 2, + b"AssetName4": -1, } } ) # Set UTXO for the inputs utxo1 = UTxO( - tx_in1, TransactionOutput(Address(policy_id), Value(10000000, multi_asset1)) + tx_in1, TransactionOutput(Address(policy_id_1), Value(10000000, multi_asset1)) ) utxo2 = UTxO( - tx_in2, TransactionOutput(Address(policy_id), Value(10000000, multi_asset2)) + tx_in2, TransactionOutput(Address(policy_id_1), Value(10000000, multi_asset2)) ) utxo3 = UTxO( - tx_in3, TransactionOutput(Address(policy_id), Value(10000000, multi_asset3)) + tx_in3, TransactionOutput(Address(policy_id_1), Value(10000000, multi_asset3)) ) utxo4 = UTxO( - tx_in4, TransactionOutput(Address(policy_id), Value(10000000, multi_asset4)) + tx_in4, TransactionOutput(Address(policy_id_1), Value(10000000, multi_asset4)) ) # Add UTXO inputs - tx_builder.add_input(utxo1) - tx_builder.add_input(utxo2) - tx_builder.add_input(utxo3) - tx_builder.add_input(utxo4) + tx_builder.add_input(utxo1).add_input(utxo2).add_input(utxo3).add_input(utxo4) # Add the minting to the builder tx_builder.mint = mint @@ -2037,10 +2037,8 @@ def test_minting_and_burning_zero_quantity_assets(chain_context): for output in tx.outputs: multi_asset = output.amount.multi_asset - # Ensure that AssetName1, Node2, and Node3 were burnt (removed) - assert AssetName(b"AssetName1") not in multi_asset.get(policy_id, {}) - assert AssetName(b"AssetName2") not in multi_asset.get(policy_id, {}) - assert AssetName(b"AssetName3") not in multi_asset.get(policy_id, {}) - - # Ensure that AssetName4 has 5 units after minting - assert multi_asset.get(policy_id, {}).get(AssetName(b"AssetName4"), 0) == 5 + # Ensure that AssetName1, AssetName2, AssetName3 and AssetName4 were burnt (removed) + assert AssetName(b"AssetName1") not in multi_asset.get(policy_id_1, {}) + assert AssetName(b"AssetName2") not in multi_asset.get(policy_id_1, {}) + assert AssetName(b"AssetName3") not in multi_asset.get(policy_id_1, {}) + assert AssetName(b"AseetName4") not in multi_asset.get(policy_id_1, {})