Giter Site home page Giter Site logo

plutonomicon / cardano-transaction-lib Goto Github PK

View Code? Open in Web Editor NEW
92.0 13.0 51.0 330.49 MB

A Purescript library for building smart contract transactions on Cardano

Home Page: https://plutonomicon.github.io/cardano-transaction-lib/

License: MIT License

Dhall 2.00% PureScript 91.37% JavaScript 1.84% Makefile 0.45% Nix 3.86% Shell 0.47%

cardano-transaction-lib's Introduction

cardano-transaction-lib cardano-purescript

Hercules-ci Cachix Cache PureScript code documentation

cardano-transaction-lib (CTL) is a Purescript framework for building smart contract transactions on Cardano. It belongs to the the same category of tools as Lucid, Mesh.js, Atlas, Plutus Application Backend (PAB).

Table of Contents

Documentation

Please explore our documentation to discover how to use CTL, how to set up its runtime, and how it compares to other tools:

You can also access PureScript documentation for CTL and its dependencies for the most recent develop version, or generate it yourself.

Additional resources/tools:

Available support channels info

You can find help, more information and ongoing discusion about the project here:

Funding acknowledgements

CTL is being developed by MLabs. The following companies/funds have contributed significant resources (development time or funding):

Use in production

cardano-transaction-lib's People

Contributors

aciceri avatar adamczykm avatar amirmrad avatar aske avatar benjmhart avatar bladyjoker avatar bradley-heather avatar brainrake avatar errfrom avatar firefrorefiddle avatar geometer1729 avatar jy14898 avatar kirill-havryliuk avatar klntsky avatar kozross avatar luis-omega avatar mangoiv avatar marcusbfs avatar marijanp avatar mitchycola avatar nalane avatar ngua avatar pb99u069 avatar przembot avatar rmgaray avatar rynov avatar szg251 avatar uhbif19 avatar vvtran avatar zmrocze avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

cardano-transaction-lib's Issues

Potentially fix `datum` type for `OgmiosTxOut` in `Types.JsonWsp`

Currently

type OgmiosTxOut =
  { address :: Address
  , value :: Value
  , datum :: Maybe String
  }

and https://ogmios.dev/ogmios.wsp.json (see "datum") says datum is base64, although the example looks like a hexadecimal (this looks to be the hash of the datum in fact). We may need datum to be a sum type over both possibilities? ATM,txOutRefToTransactionInput :: TxOutRef -> Maybe Transaction.TransactionInput assumes it's a hexadecimal.

CI?

once we have testing frameworks in place (#13), we'll want some CI checks, namely:

  • no compiler warnings
  • the package builds and passes tests

Build a `Transaction` through the `QueryM` interface

This is essentially the core of the stage-1 goal (building a transaction in the browser that works with a light wallet). Since we don't have a constraints API, we need to fill in most of the relevant information by hand

The transaction will be very simple -- sending two ada to one's own wallet

Here are the rough steps to accomplish this:

  • get the wallet's address through Nami interface embedded in QueryM (e.g. getWalletAddress)
  • query the chain with utxosAt to get the inputs
  • send two ada back to the aforementioned wallet address in the outputs
  • fill in the rest of the UnbalancedTransaction -- this steps depends on how #37 is resolved (see #61)

http query backend

do we have any options to query the chain through just HTTP. if not, do we know why?

Write smart constructors for Value, TokenName and CurrencySymbol

  • With Value now defined as a product type of Ada and non-Ada assets, we should provide smart constructors to construct such terms. This should prevent mixing of lovelaces into the non-Ada asset map.
  • We should remove the export of such data constructors.
  • Remove any newtype instances that would allow us to construct via wrap.
  • Reconsider what functions should be exported from Types.Value e.g. flattenValue - perhaps move to balancer and not export.
  • See #84 and #97

applyCode

we're going to need to be able to apply arguments to scripts and get the correct resulting hash

example: if a project uses a script that is parameterized over someone's pubkeyhash, then we will need a different version for each pubkey that might need to interact with our dApp.

ideally, we should be working with the stringified, non-CBOR version of the script, and hopefully we can get away with minimal parsing and string manipulation, rather than building out an AST.

we need examples of un-applied and applied scripts to see how to do this properly.

in a worst case scenario we could make this a backend service.

EDIT:

Since we are using the Haskell server for this, there are really two tasks:

  • Call applyArgs on the server and respond with the applied script
  • Add a QueryM effect to call this on the client side

module refactor for query types

Types.JsonWsp -> Types.JsonWsp.UtxoQR, Types.JsonWsp.TxQr, etc.

Ogmios.purs is also getting quite big and should also get it's scope broken down

Integration balancing with fee estimation and signing

After #22 is merged, we will have a balancer with some placeholders remaining

We need to integrate various other parts of the project to complete the UnbalancedTransaction -> Transaction part

This includes

  • signing: will be taken care of by #64
  • fee estimation: taken care of by #55. We can just use manual HTTP requests for now. In the future we might be able to generate a client with servant-purescript though

Add deserialization for domain types

Quoting @ngua:

Do you think it would be possible and in-scope for this PR to include some conversion functions/effects in the opposite direction, e.g. Value -> Effect T.Value? We will need these as well soon for wallet effects

I.e. to interact with wallets we need to be able to de-serialize things using cardano-serialization-lib.

document how to set up private testnet infrastructure locally

the docs now include public testnet infra, but not private. since this library will ultimately need to serve both the front end integration as well as E2E testing, we should probably document how to use the library with the Cardano Wallet Backend as well.

Simplify multisign functionality

CIP-0030 specifies a signTx function that can add a partial set of signatures to a transaction.

As argued here, this functionality would be easier to use if the function took a partially-signed transaction and returned some-more-signed transaction.

testing - helper function for failures

in the parsing test suite, we traverse over arrays of examples, verifying that they fit our schema, and verifying that they parse correctly.

it would be good to have error reporting that returns the index of an offending example, and prints it out on failure

strip logs

once we have a working prototype, we should remove a bunch of logs that are currently built into the js FFI calls, etc.

ideally the system should work silently except to report errors.

Get private keys for transaction signing

  • In MLabs pab, a Map PubKeyHash PrivateKey is obtained for signing the transaction. We need something similar like Map Address PrivateKey, there is currently a placeholder newtype PrivateKey in the BalanceTx.

`UnbalancedTransaction`

Create an UnbalancedTransaction type (e.g. here, note that recent plutus-apps splits PubKeyHash into a few different newtypes). Since we want to replicate the constraints API from Contract the type should match the plutus one pretty closely

For consideration: Move reencoding of json to Haskell side.

What if we re-parsed and re-encoded the jsons on haskell side just before sending them to frontend? I mean a thin layer in front of ogmios?

Apparently we should be able to traverse the jsons without the need to know the datatype schema that was used to generate them. The advantage is that we would be dealing with already-parsed jsons (as a tree structure), which is more reliable than a custom state machine-based tokenizer of string.

@ngua

Originally posted by @klntsky in #34 (comment)

Pick a JS bundler

We need to decide on which bundler we want to use, then

  • add it to the shell to use it manually when needed
  • extend the derivations (e.g. bundlePursProject) in nix/lib.nix

We've discussed either using Parcel or Webpack

Purescript style guide

We have a Haskell style guide which we can partially follow, but we should probably have one for Purescript code as well (and maybe even for FFI code)

Let's use this issue as a list of conventions we try to follow

  • Avoid newtypes when there are no type class instances for the type, except of cases where we want to use newtypes to prevent confusion when working with multiple values of the same type.
  • No explicit instance names
  • No $ required before do, unlike in Haskell
  • Don't mix $ with parentheses where it's possible to use only $s
  • Prefer f1 $ f2 $ f3 v over f1 <<< f2 <<< f3 $ v and (f1 <<< f2 <<< f3) v (compose uses more stack and has longer operator name)
  • Naming of FFI functions should start with underscore, except of cases when the function is exported right away with no changes to the public interface
  • If the goal of an import is just to re-export, use import Foo.Bar (baz) as X, not import Foo.Bar (baz) as Foo.Bar (avoids boilerplate and clearly indicates the purpose of the import)
  • Do not export functions more than once from Contract.* modules. The motivation is it would make imports management more complicated for the users (the need to choose between modules). language-server users will have a better UX (there is no need to choose a module if only one module exports an identifier)
  • Do not import modules from test/ in src/ (the reason is: spago only looks up for modules from src/ in dependencies of a project, so that would make CTL unusable as dependency).

Fee Estimation function

we need a function to estimate fees, this will be easiest to use a haskell server for now

Implement core of Nami wallet interface

While we don't need to implement all of Nami's functionality, we do need FFI wrappers around at least the following to build an UnbalancedTx as part of our first goal:

NOTE: Some of the links below are for the deprecated window.cardano injected API. This is because there are no docs for the new injected API; the parameters and return values are the same for the examples below, however, so I linked to them for convenience

All of these return an Effect (Promise ...) which we can then lift into Aff (i.e. Control.Promise.toAffE. Most of them return a hexadecimal string which needs to be decoded

Related issues/PRs: #60, #31, #44, #49

Deserialization for `TransactionWitnessSet`

The type is already defined in Types.Transaction, so we just need the ability to deserialize from CSL. This is required for signTx

To speed this up, there are several Maybe fields we don't care about at the moment that we can just hard-code to Nothing for now (e.g. anything Plutus-related). We can open another issue to revisit that when we start working on Plutus support

This is probably the last deserialization-related thing we need to worry about for stage 1

Aff Interface for Websockets

Currently, the interface for websockets is callback/continuation driven.

this is less than ideal.

our current goal is to have more of an Aff driven interface, probably
ReaderT { WebSocket, Wallet, Etc } Aff a

However this poses some design challenges:

  1. Dispatching the correct, corresponding response for a given query - queries are not given an ID and this may cause data races in complex usage of Aff (multiple Fibers in particular would be a problem)
  2. It would often be impossible to know where an error arose, since dispatch would presumably need to identify a consumer based on the parsed type alone.

Add `getTxById` to `Contract` interface

these are currently blocked on Ogmios-datum-cache efforts

however we will need to be able to query tx by txid and datum by datumhash. (ideally against a cache layer.

Get websockets to work in the browser

Apparently the ws package does not work in the browser (even when polyfilling the packages) and we need to use the browser-native WebSocket object instead

There are some packages like isomorphic-ws, but I don't think that's the best option

JSON / BigInt preprocessor

haskell serializes arbitrary-precision numbers as Integers.

when javascript decodes them as IEEE Floats, we can lose precision.

the argonaut library can't really be used here since it converts all json values into JS values and THEN parses them to PS values.

so we need to roll over json as a string, and whenever we encounter an integer larger than 32 bits, wrap it in quotes so it can be parsed correctly as a BigInt.

purescript-bridge tools

we should use purescript-bridge for a collection of plutus common types as well as document how the user can do this for their input types.

we need to make sure that our recommended purescript-bridge setup writes identical (and safe) json and isData instances.

MakeIsDataIndexed implementation?

we're going to need to encode and decode data in a reasonable way. - and to make sure that data instances agree from Haskell -> Purescript.

This might be a place where we can employ Purescript-bridge, which allows you to construct json-compatible purescript types from haskell types.

the package itself is poorly maintained, and implies that there's a strategy pattern of sorts for building custom instances, etc. This does not actually exist and everyone forks it.

here is a good fork i think: https://github.com/input-output-hk/purescript-bridge/

testing framework

we need a testing framework that runs both on CLI and in simulated browser environments.

currently the plan is to pull in scaffolding from the Medea library https://github.com/juspay/medea-ps/blob/master/test/Main.purs
this uses mote and spec and quickcheck together nicely. we may need a browser-specific test framework like Jest to give us everything to simulate browser behaviors.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.