Skip to content

Commit

Permalink
intitial
Browse files Browse the repository at this point in the history
  • Loading branch information
rchak007 committed Oct 7, 2023
1 parent f6d6a98 commit 958a184
Show file tree
Hide file tree
Showing 29 changed files with 10,283 additions and 0 deletions.
45 changes: 45 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -21,3 +21,48 @@ cabal.project.local
cabal.project.local~
.HTF/
.ghc.environment.*


# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.

# dependencies
/node_modules
/.pnp
.pnp.js

# testing
/coverage

# next.js
/.next/
/out/

# production
/build

# misc
.DS_Store
*.pem

# debug
npm-debug.log*
yarn-debug.log*
yarn-error.log*

# local env files
.env*.local

# vercel
.vercel

# typescript
*.tsbuildinfo
next-env.d.ts

# private keys, seed, etc
*.priv
*.seed
*secret*
getData.ts
*getData.ts*
secret.json
107 changes: 107 additions & 0 deletions READMEGuess.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
# guessNumberLucid
Off-Chain code with Lucid #plutarch #cardano





Employ Lucid to interact with off-chain code.

Employ blockfrost to connect to Cardano blockchain.





## Plutarch On Chain code

### Overview

Plutarch is an eDSL in Haskell for writing on-chain scripts for Cardano. With some caveats, Plutarch is a [simply-typed lambda calculus](https://en.wikipedia.org/wiki/Simply_typed_lambda_calculus) (or STLC). Writing a script in Plutarch allows us to leverage the language features provided by Haskell while retaining the ability to compile to compact Untyped Plutus Core (or UPLC, which is an untyped lambda calculus).

When we talk about “Plutarch scripts,” we are referring to values of type `Term (s :: S) (a :: PType)`. `Term` is a `newtype` wrapper around a more complex type, the details of which Plutarch end-users can ignore. A `Term` is a typed lambda term; it can be thought of as representing a computation that, if successfully evaluated, will return a value of type `a`.



### Why Plutarch?

Plutarch written validators are often significantly more efficient than Plutus Tx written validators. With Plutarch, you have much more fine gained control of the Plutus Core you generate, without giving up any type information.

To put things into perspective, one validator script from a large production contract was rewritten in Plutarch, changed from Plutus Tx. Here's the comparison between the Plutarch script's execution cost compared to the Plutus Tx script's execution cost. These numbers were gathered by simulating the whole contract flow on a testnet:

| Version | CPU | Memory | Script Size |
| ------------------ | ----------- | ------- | ----------- |
| PlutusTx (current) | 198,505,651 | 465,358 | 2013 |
| Plutarch | 51,475,605 | 99,992 | 489 |



[Reference]: https://github.com/Plutonomicon/plutarch-plutus#why-plutarch "Why Plutarch"







### guessNumber



Here we start with Number guess game and the Cardano plutus onChain script is written in Plutarch.

Below is snippet of onCHain code for :

#### Datum and Redeemer

```haskell
data POurDatum (s :: S) = POurDatum (Term s (PDataRecord '[ "password" ':= PInteger ]))
deriving stock (Generic)
deriving anyclass (PlutusType, PIsData, PDataFields)

instance DerivePlutusType POurDatum where
type DPTStrat _ = PlutusTypeData

instance PTryFrom PData POurDatum

data POurRedeemer (s :: S) = POurRedeemer (Term s (PDataRecord '[ "password" ':= PInteger ]))
deriving stock (Generic)
deriving anyclass (PlutusType, PIsData, PDataFields)

instance DerivePlutusType POurRedeemer where
type DPTStrat _ = PlutusTypeData

instance PTryFrom PData POurRedeemer
```



#### Plutarch validator

This is a simple validator where it matches the existing Datum number with Redeemer number, and if its equal then it unlocks the funds. Again this is a trivial example as we inline the Datum so its actually visible but ideally it should be hashed.

```haskell
pvalidateSmallChecks :: Term s (POurDatum :--> POurRedeemer :--> PScriptContext :--> PUnit)
pvalidateSmallChecks = phoistAcyclic $ plam $ \datum redeemer _ctx -> unTermCont $ do
-- ctxF <- pletFieldsC @'["txInfo"] ctx
-- infoF <- pletFieldsC @'["signatories"] ctxF.txInfo
datumF <- pletFieldsC @'["password"] datum
redeemF <- pletFieldsC @'["password"] redeemer
pure $
pif ( (redeemF.password) #== datumF.password )
(pconstant ())
perror

pvalidateSmallChecksW :: Term s PValidator
pvalidateSmallChecksW = phoistAcyclic $ plam $ \datum redeemer ctx ->
let ourDatum :: Term _ POurDatum
ourDatum = punsafeCoerce datum
ourRedeemer :: Term _ POurRedeemer
ourRedeemer = punsafeCoerce redeemer
in popaque $ pvalidateSmallChecks # ourDatum # ourRedeemer # ctx
```





25 changes: 25 additions & 0 deletions components/NftCard.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@

import { useState } from 'react'
import { useStoreActions, useStoreState } from "../utils/store";


const NftCard = (props: any) => {
const image = typeof (props.meta.image) === 'string' ? "https://ipfs.io/ipfs/" + props.meta.image.replace("ipfs://", "") : ""

return (
<>
<div className="card w-76 bg-base-300 shadow-xl m-5">
<figure className="px-10 pt-10">
<img src={image} alt="Shoes" className="rounded-xl" />
</figure>
<div className="card-body items-center text-center">
<h2 className="card-title">{props.meta.name}</h2>
<div className="card-actions">
</div>
</div>
</div>
</>
)
}

export default NftCard;
21 changes: 21 additions & 0 deletions components/NftGrid.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@

import { useEffect } from 'react'
import NftCard from './NftCard'

const NftGrid = (props : any) => {
useEffect(()=>{
console.log(props)
},[props])
return (
<>
<div className="grid grid-cols-4 gap-2">
{props.nfts.map((nft : any, index : Number) => {
return <NftCard key={index} meta={nft} />
})}
</div>
</>

)
}

export default NftGrid;
66 changes: 66 additions & 0 deletions components/WalletConnect.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
import { Lucid, Blockfrost, C } from "lucid-cardano";
import { useState, useEffect } from 'react';
import { useStoreActions, useStoreState } from "../utils/store";
import initLucid from "../utils/lucid";

const WalletConnect = () => {
// const [availableWallets, setAvailableWallets] = useState<string[]>([])
const walletStore = useStoreState(state => state.wallet)
const setWallet = useStoreActions(actions => actions.setWallet)
const availableWallets = useStoreState(state => state.availableWallets)
const setAvailableWallets = useStoreActions(actions => actions.setAvailableWallets)

const [connectedAddress, setConnectedAddress] = useState("")

const loadWalletSession = async () => {
if (walletStore.connected &&
walletStore.name &&
window.cardano &&
(await window.cardano[walletStore.name.toLowerCase()].enable())
) {
walletConnected(walletStore.name)
}
}

const walletConnected = async (wallet: string, connect: boolean = true) => {
const addr = connect ? await (await initLucid(wallet)).wallet.address() : ''
const walletStoreObj = connect ? { connected: true, name: wallet, address: addr } : { connected: false, name: '', address: '' }
setConnectedAddress(addr)
setWallet(walletStoreObj)
}

const selectWallet = async (wallet: string) => {
if (
window.cardano &&
(await window.cardano[wallet.toLocaleLowerCase()].enable())
) {
walletConnected(wallet)
}
}

useEffect(() => {
let wallets = []
if (window.cardano) {
if (window.cardano.nami) wallets.push('Nami')
if (window.cardano.eternl) wallets.push('Eternl')
if (window.cardano.flint) wallets.push('Flint')
loadWalletSession()
}
setAvailableWallets(wallets)
}, [])

return (
<>
<div className="dropdown dropdown-end">
<label tabIndex={0} className="btn m-1">{connectedAddress != "" ? 'Connected' : 'Connect'}</label>
<ul tabIndex={0} className="dropdown-content menu p-2 shadow bg-base-300 rounded-box w-52">
{availableWallets.map((wallet) =>
<li key={wallet} onClick={() => { selectWallet(wallet) }} ><a>{wallet}</a></li>
)}
</ul>
</div>
</>
)
}

export default WalletConnect;
19 changes: 19 additions & 0 deletions next.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@

/** @type {import('next').NextConfig} */
const nextConfig = {

experimental: {
outputStandalone: true,
},
reactStrictMode: true,
webpack: (config) => {
config.experiments = {
asyncWebAssembly: true,
topLevelAwait: true,
layers: true
}
return config
}
}

module.exports = nextConfig
Loading

0 comments on commit 958a184

Please sign in to comment.