Haskell library and API server for composing balanced cardano transaction
Kuber uses cardano-api
library. The system packages and dependencies required for building this project is same as that of cardano-node
To prepare your system for building kuber from sources, you can follow these instructions:
The steps can be summarized as
- install system dependencies for ghc and cardano-node
- install ghc compiler and tools with ghcup
- install iokhk patch of libsodium on the system
The steps are described in detailed in the documentation of building-cardano-node-from-soruces
Once everything is installed and is ready, kuber is ready to run
cabal update
cabal run kuber
This will start kuber on port 8081
.
You can also test kuber on cardano testnet via this playground interface : Kuber-Playground
Transaction builder object specifies the spec for the transaction that is to be composed. transaction can be composed by posting a TransactionBuilder JSON object as POST request to localhost:8081/api/v1/tx
- selections : List of utxos/addresses that can be used for balancing transaction
- inputs : List inputs in transactions
- outputs : List Output utxos in the transaction
- collaterals : [optional] List of collaterals in the transaction (It is automatically selected if missing)
- validityStart : [Integer: UnixTimestamp millisecond] Transaction validFrom
- validityEnd : [Integer : UnixTimestamp millisecond] Transaction validUntil
- mint : Minting Scripts and value in the transaction
- fee : [Integer : Lovelace] Fee is calculated automatically, but setting this will set transaction fee explicitly.
- changeAddress [Optional ] : Default change address. If it's missing, it's selected from one of the selection address. Setting
addChange
in any one output will disable this option - metadata : Transaction metadata
Selection is the wallet from which payment is being made. Selection utxos are used if required during balancing. Selection utxos can only be the output to PublicKey addresses and not to Script addresses. The Selection can be in one of following format.
-
TxIn Object : TxIn in object format. Kuber will determine the utxo value by querying with node and use it if required for balancing
{ "hash" | "txid" | "txId" : "String" transaction hash, "index" : [integer] transaction output index }
eg: { "hash": "3500e13b06e8b5c628064cba7bb4637520d2b59acfeee216961362b3919e1ca8", "index": 1}
-
TxIn [ TxHash#index ]
TxIn in readable format. Kuber will determine the utxo value by querying with node and use it if required for balancing
eg: "3500e13b06e8b5c628064cba7bb4637520d2b59acfeee216961362b3919e1ca8#1" -
Utxo CborHex
Utxo( transaction output ) in cbor format. Utxo cbor contains output address, value. Kuber directly uses the value and address by decoding it so, querying the node is not necessary.
eg: "828258202ff238f64b773435d6f626aafe56073f251b52281c50a3872951905fbc597e560082583901ab1d01c80b7ef656194c4af4a682f2d55d714379bde1afe72dc5d348f9c9e87246d2f0373885896ad2804b7229673204cac9208345c1ea5b1a0037e4d2" -
Address bench32
Wallet address in bench32 format. when address is used, all the utxos in the address is queried from the node and then the utxos are used in the transaction if required.
eg: "addr_test1vzzc9nx2lxmu9r7gyd8cyd0dcx0ynh729rpv4c553exs7kgyu9cxl" -
Address CborHex
Wallet address in cbor format. when address is used, all the utxos in the address is queried from the node and then the utxos are used if required for balancing.
eg: "6136e0cf1e52e05ef92e52c7bc2a04493d6bae481b8acbab12ec4300d7"
eg: "0136e0cf1e52e05ef92e52c7bc2a04493d6bae481b8acbab12ec4300d7f9c9e87246d2f0373885896ad2804b7229673204cac9208345c1ea5b"
input can have following fields depending on the context in which it's being used.
-
TxIn Object : TxIn in object format. Kuber will determine the utxo value by querying with node and use it if required for balancing
{ "hash" | "txid" | "txId" : "String" transaction hash, "index" : [integer] transaction output index }
eg: { "hash": "3500e13b06e8b5c628064cba7bb4637520d2b59acfeee216961362b3919e1ca8", "index": 1}
-
TxIn [ TxHash#index ] TxIn in readable format. Kuber will use this utxo in the transaction
eg: "3500e13b06e8b5c628064cba7bb4637520d2b59acfeee216961362b3919e1ca8#1" -
Address bench32
Wallet address in bench32 format. when address is used, all the utxos in the address will be used as input and spent in the transaction.
eg: "addr_test1vzzc9nx2lxmu9r7gyd8cyd0dcx0ynh729rpv4c553exs7kgyu9cxl" -
Address CborHex
Wallet address in cbor format. When address is used, all the utxos in the address will be used as input and spent in the transaction.
eg: "6136e0cf1e52e05ef92e52c7bc2a04493d6bae481b8acbab12ec4300d7"
eg: "0136e0cf1e52e05ef92e52c7bc2a04493d6bae481b8acbab12ec4300d7f9c9e87246d2f0373885896ad2804b7229673204cac9208345c1ea5b" -
Utxo CborHex
Utxo( transaction output ) in cbor format. Utxo cbor contains output address, value , (datum hash in case of script output). Kuber directly uses the value and address by decoding it so, querying the node is not necesasry.
eg: "828258202ff238f64b773435d6f626aafe56073f251b52281c50a3872951905fbc597e560082583901ab1d01c80b7ef656194c4af4a682f2d55d714379bde1afe72dc5d348f9c9e87246d2f0373885896ad2804b7229673204cac9208345c1ea5b1a0037e4d2"
When spending/redeeming form script utxo, Input value should be an object with all of the following fields.
-
utxo
: TxIn [ TxHash#index ] TxIn in readable format. Kuber will use this utxo in the transactioneg: "3500e13b06e8b5c628064cba7bb4637520d2b59acfeee216961362b3919e1ca8#1"
-
script
[Object] : Serialized script wrapped in text evelope.script
object must have the following fields{ "type": "String" Script type [ "PlutuScrpitV1" | "PlutusScriptV2" ] "cborHex": "String" Scrialized cbor hex representation of the script. }
-
redeemer
[Object] : Redeemer datum in json format.eg:
{ "constructor": 0, "fields": []}
-
datum
[Object] [Optional] : Datum matching the datumHash in the utxo. If Inline Datum feature is used, datum is not required and is directly fetched from the datum. Datumeg:
{"constructor": 0, "fields": [{"bytes":"3500e13b06e8b5c628064cba7bb4637520d2b59acfeee216961362b3919e1ca8"}]}
-
exUnits
|executionUnits
[Object] [Optional]:
Specify Execution units values. If not provided, Kuber automatically calculates the execution units and includes it in the transaction{ "steps": "String" Execution units steps "memory": "String" Execution units memory }
-
address
"String" [Optional if script is present] : Receiver address. Receiver address may be script or public key address. Address may be in bench32 or cborHex format. Ifaddress
is not provided and script is present, address is automatically calculated.e.g: "addr_test1vzzc9nx2lxmu9r7gyd8cyd0dcx0ynh729rpv4c553exs7kgyu9cxl"
e.g: "6136e0cf1e52e05ef92e52c7bc2a04493d6bae481b8acbab12ec4300d7"
-
value
[String | Integer] :
Amount to be sent. In case of native tokens, they can be joined by+
like in cardano-cli response
e.g: ada amount : "3A", "3.2Ada", "3.3a", "3ada"
e.g: lovelace amount : 3000000 or "3000000"
e.g: with native token : "3a + b14005d41c24863c570edc85e180cde5eda45bff6c9117ea70856b04.546f6b656e2331"
e.g: with native token : "3000000 + 3 21666f85344ad0f92b47ad3b359d91edc369e51031cb80e649a43434d058bd6a.546f6b656e2331" -
deductFee
[Optional] : If set to true, Fee will be deducted from this output -
addChange
[Optional] : If set to true, Change is added to this output. This can be used to make sure that at leastvalue
amount is sent to this output.
-
script
|inlineScript
: [Object] : Serialized script wrapped in text evelope. WheninlineScript
is provided, the script is inlined in the Utxo. It's object must have following fields { "type": "String" Script type [ "PlutuScrpitV1" | "PlutusScriptV2" ] "cborHex": "String" Scrialized cbor hex representation of the script. } -
datumHash
"String" [Optional] : DatumHash in cbor format. -
datum
|inlineDatum
"String" [Optional] : Datum of the script output.datum
is added in the transaction as Auxiliary Data whereasinlineDatum
is inlined in the utxo
Collaterals are selected automatically by Kuber using one of the utxos in the selections
.
If desired, collaterals list can be set explicitly .
Each Item in the list can be in one of the following form.
-
TxIn Object : TxIn in object format.
{ "hash" | "txid" | "txId" : "String" transaction hash, "index" : [integer] transaction output index }
eg: { "hash": "3500e13b06e8b5c628064cba7bb4637520d2b59acfeee216961362b3919e1ca8", "index": 1}
-
TxIn [ TxHash#index ] : TxIn in readable format.
eg: "3500e13b06e8b5c628064cba7bb4637520d2b59acfeee216961362b3919e1ca8#1" c
-
Address bench32 Wallet address in bench32 format. when address is used, all the utxos int the address will be used as an input and spent in the transaction.
eg: "addr_test1vzzc9nx2lxmu9r7gyd8cyd0dcx0ynh729rpv4c553exs7kgyu9cxl"
-
Utxo CborHex Utxo( transaction output ) in cbor format. Utxo cbor contains output address, value .
eg: "828258202ff238f64b773435d6f626aafe56073f251b52281c50a3872951905fbc597e560082583901ab1d01c80b7ef656194c4af4a682f2d55d714379bde1afe72dc5d348f9c9e87246d2f0373885896ad2804b7229673204cac9208345c1ea5b1a0037e4d2"
Each object in the mint list must have following keys
-
amount
{Object} : in amount object, keys represent the tokenName in hexFromat and value is the amount of that token to be minted.e.g.
{ "546f6b656e2331": 1, "546f6b656e2332": 1}
-
script
{Object} : Serialized script wrapped in text evelope.script
object must have following fields{ "type": "String" Script type [ "PlutuScrpitV1" | "PlutusScriptV2" ] "cborHex": "String" Scrialized cbor hex representation of the script. }
-
executionUnits
{Object} [Optional] : Specify Execution units values. If not provided, Kuber automatically calculates the executionunits and include it in the transaction{ "steps": (integer) Execution units steps "memory": (integer) Execution units memory }
-
script
{Object} : Simple script json format object{ "type": "String" Script type ["all" | "any"| "atleast" | "sig" | "after" | "before" ] "..." : Other keys are based on the type of simple script. },
BasicScripts
SignatureScript : { "type": "sig" , "keyHash": "String" PublicKeyHash hex string. This public key can only mint the token } TimeBeforeScript : { "type" : "before" "slot" : (number) the slot no before which this script cannot be minted. } TimeAfterScript : { "type" : "after" "slot" : (number) the slot no after which this script cannot be minted. }
MultiScripts:
AnyScript{ "type": "any", "scripts" : [ BasicScript | MultiScript ] : If any one of these script condition is met, token can be minted } AllScript{ "type": "all" "scripts": [ BasicScript | MultiScript ] : If condition of all of these scripts is } AnyMScript{ "type": "atLeast" "required": (number) minimun no of scripts for which condition should be met. "scripts": [ BasicScript | MultiScript ] : when required number of script condition is met, token can be minted. }
Transaction metadata must be a json object with top level integer key label.
Keys in the json shouldn't be longer than 64 bytes length. If the string value in the metadata is longer than 64 bytes length, Kuber will split the string and replace it with array of smaller chunks of the string.
Metadata object example:
{
"420": "content here",
"421": {
"key": "value",
"key": ["value1","value2"]
}
}