Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 8 additions & 8 deletions flake.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion flake.nix
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@
repo = "cardano-transaction-lib";
# should be same rev as in packages.dhall
# Oh update, do `spago2nix generate`
rev = "b7614b4e11a57b5b366b65509b86eb4b086bb1ce";
# https://github.com/Plutonomicon/cardano-transaction-lib/pull/702/commits/6592f4188850ca4b2adab0c593c6a971087a54ba
rev = "6592f4188850ca4b2adab0c593c6a971087a54ba";
};
nixpkgs.follows = "cardano-transaction-lib/nixpkgs";
};
Expand Down
13 changes: 11 additions & 2 deletions index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,13 @@ export function callMarketPlaceBuy(config: Config, args: BuyNftArgs):
Promise<void>
export function callMarketPlaceListNft(config: Config):
Promise<Array<NftListing>>
/**
* Fetch the info for a single NFT. Returns null if the given
* transaction input has been spent (for example if the NFT has been
* bought).
*/
export function callMarketPlaceFetchNft(config: Config, args: FetchNftArgs):
Promise<NftListing?>
export function connectWallet(): Promise<any>
export function getWalletBalance(): Promise<any>

Expand Down Expand Up @@ -36,6 +43,8 @@ export type BuyNftArgs = {

}

export type FetchNftArgs = Input

export type NftCollectionArgs = {
// CurrencySymbol of nft collection
collectionNftCs: string,
Expand Down Expand Up @@ -66,8 +75,8 @@ export type NftListing = {
}

export type Input = {
transaction_id: String,
input_index: number
transactionId: String,
inputIndex: number
}

export type Output = {
Expand Down
5 changes: 5 additions & 0 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,11 @@ exports.callMarketPlaceListNft = async (config) => {
return sb.callMarketPlaceListNft(config)();
};

exports.callMarketPlaceFetchNft = async (config, args) => {
const sb = await seabug;
return sb.callMarketPlaceFetchNft(config)(args)();
};


/**
* Returns a promise containing the connected wallet's balance.
Expand Down
4 changes: 1 addition & 3 deletions packages.dhall
Original file line number Diff line number Diff line change
Expand Up @@ -328,9 +328,7 @@ let additions =
]
, repo = "https://github.com/Plutonomicon/cardano-transaction-lib.git"
-- should be same rev as in flake.nix
-- https://github.com/Plutonomicon/cardano-transaction-lib/pull/696
-- PR: Return error if no utxo is specified for a tx input & Fix transaction inputs locking
, version = "b7614b4e11a57b5b366b65509b86eb4b086bb1ce"
, version = "6592f4188850ca4b2adab0c593c6a971087a54ba"
}
}
in upstream // additions
6 changes: 3 additions & 3 deletions spago-packages.nix

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions spago.dhall
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ You can edit this file as you like.
, "monad-logger"
, "mote"
, "newtype"
, "nullable"
, "ordered-collections"
, "parallel"
, "partial"
Expand Down
51 changes: 38 additions & 13 deletions src/Seabug/CallContract.purs
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
module Seabug.CallContract
( callMarketPlaceBuy
, callMarketPlaceListNft
, callMarketPlaceBuyTest
, callMarketPlaceFetchNft
, callMarketPlaceListNft
) where

import Contract.Prelude
Expand All @@ -16,12 +17,9 @@ import Contract.Monad
, runContract_
)
import Contract.Numeric.Natural (toBigInt)
import Contract.Prim.ByteArray
( byteArrayToHex
, hexToByteArray
)
import Contract.Prim.ByteArray (byteArrayToHex, hexToByteArray)
import Contract.Transaction
( TransactionInput(TransactionInput)
( TransactionInput(..)
, TransactionOutput(TransactionOutput)
)
import Contract.Value
Expand All @@ -38,19 +36,22 @@ import Control.Promise (Promise)
import Control.Promise as Promise
import Data.BigInt (BigInt)
import Data.BigInt as BigInt
import Data.Log.Level (LogLevel(..))
import Data.Nullable (Nullable, notNull, null)
import Data.Tuple.Nested ((/\))
import Data.UInt as UInt
import Effect (Effect)
import Effect.Aff (error)
import Effect.Class (liftEffect)
import Data.Log.Level (LogLevel(..))
import Effect.Exception (Error)
import Seabug.Metadata.Types (SeabugMetadata(SeabugMetadata))
import Seabug.Metadata.Share (unShare)
import Partial.Unsafe (unsafePartial)
import Plutus.Conversion (fromPlutusAddress)
import Seabug.Contract.Common (NftResult)
import Seabug.Contract.MarketPlaceBuy (marketplaceBuy)
import Seabug.Contract.MarketPlaceListNft (ListNftResult, marketPlaceListNft)
import Seabug.Contract.MarketPlaceFetchNft (marketPlaceFetchNft)
import Seabug.Contract.MarketPlaceListNft (marketPlaceListNft)
import Seabug.Metadata.Share (unShare)
import Seabug.Metadata.Types (SeabugMetadata(SeabugMetadata))
import Seabug.Types
( NftCollection(NftCollection)
, NftData(NftData)
Expand All @@ -63,14 +64,26 @@ import Serialization.Hash
, scriptHashFromBech32
, scriptHashToBech32Unsafe
)
import Types.BigNum as BigNum
import Types.Natural as Nat
import Wallet (mkNamiWalletAff)
import Types.BigNum as BigNum

-- | Exists temporarily for testing purposes
callMarketPlaceBuyTest :: String -> Effect (Promise String)
callMarketPlaceBuyTest = Promise.fromAff <<< pure

callMarketPlaceFetchNft
:: ContractConfiguration
-> TransactionInputOut
-> Effect (Promise (Nullable ListNftResultOut))
callMarketPlaceFetchNft cfg args = Promise.fromAff do
contractConfig <- buildContractConfig cfg
txInput <- liftEffect $ liftEither $ buildTransactionInput args
runContract contractConfig (marketPlaceFetchNft txInput) >>= case _ of
Nothing -> pure null
Just nftResult -> pure $ notNull $
buildNftList (unwrap contractConfig).networkId nftResult

-- | Calls Seabugs marketplaceBuy and takes care of converting data types.
-- Returns a JS promise holding no data.
callMarketPlaceBuy
Expand Down Expand Up @@ -123,12 +136,14 @@ type BuyNftArgs =
}
}

type TransactionInputOut = { transactionId :: String, inputIndex :: Int }

-- Placeholder for types I'm not sure how should we represent on frontend.
type ValueOut = Array
{ currencySymbol :: String, tokenName :: String, amount :: BigInt }

type ListNftResultOut =
{ input :: { transactionId :: String, inputIndex :: Int }
{ input :: TransactionInputOut
, output :: { address :: String, value :: ValueOut, dataHash :: String }
, metadata ::
{ seabugMetadata ::
Expand Down Expand Up @@ -193,7 +208,7 @@ stringToLogLevel "Warn" = Just Warn
stringToLogLevel "Error" = Just Error
stringToLogLevel _ = Nothing

buildNftList :: NetworkId -> ListNftResult -> ListNftResultOut
buildNftList :: NetworkId -> NftResult -> ListNftResultOut
buildNftList
network
{ input: TransactionInput input, output: TransactionOutput output, metadata } =
Expand Down Expand Up @@ -298,3 +313,13 @@ buildNftData { nftCollectionArgs, nftIdArgs } = do
, daoScript
, daoShare
}

buildTransactionInput :: TransactionInputOut -> Either Error TransactionInput
buildTransactionInput input = do
transactionId <-
note (error $ "Invalid transaction id: " <> input.transactionId)
$ wrap
<$> hexToByteArray input.transactionId
index <- note (error $ "Invalid input index: " <> show input.inputIndex) $
UInt.fromInt' input.inputIndex
pure $ wrap { transactionId, index }
12 changes: 12 additions & 0 deletions src/Seabug/Contract/Common.purs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
module Seabug.Contract.Common
( NftResult
) where

import Contract.Transaction (TransactionInput, TransactionOutput)
import Seabug.Metadata (FullSeabugMetadata)

type NftResult =
{ input :: TransactionInput
, output :: TransactionOutput
, metadata :: FullSeabugMetadata
}
38 changes: 38 additions & 0 deletions src/Seabug/Contract/MarketPlaceFetchNft.purs
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
-- | Contract to fetch a single NFT
module Seabug.Contract.MarketPlaceFetchNft
( marketPlaceFetchNft
) where

import Contract.Prelude

import Contract.Monad (Contract, liftContractM, liftedE, liftedM, logWarn')
import Contract.PlutusData (fromData, getDatumByHash)
import Contract.Transaction (TransactionInput, TransactionOutput(..))
import Contract.Utxos (getUtxo)
import Control.Monad.Reader (asks)
import Seabug.Contract.Common (NftResult)
import Seabug.Metadata (getFullSeabugMetadataWithBackoff)
import Seabug.Types (MarketplaceDatum(..))

-- | Fetch the info for a single NFT identified by a utxo
-- | (`TransactionInput`). Returns `Nothing` if the given transaction
-- | input has been spent (for example if the NFT has been bought).
marketPlaceFetchNft
:: forall (r :: Row Type)
. TransactionInput
-> Contract (projectId :: String | r) (Maybe NftResult)
marketPlaceFetchNft ref = do
getUtxo ref >>= case _ of
Nothing -> do
logWarn' "Could not find NFT utxo, it may have been spent"
pure Nothing
Just output@(TransactionOutput nftTxOut) -> do
datumHash <- liftContractM "Datum hash not available for NFT"
nftTxOut.dataHash
MarketplaceDatum { getMarketplaceDatum: datum } <-
liftedM "Could not get datum for NFT" $ getDatumByHash datumHash <#>
(_ >>= unwrap >>> fromData)
projectId <- asks $ unwrap >>> _.projectId
metadata <- liftedE $ liftAff $
getFullSeabugMetadataWithBackoff datum projectId
pure $ Just { input: ref, output, metadata }
19 changes: 5 additions & 14 deletions src/Seabug/Contract/MarketPlaceListNft.purs
Original file line number Diff line number Diff line change
@@ -1,18 +1,14 @@
-- | Helper to list the utxo with relevant NFT at the market validator script
module Seabug.Contract.MarketPlaceListNft
( ListNftResult
, marketPlaceListNft
( marketPlaceListNft
) where

import Contract.Prelude

import Contract.Address (getNetworkId, typedValidatorEnterpriseAddress)
import Contract.Monad (Contract, liftContractE, liftedM)
import Contract.PlutusData (fromData, getDatumsByHashes)
import Contract.Transaction
( TransactionInput
, TransactionOutput(TransactionOutput)
)
import Contract.Transaction (TransactionOutput(TransactionOutput))
import Contract.Utxos (utxosAt)
import Contract.Value (valueOf)
import Control.Alternative (guard)
Expand All @@ -21,22 +17,17 @@ import Control.Monad.Reader (asks)
import Control.Parallel (parTraverse)
import Data.Array (catMaybes, mapMaybe)
import Data.Map as Map
import Seabug.Contract.Common (NftResult)
import Seabug.MarketPlace (marketplaceValidator)
import Seabug.Metadata (FullSeabugMetadata, getFullSeabugMetadataWithBackoff)
import Seabug.Metadata (getFullSeabugMetadataWithBackoff)
import Seabug.Types (MarketplaceDatum(MarketplaceDatum))

type ListNftResult =
{ input :: TransactionInput
, output :: TransactionOutput
, metadata :: FullSeabugMetadata
}

-- | Lists the utxos at the script address that contain a datum of type
-- | `MarketplaceDatum` with unit value. It currently doesn't have any logic
-- | on matching `CurrencySymbol` and `TokenName`.
marketPlaceListNft
:: forall (r :: Row Type)
. Contract (projectId :: String | r) (Array ListNftResult)
. Contract (projectId :: String | r) (Array NftResult)
marketPlaceListNft = do
marketplaceValidator' <- unwrap <$> liftContractE marketplaceValidator
networkId <- getNetworkId
Expand Down
1 change: 1 addition & 0 deletions src/Seabug/Seabug.purs
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,6 @@ import Seabug.CallContract
( callMarketPlaceBuy
, callMarketPlaceBuyTest
, callMarketPlaceListNft
, callMarketPlaceFetchNft
)
import QueryM.Utxos (getWalletBalance)