diff --git a/mstoken.cabal b/mstoken.cabal index b9e24c6..a8a2e33 100644 --- a/mstoken.cabal +++ b/mstoken.cabal @@ -1,38 +1,46 @@ -name: snet-upgradeable-owners-minting-policy -version: 1.0 -author: SNET -maintainer: anastasia.martynyuk@singularitynet.io -build-type: Simple -extra-source-files: CHANGELOG.md -cabal-version: >=1.10 +name: snet-upgradeable-owners-minting-policy +version: 1.0 +author: SNET +maintainer: anastasia.martynyuk@singularitynet.io +build-type: Simple +extra-source-files: CHANGELOG.md +cabal-version: >=1.10 -library - import: common-all - hs-source-dirs: ./src - exposed-modules: NFT - , Token - , Validator - , TestSerializer - build-depends: base >=4.7 && <5 - , aeson - , bytestring - , plutus-ledger-api - , plutus-tx - , plutus-tx-plugin - , containers - , text - , plutus-ledger >=1.1.0 - , plutus-ledger-constraints >=1.1.0 - , plutus-script-utils >=1.1.0 - , cardano-api >= 1.35.4 - , serialise - , base16-bytestring - default-language: Haskell2010 +executable save-scripts + main-is: ./src/Main.hs + build-depends: + base >=4.7 && <5 + , snet-upgradeable-owners-minting-policy +library + import: common-all + hs-source-dirs: ./src + exposed-modules: + NFT + ScriptUtils + TestSerializer + Token + Validator + build-depends: + aeson + , base >=4.7 && <5 + , base16-bytestring + , bytestring + , cardano-api >=1.35.4 + , containers + , plutus-ledger >=1.1.0 + , plutus-ledger-api + , plutus-ledger-constraints >=1.1.0 + , plutus-script-utils >=1.1.0 + , plutus-tx + , plutus-tx-plugin + , serialise + , text + default-language: Haskell2010 ghc-options: -Wall -Wnoncanonical-monad-instances -Wunused-packages -Wincomplete-uni-patterns -Wincomplete-record-updates -Wredundant-constraints -Widentities -fobject-code - -fno-ignore-interface-pragmas -fno-omit-interface-pragmas \ No newline at end of file + -fno-ignore-interface-pragmas -fno-omit-interface-pragmas diff --git a/scripts/nft.json b/scripts/nft.json index 7dca9b1..35c1fa3 100644 --- a/scripts/nft.json +++ b/scripts/nft.json @@ -1,5 +1,5 @@ { "type": "PlutusScriptV2", "description": "", - "cborHex": "5909a259099f010000333233223322323232323232323232323232323232323232323232323222335501722232325335330053357389211d52656465656d6572206465636f646564207375636365737366756c6c79003333573466e1cd55ce9baa0044800080688c98c8068cd5ce00d80d00c19ab9c4912353637269707420636f6e74657874206465636f646564207375636365737366756c6c79003333573466e1cd55cea80124000466442466002006004646464646464646464646464646666ae68cdc39aab9d500c480008cccccccccccc88888888888848cccccccccccc00403403002c02802402001c01801401000c008cd4064068d5d0a80619a80c80d1aba1500b33501901b35742a014666aa03aeb94070d5d0a804999aa80ebae501c35742a01066a0320446ae85401cccd5407408dd69aba150063232323333573466e1cd55cea801240004664424660020060046464646666ae68cdc39aab9d5002480008cc8848cc00400c008cd40b5d69aba15002302e357426ae8940088c98c80c0cd5ce01881801709aab9e5001137540026ae854008c8c8c8cccd5cd19b8735573aa004900011991091980080180119a816bad35742a004605c6ae84d5d1280111931901819ab9c03103002e135573ca00226ea8004d5d09aba2500223263202c33573805a05805426aae7940044dd50009aba1500533501975c6ae854010ccd5407407c8004d5d0a801999aa80ebae200135742a00460426ae84d5d1280111931901419ab9c029028026135744a00226ae8940044d5d1280089aba25001135744a00226ae8940044d5d1280089aba25001135744a00226ae8940044d55cf280089baa00135742a00460226ae84d5d1280111931900d19ab9c01b01a01810191326320193357389210350543500019135573ca00226ea800488c8cc01ccc0192401115554784f206e6f7420636f6e73756d656400335501a33553019120013232123300122333500522002002001002350012200112330012253350021021100101e2325335333573466e3cd400488008d401c8800808007c4ccd5cd19b873500122001350072200102001f101f3500122002323500122222222222200c5001330064911377726f6e6720616d6f756e74206d696e746564005335323301c502100132350012222222222220085001101d22135002222533500413300c333573466e3c00802408c088ccd5cd19b870014800808c0888840904d400488008894cd400440684cd5ce00100c91299a8010800880c0919118011bac0013200135501a2233335573e0024a038466a03660086ae84008c00cd5d1001009119191999ab9a3370e6aae7540092000233221233001003002300a35742a004600a6ae84d5d1280111931900919ab9c013012010135573ca00226ea80048c8c8c8c8cccd5cd19b8735573aa00890001199991110919998008028020018011919191999ab9a3370e6aae7540092000233221233001003002301335742a00466a01a0246ae84d5d1280111931900b99ab9c018017015135573ca00226ea8004d5d0a802199aa8043ae500735742a0066464646666ae68cdc3a800a4008464244460040086ae84d55cf280191999ab9a3370ea0049001119091118008021bae357426aae7940108cccd5cd19b875003480008488800c8c98c8064cd5ce00d00c80b80b00a89aab9d5001137540026ae854008cd4025d71aba135744a004464c6402666ae7005004c0444d5d1280089aba25001135573ca00226ea80044cd54005d73ad112232230023756002640026aa02e44646666aae7c008940688cd4064cc8848cc00400c008c018d55cea80118029aab9e500230043574400602026ae84004488c8c8cccd5cd19b875001480008c8488c00800cc014d5d09aab9e500323333573466e1d40092002212200123263201033573802202001c01a26aae7540044dd5000919191999ab9a3370ea002900311909111180200298039aba135573ca00646666ae68cdc3a8012400846424444600400a60126ae84d55cf280211999ab9a3370ea006900111909111180080298039aba135573ca00a46666ae68cdc3a8022400046424444600600a6eb8d5d09aab9e500623263201033573802202001c01a01801626aae7540044dd5000919191999ab9a3370e6aae7540092000233221233001003002300535742a0046eb4d5d09aba2500223263200c33573801a01801426aae7940044dd50009191999ab9a3370e6aae75400520002375c6ae84d55cf280111931900519ab9c00b00a00813754002464646464646666ae68cdc3a800a401842444444400646666ae68cdc3a8012401442444444400846666ae68cdc3a801a40104664424444444660020120106eb8d5d0a8029bad357426ae8940148cccd5cd19b875004480188cc8848888888cc008024020dd71aba15007375c6ae84d5d1280391999ab9a3370ea00a900211991091111111980300480418061aba15009375c6ae84d5d1280491999ab9a3370ea00c900111909111111180380418069aba135573ca01646666ae68cdc3a803a400046424444444600a010601c6ae84d55cf280611931900999ab9c01401301101000f00e00d00c00b135573aa00826aae79400c4d55cf280109aab9e5001137540024646464646666ae68cdc3a800a4004466644424466600200a0080066eb4d5d0a8021bad35742a0066eb4d5d09aba2500323333573466e1d4009200023212230020033008357426aae7940188c98c8030cd5ce00680600500489aab9d5003135744a00226aae7940044dd5000919191999ab9a3370ea002900111909118008019bae357426aae79400c8cccd5cd19b875002480008c8488c00800cdd71aba135573ca008464c6401266ae7002802401c0184d55cea80089baa00112232323333573466e1d400520042122200123333573466e1d40092002232122230030043006357426aae7940108cccd5cd19b87500348000848880088c98c8028cd5ce00580500400380309aab9d5001137540024646666ae68cdc3a800a4004401846666ae68cdc3a801240004018464c6400c66ae7001c01801000c4d55ce9baa00149848005240103505431003200135500822112225335001135003220012213335005220023004002333553007120010050040011122300200132001355006222533500110022213500222330073330080020060010033200135500522225335001100222135002225335333573466e1c005200000a0091333008007006003133300800733500b123330010080030020060031220021220011122002122122330010040031123230010012233003300200200133512233002488120f160ee01ff83321e37289837d6998273c4629667fb8f85b1a938fab81e01806b00480088848cc00400c008800522010a5468726561645f4e46540001" + "cborHex": "5909e15909de01000033323322332232323232323232323232323232323232323232323222322232325335330053357389211d52656465656d6572206465636f646564207375636365737366756c6c79003333573466e1cd55ce9baa0044800080688c98c8068cd5ce00d80d00c19ab9c4912353637269707420636f6e74657874206465636f646564207375636365737366756c6c79003333573466e1cd55cea80124000466442466002006004646464646464646464646464646666ae68cdc39aab9d500c480008cccccccccccc88888888888848cccccccccccc00403403002c02802402001c01801401000c008cd4064068d5d0a80619a80c80d1aba1500b33501901b35742a014666aa03aeb94070d5d0a804999aa80ebae501c35742a01066a0320446ae85401cccd5407408dd69aba150063232323333573466e1cd55cea801240004664424660020060046464646666ae68cdc39aab9d5002480008cc8848cc00400c008cd40b5d69aba15002302e357426ae8940088c98c80c0cd5ce01881801709aab9e5001137540026ae854008c8c8c8cccd5cd19b8735573aa004900011991091980080180119a816bad35742a004605c6ae84d5d1280111931901819ab9c03103002e135573ca00226ea8004d5d09aba2500223263202c33573805a05805426aae7940044dd50009aba1500533501975c6ae854010ccd5407407c8004d5d0a801999aa80ebae200135742a00460426ae84d5d1280111931901419ab9c029028026135744a00226ae8940044d5d1280089aba25001135744a00226ae8940044d5d1280089aba25001135744a00226ae8940044d55cf280089baa00135742a00460226ae84d5d1280111931900d19ab9c01b01a01810191326320193357389210350543500019135573ca00226ea8004c8c888c94cd54cd4ccd54c02448004c8c848cc00488ccd401488008008004008d40048800448cc004894cd4008408440040788c94cd4ccd5cd19b8f3500122002350072200202001f1333573466e1cd400488004d401c8800408007c407cd400488008d5400488888888888803040784cd5ce249115554784f206e6f7420636f6e73756d65640001d153355335323301c5021001355001222222222222008101d22135002222533500415335333573466e3c00802408c0884ccd5cd19b870014800808c088408888409040784cd5ce24811377726f6e6720616d6f756e74206d696e7465640001d101d13500122002333500475c92011f436f756c646e277420646573657269616c697a6520546f6b656e4e616d652e00002333500300c4911e436f756c646e277420646573657269616c697a652054784f75745265662e0000212223357380046006002640026aa0304422444a66a00226a00644002442666a00a440046008004666aa600e2400200a0080022464460046eb0004c8004d5406088cccd55cf8009280d119a80c98021aba1002300335744004024464646666ae68cdc39aab9d5002480008cc8848cc00400c008c028d5d0a80118029aba135744a004464c6402466ae7004c0480404d55cf280089baa0012323232323333573466e1cd55cea8022400046666444424666600200a0080060046464646666ae68cdc39aab9d5002480008cc8848cc00400c008c04cd5d0a80119a8068091aba135744a004464c6402e66ae7006005c0544d55cf280089baa00135742a008666aa010eb9401cd5d0a8019919191999ab9a3370ea0029002119091118010021aba135573ca00646666ae68cdc3a80124004464244460020086eb8d5d09aab9e500423333573466e1d400d20002122200323263201933573803403202e02c02a26aae7540044dd50009aba1500233500975c6ae84d5d1280111931900999ab9c014013011135744a00226ae8940044d55cf280089baa0011335500175ceb44488c88c008dd5800990009aa80a91191999aab9f00225018233501733221233001003002300635573aa004600a6aae794008c010d5d100180809aba100112232323333573466e1d4005200023212230020033005357426aae79400c8cccd5cd19b8750024800884880048c98c8040cd5ce00880800700689aab9d500113754002464646666ae68cdc3a800a400c46424444600800a600e6ae84d55cf280191999ab9a3370ea004900211909111180100298049aba135573ca00846666ae68cdc3a801a400446424444600200a600e6ae84d55cf280291999ab9a3370ea00890001190911118018029bae357426aae7940188c98c8040cd5ce00880800700680600589aab9d500113754002464646666ae68cdc39aab9d5002480008cc8848cc00400c008c014d5d0a8011bad357426ae8940088c98c8030cd5ce00680600509aab9e5001137540024646666ae68cdc39aab9d5001480008dd71aba135573ca004464c6401466ae7002c0280204dd5000919191919191999ab9a3370ea002900610911111100191999ab9a3370ea004900510911111100211999ab9a3370ea00690041199109111111198008048041bae35742a00a6eb4d5d09aba2500523333573466e1d40112006233221222222233002009008375c6ae85401cdd71aba135744a00e46666ae68cdc3a802a400846644244444446600c01201060186ae854024dd71aba135744a01246666ae68cdc3a8032400446424444444600e010601a6ae84d55cf280591999ab9a3370ea00e900011909111111180280418071aba135573ca018464c6402666ae7005004c04404003c03803403002c4d55cea80209aab9e5003135573ca00426aae7940044dd50009191919191999ab9a3370ea002900111999110911998008028020019bad35742a0086eb4d5d0a8019bad357426ae89400c8cccd5cd19b875002480008c8488c00800cc020d5d09aab9e500623263200c33573801a01801401226aae75400c4d5d1280089aab9e500113754002464646666ae68cdc3a800a400446424460020066eb8d5d09aab9e500323333573466e1d400920002321223002003375c6ae84d55cf280211931900499ab9c00a009007006135573aa00226ea8004488c8c8cccd5cd19b87500148010848880048cccd5cd19b875002480088c84888c00c010c018d5d09aab9e500423333573466e1d400d20002122200223263200a33573801601401000e00c26aae7540044dd50009191999ab9a3370ea0029001100511999ab9a3370ea0049000100511931900319ab9c007006004003135573a6ea80052612001491035054310032001355006222533500110022213500222330073330080020060010033200135500522225335001100222135002225335333573466e1c005200000a0091333008007006003133300800733500b12333001008003002006003122002122001112200212212233001004003112323001001223300330020020014c12bd8799fd8799f5820f160ee01ff83321e37289837d6998273c4629667fb8f85b1a938fab81e01806bff01ff004c010b4a5468726561645f4e46540001" } diff --git a/scripts/nft_unapplied.json b/scripts/nft_unapplied.json new file mode 100644 index 0000000..f5dd1d4 --- /dev/null +++ b/scripts/nft_unapplied.json @@ -0,0 +1,5 @@ +{ + "type": "PlutusScriptV2", + "description": "", + "cborHex": "5909a259099f010000323322332232323232323232323232323232323232323232323222322232325335330053357389211d52656465656d6572206465636f646564207375636365737366756c6c79003333573466e1cd55ce9baa0044800080688c98c8068cd5ce00d80d00c19ab9c4912353637269707420636f6e74657874206465636f646564207375636365737366756c6c79003333573466e1cd55cea80124000466442466002006004646464646464646464646464646666ae68cdc39aab9d500c480008cccccccccccc88888888888848cccccccccccc00403403002c02802402001c01801401000c008cd4064068d5d0a80619a80c80d1aba1500b33501901b35742a014666aa03aeb94070d5d0a804999aa80ebae501c35742a01066a0320446ae85401cccd5407408dd69aba150063232323333573466e1cd55cea801240004664424660020060046464646666ae68cdc39aab9d5002480008cc8848cc00400c008cd40b5d69aba15002302e357426ae8940088c98c80c0cd5ce01881801709aab9e5001137540026ae854008c8c8c8cccd5cd19b8735573aa004900011991091980080180119a816bad35742a004605c6ae84d5d1280111931901819ab9c03103002e135573ca00226ea8004d5d09aba2500223263202c33573805a05805426aae7940044dd50009aba1500533501975c6ae854010ccd5407407c8004d5d0a801999aa80ebae200135742a00460426ae84d5d1280111931901419ab9c029028026135744a00226ae8940044d5d1280089aba25001135744a00226ae8940044d5d1280089aba25001135744a00226ae8940044d55cf280089baa00135742a00460226ae84d5d1280111931900d19ab9c01b01a01810191326320193357389210350543500019135573ca00226ea8004c8c888c94cd54cd4ccd54c02448004c8c848cc00488ccd401488008008004008d40048800448cc004894cd4008408440040788c94cd4ccd5cd19b8f3500122002350072200202001f1333573466e1cd400488004d401c8800408007c407cd400488008d5400488888888888803040784cd5ce249115554784f206e6f7420636f6e73756d65640001d153355335323301c5021001355001222222222222008101d22135002222533500415335333573466e3c00802408c0884ccd5cd19b870014800808c088408888409040784cd5ce24811377726f6e6720616d6f756e74206d696e7465640001d101d13500122002333500475c92011f436f756c646e277420646573657269616c697a6520546f6b656e4e616d652e00002333500300c4911e436f756c646e277420646573657269616c697a652054784f75745265662e0000212223357380046006002640026aa0304422444a66a00226a00644002442666a00a440046008004666aa600e2400200a0080022464460046eb0004c8004d5406088cccd55cf8009280d119a80c98021aba1002300335744004024464646666ae68cdc39aab9d5002480008cc8848cc00400c008c028d5d0a80118029aba135744a004464c6402466ae7004c0480404d55cf280089baa0012323232323333573466e1cd55cea8022400046666444424666600200a0080060046464646666ae68cdc39aab9d5002480008cc8848cc00400c008c04cd5d0a80119a8068091aba135744a004464c6402e66ae7006005c0544d55cf280089baa00135742a008666aa010eb9401cd5d0a8019919191999ab9a3370ea0029002119091118010021aba135573ca00646666ae68cdc3a80124004464244460020086eb8d5d09aab9e500423333573466e1d400d20002122200323263201933573803403202e02c02a26aae7540044dd50009aba1500233500975c6ae84d5d1280111931900999ab9c014013011135744a00226ae8940044d55cf280089baa0011335500175ceb44488c88c008dd5800990009aa80a91191999aab9f00225018233501733221233001003002300635573aa004600a6aae794008c010d5d100180809aba100112232323333573466e1d4005200023212230020033005357426aae79400c8cccd5cd19b8750024800884880048c98c8040cd5ce00880800700689aab9d500113754002464646666ae68cdc3a800a400c46424444600800a600e6ae84d55cf280191999ab9a3370ea004900211909111180100298049aba135573ca00846666ae68cdc3a801a400446424444600200a600e6ae84d55cf280291999ab9a3370ea00890001190911118018029bae357426aae7940188c98c8040cd5ce00880800700680600589aab9d500113754002464646666ae68cdc39aab9d5002480008cc8848cc00400c008c014d5d0a8011bad357426ae8940088c98c8030cd5ce00680600509aab9e5001137540024646666ae68cdc39aab9d5001480008dd71aba135573ca004464c6401466ae7002c0280204dd5000919191919191999ab9a3370ea002900610911111100191999ab9a3370ea004900510911111100211999ab9a3370ea00690041199109111111198008048041bae35742a00a6eb4d5d09aba2500523333573466e1d40112006233221222222233002009008375c6ae85401cdd71aba135744a00e46666ae68cdc3a802a400846644244444446600c01201060186ae854024dd71aba135744a01246666ae68cdc3a8032400446424444444600e010601a6ae84d55cf280591999ab9a3370ea00e900011909111111180280418071aba135573ca018464c6402666ae7005004c04404003c03803403002c4d55cea80209aab9e5003135573ca00426aae7940044dd50009191919191999ab9a3370ea002900111999110911998008028020019bad35742a0086eb4d5d0a8019bad357426ae89400c8cccd5cd19b875002480008c8488c00800cc020d5d09aab9e500623263200c33573801a01801401226aae75400c4d5d1280089aab9e500113754002464646666ae68cdc3a800a400446424460020066eb8d5d09aab9e500323333573466e1d400920002321223002003375c6ae84d55cf280211931900499ab9c00a009007006135573aa00226ea8004488c8c8cccd5cd19b87500148010848880048cccd5cd19b875002480088c84888c00c010c018d5d09aab9e500423333573466e1d400d20002122200223263200a33573801601401000e00c26aae7540044dd50009191999ab9a3370ea0029001100511999ab9a3370ea0049000100511931900319ab9c007006004003135573a6ea80052612001491035054310032001355006222533500110022213500222330073330080020060010033200135500522225335001100222135002225335333573466e1c005200000a0091333008007006003133300800733500b12333001008003002006003122002122001112200212212233001004003112323001001223300330020020011" +} diff --git a/scripts/token.json b/scripts/token.json index 9cfeeb8..0c88457 100644 --- a/scripts/token.json +++ b/scripts/token.json @@ -1,5 +1,5 @@ { "type": "PlutusScriptV2", "description": "", - "cborHex": "5909da5909d7010000333233223322323232323232323232323232323232323232323232322322335501322232325335330053357389211d52656465656d6572206465636f646564207375636365737366756c6c79003333573466e1cd55ce9baa0044800080748c98c8074cd5ce00c00e80d99ab9c4912353637269707420636f6e74657874206465636f646564207375636365737366756c6c79003333573466e1cd55cea80124000466442466002006004646464646464646464646464646666ae68cdc39aab9d500c480008cccccccccccc88888888888848cccccccccccc00403403002c02802402001c01801401000c008cd4060064d5d0a80619a80c00c9aba1500b33501801a35742a014666aa038eb9406cd5d0a804999aa80e3ae501b35742a01066a0300426ae85401cccd54070089d69aba150063232323333573466e1cd55cea801240004664424660020060046464646666ae68cdc39aab9d5002480008cc8848cc00400c008cd40b1d69aba15002302d357426ae8940088c98c80cccd5ce01701981889aab9e5001137540026ae854008c8c8c8cccd5cd19b8735573aa004900011991091980080180119a8163ad35742a004605a6ae84d5d1280111931901999ab9c02e033031135573ca00226ea8004d5d09aba2500223263202f33573805405e05a26aae7940044dd50009aba1500533501875c6ae854010ccd540700788004d5d0a801999aa80e3ae200135742a00460406ae84d5d1280111931901599ab9c02602b029135744a00226ae8940044d5d1280089aba25001135744a00226ae8940044d5d1280089aba25001135744a00226ae8940044d55cf280089baa00135742a00460206ae84d5d1280111931900e99ab9c01801d01b101c13501a49010350543500135573ca00226ea800488c94cd4c8ccd5cd19b89001480000800854cd4c8cc071407c004c8d400488888888888802140044c05d2622135002222533500415335333573466e3c00802409409040044d407524010f696e636f727265637420746f6b656e00221301e4984c94cd400440844cd5ce24810f6e6f206e667420696e20696e7075740002053353005323500122222222222200c5001101f221533500110222210231020135001220023200135501c2253350011501b23221533533550162333573466e1cc8c8c8c8c004014c8004d5409488cd400520002235002225335333573466e3c0080240a80a44c01c0044c01800cc8004d5409088cd400520002235002225335333573466e3c00801c0a40a040044c01800cd402088004d401c880092002021020323500122220035002133501d5002300500113005001135001220011232230023758002640026aa036446666aae7c0049406c8cd4068c010d5d080118019aba2002016232323333573466e1cd55cea8012400046644246600200600460146ae854008c014d5d09aba2500223263201633573802202c02826aae7940044dd50009191919191999ab9a3370e6aae75401120002333322221233330010050040030023232323333573466e1cd55cea8012400046644246600200600460266ae854008cd4034048d5d09aba2500223263201b33573802c03603226aae7940044dd50009aba150043335500875ca00e6ae85400cc8c8c8cccd5cd19b875001480108c84888c008010d5d09aab9e500323333573466e1d4009200223212223001004375c6ae84d55cf280211999ab9a3370ea00690001091100191931900e99ab9c01801d01b01a019135573aa00226ea8004d5d0a80119a804bae357426ae8940088c98c805ccd5ce00900b80a89aba25001135744a00226aae7940044dd5000899aa800bae75a224464460046eac004c8004d5406088c8cccd55cf8011280c919a80c1991091980080180118031aab9d5002300535573ca00460086ae8800c0504d5d080089119191999ab9a3370ea0029000119091180100198029aba135573ca00646666ae68cdc3a801240044244002464c6402866ae7003c0500480444d55cea80089baa001232323333573466e1d400520062321222230040053007357426aae79400c8cccd5cd19b875002480108c848888c008014c024d5d09aab9e500423333573466e1d400d20022321222230010053007357426aae7940148cccd5cd19b875004480008c848888c00c014dd71aba135573ca00c464c6402866ae7003c05004804404003c4d55cea80089baa001232323333573466e1cd55cea80124000466442466002006004600a6ae854008dd69aba135744a004464c6402066ae7002c0400384d55cf280089baa0012323333573466e1cd55cea800a400046eb8d5d09aab9e500223263200e33573801201c01826ea80048c8c8c8c8c8cccd5cd19b8750014803084888888800c8cccd5cd19b875002480288488888880108cccd5cd19b875003480208cc8848888888cc004024020dd71aba15005375a6ae84d5d1280291999ab9a3370ea00890031199109111111198010048041bae35742a00e6eb8d5d09aba2500723333573466e1d40152004233221222222233006009008300c35742a0126eb8d5d09aba2500923333573466e1d40192002232122222223007008300d357426aae79402c8cccd5cd19b875007480008c848888888c014020c038d5d09aab9e500c23263201733573802402e02a02802602402202001e26aae7540104d55cf280189aab9e5002135573ca00226ea80048c8c8c8c8cccd5cd19b875001480088ccc888488ccc00401401000cdd69aba15004375a6ae85400cdd69aba135744a00646666ae68cdc3a80124000464244600400660106ae84d55cf280311931900819ab9c00b01000e00d135573aa00626ae8940044d55cf280089baa001232323333573466e1d400520022321223001003375c6ae84d55cf280191999ab9a3370ea004900011909118010019bae357426aae7940108c98c8034cd5ce00400680580509aab9d50011375400224464646666ae68cdc3a800a40084244400246666ae68cdc3a8012400446424446006008600c6ae84d55cf280211999ab9a3370ea00690001091100111931900719ab9c00900e00c00b00a135573aa00226ea80048c8cccd5cd19b87500148008803c8cccd5cd19b87500248000803c8c98c8028cd5ce00280500400389aab9d37540029201035054310011223002001235002491136578706563746564206f6e6520706f6c6963790012326320033357380020069309000990009aa803111299a80088011109a8011119803999804001003000801990009aa8029111299a80088011109a80111299a999ab9a3370e00290000060058999804003803001899980400399a804891998008040018010030018891001091091198008020018910010910008891918008009119801980100100099a891198012451c3523a559f6d9af65bfd05f6f827eb3c6adf6ca9d295878461e567fd60048810a5468726561645f4e46540022123300100300220014890654546f6b656e0001" + "cborHex": "590a55590a520100003332323233223233223232323232323232323232323232323232323222322232325335330053357389211d52656465656d6572206465636f646564207375636365737366756c6c79003333573466e1cd55ce9baa0044800080888c98c8088cd5ce00c01101019ab9c4912353637269707420636f6e74657874206465636f646564207375636365737366756c6c79003333573466e1cd55cea80124000466442466002006004646464646464646464646464646666ae68cdc39aab9d500c480008cccccccccccc88888888888848cccccccccccc00403403002c02802402001c01801401000c008cd4060064d5d0a80619a80c00c9aba1500b33501801a35742a014666aa038eb9406cd5d0a804999aa80e3ae501b35742a01066a0300426ae85401cccd54070089d69aba150063232323333573466e1cd55cea801240004664424660020060046464646666ae68cdc39aab9d5002480008cc8848cc00400c008cd40b1d69aba15002302d357426ae8940088c98c80e0cd5ce01701c01b09aab9e5001137540026ae854008c8c8c8cccd5cd19b8735573aa004900011991091980080180119a8163ad35742a004605a6ae84d5d1280111931901c19ab9c02e038036135573ca00226ea8004d5d09aba2500223263203433573805406806426aae7940044dd50009aba1500533501875c6ae854010ccd540700788004d5d0a801999aa80e3ae200135742a00460406ae84d5d1280111931901819ab9c02603002e135744a00226ae8940044d5d1280089aba25001135744a00226ae8940044d5d1280089aba25001135744a00226ae8940044d55cf280089baa00135742a00460206ae84d5d1280111931901119ab9c01802202010211326320213357389210350543500021135573ca00226ea8004c8c888c94cd4ccd5cd19b895335323301a501d00135500122222222222200813018498884d40088894cd401054cd4ccd5cd19b8f00200902402310011326320263357389210f696e636f727265637420746f6b656e00026221301f499200001e01f15335332232300135500422222222222200c3200135502422533500110032322132533532333573466e1cc8c8c8c8c004014c8004d540b888cd400520002235002225335333573466e3c0080240c40c04c01c0044c01800cc8004d540b488cd400520002235002225335333573466e3c00801c0c00bc40044c01800cd403c88004d4038880092002028027355003222200313300850030011001300500113500122001501b501c1301d4988854cd40044084884c08526101f13500122002333500475c92119436f756c646e2774206465636f646520546f6b656e4e616d65000023335003232323333573466e1cd55cea801240004664424660020060046eb8d5d0a8011bae357426ae8940088c98c8080cd5ce00b01000f09aab9e500113754002920119436f756c646e2774206465636f6465204e4654506172616d7300002122233573800460060022464460046eb0004c8004d5406888cccd55cf8009280b919a80b18021aba1002300335744004036464646666ae68cdc39aab9d5002480008cc8848cc00400c008c028d5d0a80118029aba135744a004464c6403666ae7004406c0644d55cf280089baa0012323232323333573466e1cd55cea8022400046666444424666600200a0080060046464646666ae68cdc39aab9d5002480008cc8848cc00400c008c04cd5d0a80119a8068091aba135744a004464c6404066ae700580800784d55cf280089baa00135742a008666aa010eb9401cd5d0a8019919191999ab9a3370ea0029002119091118010021aba135573ca00646666ae68cdc3a80124004464244460020086eb8d5d09aab9e500423333573466e1d400d20002122200323263202233573803004404003e03c26aae7540044dd50009aba1500233500975c6ae84d5d1280111931900e19ab9c01201c01a135744a00226ae8940044d55cf280089baa0011335500175ceb44488c88c008dd5800990009aa80b91191999aab9f00225015233501433221233001003002300635573aa004600a6aae794008c010d5d100180c89aba100112232323333573466e1d4005200023212230020033005357426aae79400c8cccd5cd19b8750024800884880048c98c8064cd5ce00780c80b80b09aab9d500113754002464646666ae68cdc3a800a400c46424444600800a600e6ae84d55cf280191999ab9a3370ea004900211909111180100298049aba135573ca00846666ae68cdc3a801a400446424444600200a600e6ae84d55cf280291999ab9a3370ea00890001190911118018029bae357426aae7940188c98c8064cd5ce00780c80b80b00a80a09aab9d500113754002464646666ae68cdc39aab9d5002480008cc8848cc00400c008c014d5d0a8011bad357426ae8940088c98c8054cd5ce00580a80989aab9e5001137540024646666ae68cdc39aab9d5001480008dd71aba135573ca004464c6402666ae7002404c0444dd5000919191919191999ab9a3370ea002900610911111100191999ab9a3370ea004900510911111100211999ab9a3370ea00690041199109111111198008048041bae35742a00a6eb4d5d09aba2500523333573466e1d40112006233221222222233002009008375c6ae85401cdd71aba135744a00e46666ae68cdc3a802a400846644244444446600c01201060186ae854024dd71aba135744a01246666ae68cdc3a8032400446424444444600e010601a6ae84d55cf280591999ab9a3370ea00e900011909111111180280418071aba135573ca018464c6403866ae7004807006806406005c0580540504d55cea80209aab9e5003135573ca00426aae7940044dd50009191919191999ab9a3370ea002900111999110911998008028020019bad35742a0086eb4d5d0a8019bad357426ae89400c8cccd5cd19b875002480008c8488c00800cc020d5d09aab9e500623263201533573801602a02602426aae75400c4d5d1280089aab9e500113754002464646666ae68cdc3a800a400446424460020066eb8d5d09aab9e500323333573466e1d400920002321223002003375c6ae84d55cf280211931900919ab9c00801201000f135573aa00226ea8004488c8c8cccd5cd19b87500148010848880048cccd5cd19b875002480088c84888c00c010c018d5d09aab9e500423333573466e1d400d20002122200223263201333573801202602202001e26aae7540044dd50009191999ab9a3370ea0029001100611999ab9a3370ea0049000100611931900799ab9c00500f00d00c135573a6ea8005241035054310023263200a335738921136578706563746564206f6e6520706f6c6963790000a32001355009222533500110022213500222330073330080020060010033200135500822225335001100222135002225335333573466e1c005200000d00c133300800700600313330080073350091233300100800300200600311220021221223300100400323263200533573892010f6e6f204e465420696e20696e7075740000512200212200149848004448c8c00400488cc00cc00800800530012dd8799f581c1e579092d8569370cf046b7b7ec3e1cdc8d9d27f237d522304ef00d84a5468726561645f4e4654ff004c01074654546f6b656e0001" } diff --git a/scripts/token_unapplied.json b/scripts/token_unapplied.json new file mode 100644 index 0000000..74f2d96 --- /dev/null +++ b/scripts/token_unapplied.json @@ -0,0 +1,5 @@ +{ + "type": "PlutusScriptV2", + "description": "", + "cborHex": "590a17590a1401000032323233223233223232323232323232323232323232323232323222322232325335330053357389211d52656465656d6572206465636f646564207375636365737366756c6c79003333573466e1cd55ce9baa0044800080888c98c8088cd5ce00c01101019ab9c4912353637269707420636f6e74657874206465636f646564207375636365737366756c6c79003333573466e1cd55cea80124000466442466002006004646464646464646464646464646666ae68cdc39aab9d500c480008cccccccccccc88888888888848cccccccccccc00403403002c02802402001c01801401000c008cd4060064d5d0a80619a80c00c9aba1500b33501801a35742a014666aa038eb9406cd5d0a804999aa80e3ae501b35742a01066a0300426ae85401cccd54070089d69aba150063232323333573466e1cd55cea801240004664424660020060046464646666ae68cdc39aab9d5002480008cc8848cc00400c008cd40b1d69aba15002302d357426ae8940088c98c80e0cd5ce01701c01b09aab9e5001137540026ae854008c8c8c8cccd5cd19b8735573aa004900011991091980080180119a8163ad35742a004605a6ae84d5d1280111931901c19ab9c02e038036135573ca00226ea8004d5d09aba2500223263203433573805406806426aae7940044dd50009aba1500533501875c6ae854010ccd540700788004d5d0a801999aa80e3ae200135742a00460406ae84d5d1280111931901819ab9c02603002e135744a00226ae8940044d5d1280089aba25001135744a00226ae8940044d5d1280089aba25001135744a00226ae8940044d55cf280089baa00135742a00460206ae84d5d1280111931901119ab9c01802202010211326320213357389210350543500021135573ca00226ea8004c8c888c94cd4ccd5cd19b895335323301a501d00135500122222222222200813018498884d40088894cd401054cd4ccd5cd19b8f00200902402310011326320263357389210f696e636f727265637420746f6b656e00026221301f499200001e01f15335332232300135500422222222222200c3200135502422533500110032322132533532333573466e1cc8c8c8c8c004014c8004d540b888cd400520002235002225335333573466e3c0080240c40c04c01c0044c01800cc8004d540b488cd400520002235002225335333573466e3c00801c0c00bc40044c01800cd403c88004d4038880092002028027355003222200313300850030011001300500113500122001501b501c1301d4988854cd40044084884c08526101f13500122002333500475c92119436f756c646e2774206465636f646520546f6b656e4e616d65000023335003232323333573466e1cd55cea801240004664424660020060046eb8d5d0a8011bae357426ae8940088c98c8080cd5ce00b01000f09aab9e500113754002920119436f756c646e2774206465636f6465204e4654506172616d7300002122233573800460060022464460046eb0004c8004d5406888cccd55cf8009280b919a80b18021aba1002300335744004036464646666ae68cdc39aab9d5002480008cc8848cc00400c008c028d5d0a80118029aba135744a004464c6403666ae7004406c0644d55cf280089baa0012323232323333573466e1cd55cea8022400046666444424666600200a0080060046464646666ae68cdc39aab9d5002480008cc8848cc00400c008c04cd5d0a80119a8068091aba135744a004464c6404066ae700580800784d55cf280089baa00135742a008666aa010eb9401cd5d0a8019919191999ab9a3370ea0029002119091118010021aba135573ca00646666ae68cdc3a80124004464244460020086eb8d5d09aab9e500423333573466e1d400d20002122200323263202233573803004404003e03c26aae7540044dd50009aba1500233500975c6ae84d5d1280111931900e19ab9c01201c01a135744a00226ae8940044d55cf280089baa0011335500175ceb44488c88c008dd5800990009aa80b91191999aab9f00225015233501433221233001003002300635573aa004600a6aae794008c010d5d100180c89aba100112232323333573466e1d4005200023212230020033005357426aae79400c8cccd5cd19b8750024800884880048c98c8064cd5ce00780c80b80b09aab9d500113754002464646666ae68cdc3a800a400c46424444600800a600e6ae84d55cf280191999ab9a3370ea004900211909111180100298049aba135573ca00846666ae68cdc3a801a400446424444600200a600e6ae84d55cf280291999ab9a3370ea00890001190911118018029bae357426aae7940188c98c8064cd5ce00780c80b80b00a80a09aab9d500113754002464646666ae68cdc39aab9d5002480008cc8848cc00400c008c014d5d0a8011bad357426ae8940088c98c8054cd5ce00580a80989aab9e5001137540024646666ae68cdc39aab9d5001480008dd71aba135573ca004464c6402666ae7002404c0444dd5000919191919191999ab9a3370ea002900610911111100191999ab9a3370ea004900510911111100211999ab9a3370ea00690041199109111111198008048041bae35742a00a6eb4d5d09aba2500523333573466e1d40112006233221222222233002009008375c6ae85401cdd71aba135744a00e46666ae68cdc3a802a400846644244444446600c01201060186ae854024dd71aba135744a01246666ae68cdc3a8032400446424444444600e010601a6ae84d55cf280591999ab9a3370ea00e900011909111111180280418071aba135573ca018464c6403866ae7004807006806406005c0580540504d55cea80209aab9e5003135573ca00426aae7940044dd50009191919191999ab9a3370ea002900111999110911998008028020019bad35742a0086eb4d5d0a8019bad357426ae89400c8cccd5cd19b875002480008c8488c00800cc020d5d09aab9e500623263201533573801602a02602426aae75400c4d5d1280089aab9e500113754002464646666ae68cdc3a800a400446424460020066eb8d5d09aab9e500323333573466e1d400920002321223002003375c6ae84d55cf280211931900919ab9c00801201000f135573aa00226ea8004488c8c8cccd5cd19b87500148010848880048cccd5cd19b875002480088c84888c00c010c018d5d09aab9e500423333573466e1d400d20002122200223263201333573801202602202001e26aae7540044dd50009191999ab9a3370ea0029001100611999ab9a3370ea0049000100611931900799ab9c00500f00d00c135573a6ea8005241035054310023263200a335738921136578706563746564206f6e6520706f6c6963790000a32001355009222533500110022213500222330073330080020060010033200135500822225335001100222135002225335333573466e1c005200000d00c133300800700600313330080073350091233300100800300200600311220021221223300100400323263200533573892010f6e6f204e465420696e20696e7075740000512200212200149848004448c8c00400488cc00cc008008005" +} diff --git a/scripts/validator.json b/scripts/validator.json index 49ba1ae..5a843ca 100644 --- a/scripts/validator.json +++ b/scripts/validator.json @@ -1,5 +1,5 @@ { "type": "PlutusScriptV2", "description": "", - "cborHex": "590f1a590f1701000033232332233223232323233223232323232323232323232323232323232323232323232323232323232323232322335501f22323223232323223232533533300c3357389211944617461206465636f646564207375636365737366756c6c79003333573466e1cd55cea8052400046602466a038eb8d5d0a8051bad357426ae8940288c98c80d4cd5ce01501d01999ab9c4911d52656465656d6572206465636f646564207375636365737366756c6c79003333573466e1d40112006232122223001005375a6ae84d55cf280411999ab9a3370ea00a90021199109111198018030029bae35742a00e6eb4d5d09aba2500723333573466e1d40192002233221222233004006005375c6ae854024dd69aba135744a01246666ae68cdc3a803a4000424444004464c6407066ae700b40f40d80d40d00cccd5ce2492353637269707420636f6e74657874206465636f646564207375636365737366756c6c79003333573466e1cd55cea80124000466442466002006004646464646464646464646464646666ae68cdc39aab9d500c480008cccccccccccc88888888888848cccccccccccc00403403002c02802402001c01801401000c008cd40a80acd5d0a80619a8150159aba1500b33502a02c35742a014666aa05ceb940b4d5d0a804999aa8173ae502d35742a01066a0540666ae85401cccd540b80d1d69aba150063232323333573466e1cd55cea801240004664424660020060046464646666ae68cdc39aab9d5002480008cc8848cc00400c008cd40f9d69aba15002303f357426ae8940088c98c812ccd5ce02002802489aab9e5001137540026ae854008c8c8c8cccd5cd19b8735573aa004900011991091980080180119a81f3ad35742a004607e6ae84d5d1280111931902599ab9c040050049135573ca00226ea8004d5d09aba2500223263204733573807809808a26aae7940044dd50009aba1500533502a75c6ae854010ccd540b80c08004d5d0a801999aa8173ae200135742a00460646ae84d5d1280111931902199ab9c038048041135744a00226ae8940044d5d1280089aba25001135744a00226ae8940044d5d1280089aba25001135744a00226ae8940044d55cf280089baa00135742a00460446ae84d5d1280111931901a99ab9c02a03a033103913503249010350543500135573ca00226ea80044d55cea80189aab9e5002135573ca00226ea80044d55cf280089baa0012223232330273300749011b4e6f7420656e6f756768206f776e657273207369676e65642074780033026335500b300c12001335012233355300d12001323350112233350032200200200135001220011233001225335002102d100102a30120013235001222222222222004350042200230080053009005533335004221330293300949010f4f776e6572206e6f742061646465640033003335030002300a007001330270013233700002900119aa80698070900098050039109981499804a481114f776e6572206e6f742072656d6f76656400330033350142533533014001003102b102c300a007001330270013233702002900119aa8069807090009805003899803a48111446174756d20776173206368616e676564003300130080053009005213302833008491155468726573686f6c64206e6f7420757064617465640033002300900600133026001335500c300d120013009006225335330283332001353024120010120023009500333011001300a5003102a13502c49117756e6578706563746564206f757470757420646174756d0015333532350012222002533553353500122350022222222222223333500d2503d2503d2503d23335530191200133501c225335002210031001503d2350012253355335333573466e3cd400888008d4010880080e40e04ccd5cd19b873500222001350042200103903810381350410031504000d213500122350012222350082235002222222222222333553026120012235002222253353501822350062232335005233500425335333573466e3c0080041241205400c412081208cd4010812094cd4ccd5cd19b8f0020010490481500310481533500321533500221335002233500223350022335002233034002001204b2335002204b23303400200122204b222335004204b2225335333573466e1c01800c13813454cd4ccd5cd19b8700500204e04d133035004001104d104d10461533500121046104613350470060051005504200a13263202b3357389201024c6600030130284988854cd400454cd4cd540908ccd5cd19b8732323232300100532001355037223350014800088d4008894cd4ccd5cd19b8f002009033032130070011300600332001355036223350014800088d4008894cd4ccd5cd19b8f00200703203110011300600335008220013500722002480080a80a4cd540908d4004888800c00840084c0a926221302c4984d40a52410f6e6f20696e6c696e6520646174756d002323232153353333333574800846666ae68cdc39aab9d5004480008cccd55cfa8021281a91999aab9f500425036233335573e6ae89401494cd54cd4c8ccccccd5d20009281c9281c9181b1bac002250392503903a35742a00e426a07260240022a06e42a66a646666666ae90004940e8940e8940e88d40ecdd68011281d01d9aba15007213503a30020011503815037250370380370362503402f250332503325033250330342100113502d49112696e76616c696420646174756d207479706500135744a00226aae7940044dd5000909a8152490f6e6f20696e6c696e6520646174756d002253350011024133573800404646a0024400446a0024400244246600200600422446666aa0046466a00e44666a0100060020046a00a00266a00c4446006600400240024466e00005200200148000c8004d5409c88448894cd40044d401800c884ccd4024014c010008ccd54c01c4800401401000448d40048800448d40048800848848cc00400c00888ccd5cd19b8700200101b01a22333573466e3c00800406806448cd54c00848004894cd4c00c0084cd407c00800440054078c8004d5408088448894cd40044008884cc014008ccd54c01c4800401401000448c88c008dd6000990009aa810111999aab9f0012501f233501e30043574200460066ae880080848c8c8cccd5cd19b8735573aa004900011991091980080180118051aba150023005357426ae8940088c98c8070cd5ce00881080d09aab9e5001137540024646464646666ae68cdc39aab9d5004480008cccc888848cccc00401401000c008c8c8c8cccd5cd19b8735573aa004900011991091980080180118099aba1500233500d012357426ae8940088c98c8084cd5ce00b01300f89aab9e5001137540026ae854010ccd54021d728039aba150033232323333573466e1d4005200423212223002004357426aae79400c8cccd5cd19b875002480088c84888c004010dd71aba135573ca00846666ae68cdc3a801a400042444006464c6404666ae700600a008408007c4d55cea80089baa00135742a00466a012eb8d5d09aba2500223263201d33573802404403626ae8940044d5d1280089aab9e500113754002266aa002eb9d6889119118011bab0013200135501d223233335573e0044a03a466a03866442466002006004600c6aae754008c014d55cf280118021aba200301f13574200224464646666ae68cdc3a800a400046a03a600a6ae84d55cf280191999ab9a3370ea00490011280e91931900d19ab9c00f01f018017135573aa00226ea80048c8c8cccd5cd19b875001480188c848888c010014c01cd5d09aab9e500323333573466e1d400920042321222230020053009357426aae7940108cccd5cd19b875003480088c848888c004014c01cd5d09aab9e500523333573466e1d40112000232122223003005375c6ae84d55cf280311931900d19ab9c00f01f018017016015135573aa00226ea80048c8c8cccd5cd19b8735573aa004900011991091980080180118029aba15002375a6ae84d5d1280111931900b19ab9c00b01b014135573ca00226ea80048c8cccd5cd19b8735573aa002900011bae357426aae7940088c98c8050cd5ce00480c80909baa001232323232323333573466e1d4005200c21222222200323333573466e1d4009200a21222222200423333573466e1d400d2008233221222222233001009008375c6ae854014dd69aba135744a00a46666ae68cdc3a8022400c4664424444444660040120106eb8d5d0a8039bae357426ae89401c8cccd5cd19b875005480108cc8848888888cc018024020c030d5d0a8049bae357426ae8940248cccd5cd19b875006480088c848888888c01c020c034d5d09aab9e500b23333573466e1d401d2000232122222223005008300e357426aae7940308c98c8074cd5ce00901100d80d00c80c00b80b00a89aab9d5004135573ca00626aae7940084d55cf280089baa0012323232323333573466e1d400520022333222122333001005004003375a6ae854010dd69aba15003375a6ae84d5d1280191999ab9a3370ea0049000119091180100198041aba135573ca00c464c6402c66ae7002c06c05004c4d55cea80189aba25001135573ca00226ea80048c8c8cccd5cd19b875001480088c8488c00400cdd71aba135573ca00646666ae68cdc3a8012400046424460040066eb8d5d09aab9e500423263201333573801003002202026aae7540044dd500089119191999ab9a3370ea00290021091100091999ab9a3370ea00490011190911180180218031aba135573ca00846666ae68cdc3a801a400042444004464c6402866ae700240640480440404d55cea80089baa0012323333573466e1d40052002200b23333573466e1d40092000200b23263201033573800a02a01c01a26aae74dd5000a481035054310032001355010221222533500215335001100b22100c2215335003100c22153353300700400213335300912001007003001100e1122300200122330043300300248010ccd5cd19b8900200100600522333573466e20008004010014894cd40084004400c4880084880048d40092401126e6f206f75747075742077697468206e667400123263200333573800201093190009aa803111999aab9f00123500750052533532333333357480024a0104a0104a0104a01046a0126eb8008024d5d080110a99a98021aba20032135009335006002001150071500600711220021221223300100400312122300200311220011200111232300100122330033002002001335122330024891c3523a559f6d9af65bfd05f6f827eb3c6adf6ca9d295878461e567fd60048810a5468726561645f4e46540022123300100300220011" + "cborHex": "590f82590f7f010000332323322332232323233223232323232323232323232323232323232323232323232323223232322323223232323223232533533300c3357389211944617461206465636f646564207375636365737366756c6c79003333573466e1cd55cea8052400046603066a034eb8d5d0a8051bad357426ae8940288c98c80b8cd5ce01401981619ab9c4911d52656465656d6572206465636f646564207375636365737366756c6c79003333573466e1d40112006232122223001005375a6ae84d55cf280411999ab9a3370ea00a90021199109111198018030029bae35742a00e6eb4d5d09aba2500723333573466e1d40192002233221222233004006005375c6ae854024dd69aba135744a01246666ae68cdc3a803a4000424444004464c6406266ae700ac0d80bc0b80b40b0cd5ce2492353637269707420636f6e74657874206465636f646564207375636365737366756c6c79003333573466e1cd55cea80124000466442466002006004646464646464646464646464646666ae68cdc39aab9d500c480008cccccccccccc88888888888848cccccccccccc00403403002c02802402001c01801401000c008cd40a00a4d5d0a80619a8140149aba1500b33502802a35742a014666aa058eb940acd5d0a804999aa8163ae502b35742a01066a0500626ae85401cccd540b00c9d69aba150063232323333573466e1cd55cea801240004664424660020060046464646666ae68cdc39aab9d5002480008cc8848cc00400c008cd40f1d69aba15002303d357426ae8940088c98c8110cd5ce01f02482109aab9e5001137540026ae854008c8c8c8cccd5cd19b8735573aa004900011991091980080180119a81e3ad35742a004607a6ae84d5d1280111931902219ab9c03e049042135573ca00226ea8004d5d09aba2500223263204033573807408a07c26aae7940044dd50009aba1500533502875c6ae854010ccd540b00b88004d5d0a801999aa8163ae200135742a00460606ae84d5d1280111931901e19ab9c03604103a135744a00226ae8940044d5d1280089aba25001135744a00226ae8940044d5d1280089aba25001135744a00226ae8940044d55cf280089baa00135742a00460406ae84d5d1280111931901719ab9c02803302c103213263202d3357389210350543500032135573ca00226ea80044d55cea80189aab9e5002135573ca00226ea80044d55cf280089baa00132222323253355335333573466e20cd54028c03048004ccd54c02c48004894cd4ccd54c03848004c8cd404888ccd400c88008008004d40048800448cc004894cd400840a44004098c048008d4d4014880088888888888880104cd40a8008004400540a4d401488008d40148800408c09040904cd5ce2491b4e6f7420656e6f756768206f776e657273207369676e6564207478000231533335004221533553353300333502a00235007220020011026133573892010f4f776e6572206e6f74206164646564000251330240013370066aa018601c240026a00e4400490010812910a99aa99a99801999aa98068900091299aa99a9980a00100208138814099a8160010008800a8159a803910010008813099ab9c491114f776e6572206e6f742072656d6f766564000251330240013370266aa018601c240026a00e44004900108128a99a998009a802910011a802910008812099ab9c490111446174756d20776173206368616e676564000232153355335330023500622002001102513357389201155468726573686f6c64206e6f74207570646174656400024133023001335500b300d1200135006220021024102322533553353335301312001011002355003220021333573466e1c004d5400c88004094090409040944c98c80a0cd5ce24917756e6578706563746564206f757470757420646174756d0002d15333535533553353500122350022222222222223333500d25037250372503723335530191200133501c22533500221003100150372350012253355335333573466e3cd400888008d4010880080d00cc4ccd5cd19b8735002220013500422001034033103313503b0031503a00d21350012235001222235008223500222222222222233355301e120012235002222253353501822350062232335005233500425335333573466e3c00800411010c5400c410c810c8cd4010810c94cd4ccd5cd19b8f002001044043150031043153350032153350022133500223350022335002233500223303300200120462335002204623303300200122204622233500420462225335333573466e1c01800c12412054cd4ccd5cd19b870050020490481333573466e1c01000412412041204120410454cd40048410441044cd4104018014401540f00284c98c8094cd5ce249024c660002a130234988854cd400454cd4c8ccd5cd19b8732323232300100532001355031223350014800088d4008894cd4ccd5cd19b8f00200902e02d130070011300600332001355030223350014800088d4008894cd4ccd5cd19b8f00200702d02c1001130060033500822001350072200248008094090d4008888800c40084c09526221302749888880084c98c8094cd5ce2490f6e6f20696e6c696e6520646174756d0002a2323232153353333333574800846666ae68cdc39aab9d5004480008cccd55cfa8021281791999aab9f500425030233335573e6ae89401494cd54cd4c8ccccccd5d20009281992819918181bac002250332503303435742a00e426a06660320022a06242a66a646666666ae90004940d0940d0940d08d40d4dd68011281a01a9aba15007213503430020011503215031250310320310302502e0292502d2502d2502d2502d02e2100113263202933573892112696e76616c696420646174756d20747970650002e135744a00226aae7940044dd5000909931901319ab9c4910f6e6f20696e6c696e6520646174756d0002b33573892119436f756c646e2774206465636f6465204e4654506172616d73003333573466e1cd55cea801240004664424660020060046eb8d5d0a8011bae357426ae8940088c98c8088cd5ce00e01381009aab9e50011375400222446666aa0046466a01044666a0120060020046a00c00266a00e4446006600400240024466e00005200200148000c8004d5408888448894cd40044008884cc014008ccd54c01c48004014010004c8004d5408488448894cd40044d401800c884ccd4024014c010008ccd54c01c4800401401000448d40048800448d40048800848848cc00400c00888ccd5cd19b8f0020010160152212330010030023200135501b22122253350021533500110172210182215335003101822153353300700400213335300912001007003001101a1232230023758002640026aa036446666aae7c004940688cd4064c010d5d080118019aba200201c232323333573466e1cd55cea8012400046644246600200600460146ae854008c014d5d09aba2500223263201733573802203802a26aae7940044dd50009191919191999ab9a3370e6aae75401120002333322221233330010050040030023232323333573466e1cd55cea8012400046644246600200600460266ae854008cd4034048d5d09aba2500223263201c33573802c04203426aae7940044dd50009aba150043335500875ca00e6ae85400cc8c8c8cccd5cd19b875001480108c84888c008010d5d09aab9e500323333573466e1d4009200223212223001004375c6ae84d55cf280211999ab9a3370ea00690001091100191931900f19ab9c01802301c01b01a135573aa00226ea8004d5d0a80119a804bae357426ae8940088c98c8060cd5ce00900e80b09aba25001135744a00226aae7940044dd5000899aa800bae75a224464460046eac004c8004d5406088c8cccd55cf8011280c119a80b9991091980080180118031aab9d5002300535573ca00460086ae8800c0684d5d080089119191999ab9a3370ea002900011a80c18029aba135573ca00646666ae68cdc3a801240044a030464c6402a66ae7003c06804c0484d55cea80089baa001232323333573466e1d400520062321222230040053007357426aae79400c8cccd5cd19b875002480108c848888c008014c024d5d09aab9e500423333573466e1d400d20022321222230010053007357426aae7940148cccd5cd19b875004480008c848888c00c014dd71aba135573ca00c464c6402a66ae7003c06804c0480440404d55cea80089baa001232323333573466e1cd55cea80124000466442466002006004600a6ae854008dd69aba135744a004464c6402266ae7002c05803c4d55cf280089baa0012323333573466e1cd55cea800a400046eb8d5d09aab9e500223263200f33573801202801a26ea80048c8c8c8c8c8cccd5cd19b8750014803084888888800c8cccd5cd19b875002480288488888880108cccd5cd19b875003480208cc8848888888cc004024020dd71aba15005375a6ae84d5d1280291999ab9a3370ea00890031199109111111198010048041bae35742a00e6eb8d5d09aba2500723333573466e1d40152004233221222222233006009008300c35742a0126eb8d5d09aba2500923333573466e1d40192002232122222223007008300d357426aae79402c8cccd5cd19b875007480008c848888888c014020c038d5d09aab9e500c23263201833573802403a02c02a02802602402202026aae7540104d55cf280189aab9e5002135573ca00226ea80048c8c8c8c8cccd5cd19b875001480088ccc888488ccc00401401000cdd69aba15004375a6ae85400cdd69aba135744a00646666ae68cdc3a80124000464244600400660106ae84d55cf280311931900899ab9c00b01600f00e135573aa00626ae8940044d55cf280089baa001232323333573466e1d400520022321223001003375c6ae84d55cf280191999ab9a3370ea004900011909118010019bae357426aae7940108c98c8038cd5ce00400980600589aab9d50011375400224464646666ae68cdc3a800a40084244400246666ae68cdc3a8012400446424446006008600c6ae84d55cf280211999ab9a3370ea00690001091100111931900799ab9c00901400d00c00b135573aa00226ea80048c8cccd5cd19b87500148008801c8cccd5cd19b87500248000801c8c98c802ccd5ce00280800480409aab9d375400292010350543100225335333573466e2000920040030041333573466e2400800401000c400c4880084880048c98c800ccd5ce2481126e6f206f75747075742077697468206e667400008498c8004d5401888cccd55cf80091a803a8029299a991999999aba400125008250082500825008235009375c0040126ae84008854cd4c010d5d1001909a80499a8030010008a8038a80300388910010910911980080200189091180100188910008900088919180080091198019801001000a612dd8799f581c1e579092d8569370cf046b7b7ec3e1cdc8d9d27f237d522304ef00d84a5468726561645f4e4654ff0001" } diff --git a/scripts/validator_unapplied.json b/scripts/validator_unapplied.json new file mode 100644 index 0000000..842ed3b --- /dev/null +++ b/scripts/validator_unapplied.json @@ -0,0 +1,5 @@ +{ + "type": "PlutusScriptV2", + "description": "", + "cborHex": "590f51590f4e01000032323322332232323233223232323232323232323232323232323232323232323232323223232322323223232323223232533533300c33573892011944617461206465636f646564207375636365737366756c6c79003333573466e1cd55cea8052400046603066a034eb8d5d0a8051bad357426ae8940288c98c80b8cd5ce01401981619ab9c4911d52656465656d6572206465636f646564207375636365737366756c6c79003333573466e1d40112006232122223001005375a6ae84d55cf280411999ab9a3370ea00a90021199109111198018030029bae35742a00e6eb4d5d09aba2500723333573466e1d40192002233221222233004006005375c6ae854024dd69aba135744a01246666ae68cdc3a803a4000424444004464c6406266ae700ac0d80bc0b80b40b0cd5ce2492353637269707420636f6e74657874206465636f646564207375636365737366756c6c79003333573466e1cd55cea80124000466442466002006004646464646464646464646464646666ae68cdc39aab9d500c480008cccccccccccc88888888888848cccccccccccc00403403002c02802402001c01801401000c008cd40a00a4d5d0a80619a8140149aba1500b33502802a35742a014666aa058eb940acd5d0a804999aa8163ae502b35742a01066a0500626ae85401cccd540b00c9d69aba150063232323333573466e1cd55cea801240004664424660020060046464646666ae68cdc39aab9d5002480008cc8848cc00400c008cd40f1d69aba15002303d357426ae8940088c98c8110cd5ce01f02482109aab9e5001137540026ae854008c8c8c8cccd5cd19b8735573aa004900011991091980080180119a81e3ad35742a004607a6ae84d5d1280111931902219ab9c03e049042135573ca00226ea8004d5d09aba2500223263204033573807408a07c26aae7940044dd50009aba1500533502875c6ae854010ccd540b00b88004d5d0a801999aa8163ae200135742a00460606ae84d5d1280111931901e19ab9c03604103a135744a00226ae8940044d5d1280089aba25001135744a00226ae8940044d5d1280089aba25001135744a00226ae8940044d55cf280089baa00135742a00460406ae84d5d1280111931901719ab9c02803302c103213263202d3357389210350543500032135573ca00226ea80044d55cea80189aab9e5002135573ca00226ea80044d55cf280089baa00132222323253355335333573466e20cd54028c03048004ccd54c02c48004894cd4ccd54c03848004c8cd404888ccd400c88008008004d40048800448cc004894cd400840a44004098c048008d4d4014880088888888888880104cd40a8008004400540a4d401488008d40148800408c09040904cd5ce2491b4e6f7420656e6f756768206f776e657273207369676e6564207478000231533335004221533553353300333502a00235007220020011026133573892010f4f776e6572206e6f74206164646564000251330240013370066aa018601c240026a00e4400490010812910a99aa99a99801999aa98068900091299aa99a9980a00100208138814099a8160010008800a8159a803910010008813099ab9c491114f776e6572206e6f742072656d6f766564000251330240013370266aa018601c240026a00e44004900108128a99a998009a802910011a802910008812099ab9c490111446174756d20776173206368616e676564000232153355335330023500622002001102513357389201155468726573686f6c64206e6f74207570646174656400024133023001335500b300d1200135006220021024102322533553353335301312001011002355003220021333573466e1c004d5400c88004094090409040944c98c80a0cd5ce24917756e6578706563746564206f757470757420646174756d0002d15333535533553353500122350022222222222223333500d25037250372503723335530191200133501c22533500221003100150372350012253355335333573466e3cd400888008d4010880080d00cc4ccd5cd19b8735002220013500422001034033103313503b0031503a00d21350012235001222235008223500222222222222233355301e120012235002222253353501822350062232335005233500425335333573466e3c00800411010c5400c410c810c8cd4010810c94cd4ccd5cd19b8f002001044043150031043153350032153350022133500223350022335002233500223303300200120462335002204623303300200122204622233500420462225335333573466e1c01800c12412054cd4ccd5cd19b870050020490481333573466e1c01000412412041204120410454cd40048410441044cd4104018014401540f00284c98c8094cd5ce249024c660002a130234988854cd400454cd4c8ccd5cd19b8732323232300100532001355031223350014800088d4008894cd4ccd5cd19b8f00200902e02d130070011300600332001355030223350014800088d4008894cd4ccd5cd19b8f00200702d02c1001130060033500822001350072200248008094090d4008888800c40084c09526221302749888880084c98c8094cd5ce2490f6e6f20696e6c696e6520646174756d0002a2323232153353333333574800846666ae68cdc39aab9d5004480008cccd55cfa8021281791999aab9f500425030233335573e6ae89401494cd54cd4c8ccccccd5d20009281992819918181bac002250332503303435742a00e426a06660320022a06242a66a646666666ae90004940d0940d0940d08d40d4dd68011281a01a9aba15007213503430020011503215031250310320310302502e0292502d2502d2502d2502d02e2100113263202933573892112696e76616c696420646174756d20747970650002e135744a00226aae7940044dd5000909931901319ab9c4910f6e6f20696e6c696e6520646174756d0002b33573892119436f756c646e2774206465636f6465204e4654506172616d73003333573466e1cd55cea801240004664424660020060046eb8d5d0a8011bae357426ae8940088c98c8088cd5ce00e01381009aab9e50011375400222446666aa0046466a01044666a0120060020046a00c00266a00e4446006600400240024466e00005200200148000c8004d5408888448894cd40044008884cc014008ccd54c01c48004014010004c8004d5408488448894cd40044d401800c884ccd4024014c010008ccd54c01c4800401401000448d40048800448d40048800848848cc00400c00888ccd5cd19b8f0020010160152212330010030023200135501b22122253350021533500110172210182215335003101822153353300700400213335300912001007003001101a1232230023758002640026aa036446666aae7c004940688cd4064c010d5d080118019aba200201c232323333573466e1cd55cea8012400046644246600200600460146ae854008c014d5d09aba2500223263201733573802203802a26aae7940044dd50009191919191999ab9a3370e6aae75401120002333322221233330010050040030023232323333573466e1cd55cea8012400046644246600200600460266ae854008cd4034048d5d09aba2500223263201c33573802c04203426aae7940044dd50009aba150043335500875ca00e6ae85400cc8c8c8cccd5cd19b875001480108c84888c008010d5d09aab9e500323333573466e1d4009200223212223001004375c6ae84d55cf280211999ab9a3370ea00690001091100191931900f19ab9c01802301c01b01a135573aa00226ea8004d5d0a80119a804bae357426ae8940088c98c8060cd5ce00900e80b09aba25001135744a00226aae7940044dd5000899aa800bae75a224464460046eac004c8004d5406088c8cccd55cf8011280c119a80b9991091980080180118031aab9d5002300535573ca00460086ae8800c0684d5d080089119191999ab9a3370ea002900011a80c18029aba135573ca00646666ae68cdc3a801240044a030464c6402a66ae7003c06804c0484d55cea80089baa001232323333573466e1d400520062321222230040053007357426aae79400c8cccd5cd19b875002480108c848888c008014c024d5d09aab9e500423333573466e1d400d20022321222230010053007357426aae7940148cccd5cd19b875004480008c848888c00c014dd71aba135573ca00c464c6402a66ae7003c06804c0480440404d55cea80089baa001232323333573466e1cd55cea80124000466442466002006004600a6ae854008dd69aba135744a004464c6402266ae7002c05803c4d55cf280089baa0012323333573466e1cd55cea800a400046eb8d5d09aab9e500223263200f33573801202801a26ea80048c8c8c8c8c8cccd5cd19b8750014803084888888800c8cccd5cd19b875002480288488888880108cccd5cd19b875003480208cc8848888888cc004024020dd71aba15005375a6ae84d5d1280291999ab9a3370ea00890031199109111111198010048041bae35742a00e6eb8d5d09aba2500723333573466e1d40152004233221222222233006009008300c35742a0126eb8d5d09aba2500923333573466e1d40192002232122222223007008300d357426aae79402c8cccd5cd19b875007480008c848888888c014020c038d5d09aab9e500c23263201833573802403a02c02a02802602402202026aae7540104d55cf280189aab9e5002135573ca00226ea80048c8c8c8c8cccd5cd19b875001480088ccc888488ccc00401401000cdd69aba15004375a6ae85400cdd69aba135744a00646666ae68cdc3a80124000464244600400660106ae84d55cf280311931900899ab9c00b01600f00e135573aa00626ae8940044d55cf280089baa001232323333573466e1d400520022321223001003375c6ae84d55cf280191999ab9a3370ea004900011909118010019bae357426aae7940108c98c8038cd5ce00400980600589aab9d50011375400224464646666ae68cdc3a800a40084244400246666ae68cdc3a8012400446424446006008600c6ae84d55cf280211999ab9a3370ea00690001091100111931900799ab9c00901400d00c00b135573aa00226ea80048c8cccd5cd19b87500148008801c8cccd5cd19b87500248000801c8c98c802ccd5ce00280800480409aab9d375400292010350543100225335333573466e2000920040030041333573466e2400800401000c400c4880084880048c98c800ccd5ce2481126e6f206f75747075742077697468206e667400008498c8004d5401888cccd55cf80091a803a8029299a991999999aba400125008250082500825008235009375c0040126ae84008854cd4c010d5d1001909a80499a8030010008a8038a803003889100109109119800802001890911801001889100089000889191800800911980198010010009" +} diff --git a/shell.nix b/shell.nix index dd91294..a70aa62 100644 --- a/shell.nix +++ b/shell.nix @@ -1,4 +1,23 @@ +{ pkgs ? import { } }: let plutus_apps = builtins.getFlake "github:IntersectMBO/plutus-apps?ref=v1.1.0"; + # nix_lib = builtins.getFlake "git+https://github.com/zmrocze/nix-lib"; in -import "${plutus_apps}/shell.nix" +(pkgs.mkShell { + packages = [ pkgs.nodejs_20 ]; + + inputsFrom = [ (import "${plutus_apps}/shell.nix" { }) ]; + + shellHook = '' + echo "node --version: " $(node --version) + echo "npm --version: " $(npm --version) + echo "Now install tsc typescript compiler. I think it's: + echo "$ npm i --save-dev typescript" + echo "$ npm i tsc" + echo "Then in ./tests try:" + echo "$ npm exec -c tsc && node dist/tests/offchain_emulated.js" + echo "to execute the offchain_emulated.js test." + echo "" + echo "Regenerate scripts with `cabal run`" + ''; +}) diff --git a/src/Main.hs b/src/Main.hs new file mode 100644 index 0000000..9b659f3 --- /dev/null +++ b/src/Main.hs @@ -0,0 +1,7 @@ + +module Main where + +import TestSerializer (createTestPlutusScripts) + +main :: IO () +main = createTestPlutusScripts diff --git a/src/NFT.hs b/src/NFT.hs index 0779907..010ce63 100644 --- a/src/NFT.hs +++ b/src/NFT.hs @@ -1,45 +1,55 @@ {-# LANGUAGE DataKinds #-} +{-# LANGUAGE ImportQualifiedPost #-} +{-# LANGUAGE MultiParamTypeClasses #-} {-# LANGUAGE NoImplicitPrelude #-} {-# LANGUAGE OverloadedStrings #-} -{-# LANGUAGE TemplateHaskell #-} -{-# LANGUAGE ImportQualifiedPost #-} {-# LANGUAGE ScopedTypeVariables #-} -{-# LANGUAGE MultiParamTypeClasses #-} +{-# LANGUAGE TemplateHaskell #-} module NFT( hasNFT, nftPolicySerializer, nftPlutusScript, nftCurrencySymbol, + nftUnappliedPlutusScript, NFTParams(..), nftAsset ) where -import Cardano.Api.Shelley (writeFileTextEnvelope, serialiseToCBOR, PlutusScript (..), PlutusScriptV2) -import Codec.Serialise -import Data.ByteString.Lazy qualified as LBS -import Data.ByteString.Short qualified as SBS -import Plutus.Script.Utils.Typed as Scripts -import Plutus.V2.Ledger.Api qualified as V2 -import PlutusTx qualified -import PlutusTx.Prelude -import qualified Data.ByteString.Base16 as B16 -import qualified Data.ByteString as B -import Plutus.V1.Ledger.Value (mpsSymbol, assetClassValueOf, Value, AssetClass(..), flattenValue) -import Plutus.V2.Ledger.Contexts as V2 -import Plutus.V2.Ledger.Api (CurrencySymbol, MintingPolicy, TokenName, mkMintingPolicyScript) -import Prelude (Show (..), String, IO) +import Cardano.Api.Shelley (PlutusScript (..), + PlutusScriptV2, + serialiseToCBOR, + writeFileTextEnvelope) +import Codec.Serialise +import qualified Data.ByteString as B +import qualified Data.ByteString.Base16 as B16 +import qualified Data.ByteString.Lazy as LBS +import qualified Data.ByteString.Short as SBS +import Plutus.Script.Utils.Typed as Scripts import qualified Plutus.Script.Utils.V2.Scripts as PSU.V2 +import Plutus.V1.Ledger.Value (AssetClass (..), Value, + assetClassValueOf, + flattenValue, mpsSymbol) +import Plutus.V2.Ledger.Api (CurrencySymbol, MintingPolicy, + TokenName, fromCompiledCode, + mkMintingPolicyScript) +import qualified Plutus.V2.Ledger.Api as V2 +import Plutus.V2.Ledger.Contexts as V2 +import PlutusTx (CompiledCode, unsafeFromBuiltinData, toBuiltinData) +import qualified PlutusTx +import PlutusTx.Prelude +import Prelude (IO, Show (..), String) +import ScriptUtils (toPlutusScriptV2,tracedUnsafeFrom) --- data type for thread NFT -data NFTParams = NFTParams - { policyId :: CurrencySymbol - , name :: TokenName +-- data type for thread NFT +data NFTParams = NFTParams + { policyId :: CurrencySymbol + , name :: TokenName } deriving Show PlutusTx.makeIsDataIndexed ''NFTParams [('NFTParams, 0)] PlutusTx.makeLift ''NFTParams -{-# INLINEABLE nftAsset #-} +{-# INLINEABLE nftAsset #-} nftAsset :: NFTParams -> AssetClass nftAsset nftparams = AssetClass (policyId nftparams, name nftparams) @@ -48,7 +58,6 @@ nftAsset nftparams = AssetClass (policyId nftparams, name nftparams) hasNFT :: NFTParams -> Value -> Bool hasNFT nftparams value = assetClassValueOf value (nftAsset nftparams) == 1 - -- NFT minting policy {-# INLINABLE mkNFTPolicy #-} mkNFTPolicy :: TxOutRef -> TokenName -> () -> V2.ScriptContext -> Bool @@ -66,27 +75,45 @@ mkNFTPolicy oref tn _ ctx = traceIfFalse "UTxO not consumed" hasUTxO && [(_, tn'', amt)] -> tn'' == tn && amt == 1 _ -> False + -- TxOutRef -> TokenName -> BuiltinData -> BuiltinData -> () +{-# INLINABLE policyUnapplied #-} +policyUnapplied :: CompiledCode (BuiltinData -> BuiltinData -> BuiltinData -> BuiltinData -> ()) +policyUnapplied = + $$(PlutusTx.compile [|| wrap ||]) + where + wrap out tn = Scripts.mkUntypedMintingPolicy $ + mkNFTPolicy (tracedUnsafeFrom "Couldn't deserialize TxOutRef." out) (tracedUnsafeFrom "Couldn't deserialize TokenName." tn) + +-- {-# INLINABLE policyUnapplied #-} +-- policyUnapplied :: CompiledCode (TxOutRef -> TokenName -> BuiltinData -> BuiltinData -> ()) +-- policyUnapplied = +-- $$(PlutusTx.compile [|| wrap ||]) +-- where +-- wrap out tn = Scripts.mkUntypedMintingPolicy $ mkNFTPolicy (unsafeFromBuiltinData out) tn + + policy :: TxOutRef -> TokenName -> MintingPolicy policy outRef tokenName = mkMintingPolicyScript $ - $$(PlutusTx.compile [|| wrap ||]) + policyUnapplied `PlutusTx.applyCode` - PlutusTx.liftCode outRef + PlutusTx.liftCode (toBuiltinData outRef) `PlutusTx.applyCode` - PlutusTx.liftCode tokenName - where - wrap out tn = Scripts.mkUntypedMintingPolicy $ mkNFTPolicy out tn + PlutusTx.liftCode (toBuiltinData tokenName) +currencySymbol :: MintingPolicy -> CurrencySymbol +currencySymbol = mpsSymbol . PSU.V2.mintingPolicyHash nftCurrencySymbol :: TxOutRef -> TokenName -> CurrencySymbol -nftCurrencySymbol outRef tokenName = mpsSymbol $ PSU.V2.mintingPolicyHash (policy outRef tokenName) +nftCurrencySymbol outRef tokenName = currencySymbol (policy outRef tokenName) -- Serialization nftPlutusScript :: TxOutRef -> TokenName -> PlutusScript PlutusScriptV2 -nftPlutusScript outRef tn = - PlutusScriptSerialised $ - SBS.toShort . LBS.toStrict $ - serialise $ - V2.unMintingPolicyScript $ policy outRef tn +nftPlutusScript outRef tn = toPlutusScriptV2 $ + V2.unMintingPolicyScript $ policy outRef tn + +-- Serialization +nftUnappliedPlutusScript :: PlutusScript PlutusScriptV2 +nftUnappliedPlutusScript = toPlutusScriptV2 $ fromCompiledCode policyUnapplied nftPolicySerializer :: TxOutRef -> TokenName -> B.ByteString -nftPolicySerializer outRef tn = B16.encode $ serialiseToCBOR $ nftPlutusScript outRef tn +nftPolicySerializer outRef tn = B16.encode $ serialiseToCBOR $ nftPlutusScript outRef tn diff --git a/src/ScriptUtils.hs b/src/ScriptUtils.hs new file mode 100644 index 0000000..affb2c5 --- /dev/null +++ b/src/ScriptUtils.hs @@ -0,0 +1,57 @@ +{-# LANGUAGE DataKinds #-} +{-# LANGUAGE ImportQualifiedPost #-} +{-# LANGUAGE MultiParamTypeClasses #-} +{-# LANGUAGE NoImplicitPrelude #-} +{-# LANGUAGE OverloadedStrings #-} +{-# LANGUAGE ScopedTypeVariables #-} +{-# LANGUAGE TemplateHaskell #-} + +module ScriptUtils( + toPlutusScriptV2, + currencySymbol, + plutusScriptToByteString, + tracedUnsafeFrom +) where + +import Cardano.Api.Shelley (PlutusScript (..), + PlutusScriptV2, + serialiseToCBOR, + writeFileTextEnvelope) +import Codec.Serialise +import qualified Data.ByteString as B +import qualified Data.ByteString.Base16 as B16 +import qualified Data.ByteString.Lazy as LBS +import qualified Data.ByteString.Short as SBS +import Plutus.Script.Utils.Typed as Scripts +import qualified Plutus.Script.Utils.V2.Scripts as PSU.V2 +import Plutus.V1.Ledger.Value (AssetClass (..), Value, + assetClassValueOf, + flattenValue, mpsSymbol) +import Plutus.V2.Ledger.Api +import Plutus.V2.Ledger.Api (CurrencySymbol, MintingPolicy, + TokenName, fromCompiledCode, + mkMintingPolicyScript) +import qualified Plutus.V2.Ledger.Api as V2 +import Plutus.V2.Ledger.Contexts as V2 +import PlutusTx +import PlutusTx (CompiledCode, UnsafeFromData(unsafeFromBuiltinData)) +import Prelude (IO, Maybe (..), Show (..), + String, return, ($), (.)) +import PlutusTx.Prelude (BuiltinData, BuiltinString, trace) + +currencySymbol :: MintingPolicy -> CurrencySymbol +currencySymbol = mpsSymbol . PSU.V2.mintingPolicyHash + +-- Serialization +toPlutusScriptV2 :: Script -> PlutusScript PlutusScriptV2 +toPlutusScriptV2 script = + PlutusScriptSerialised $ + SBS.toShort . LBS.toStrict $ + serialise $ script + +plutusScriptToByteString :: PlutusScript PlutusScriptV2 -> B.ByteString +plutusScriptToByteString x = B16.encode $ serialiseToCBOR x + +{-# INLINABLE tracedUnsafeFrom #-} +tracedUnsafeFrom :: forall a. UnsafeFromData a => BuiltinString -> BuiltinData -> a +tracedUnsafeFrom label d = trace label $ unsafeFromBuiltinData d \ No newline at end of file diff --git a/src/TestSerializer.hs b/src/TestSerializer.hs index 9fc4bba..388918c 100644 --- a/src/TestSerializer.hs +++ b/src/TestSerializer.hs @@ -1,10 +1,10 @@ {-# LANGUAGE DataKinds #-} +{-# LANGUAGE ImportQualifiedPost #-} +{-# LANGUAGE MultiParamTypeClasses #-} {-# LANGUAGE NoImplicitPrelude #-} {-# LANGUAGE OverloadedStrings #-} -{-# LANGUAGE TemplateHaskell #-} -{-# LANGUAGE ImportQualifiedPost #-} {-# LANGUAGE ScopedTypeVariables #-} -{-# LANGUAGE MultiParamTypeClasses #-} +{-# LANGUAGE TemplateHaskell #-} module TestSerializer( testNftPolicySerializer, @@ -14,15 +14,21 @@ module TestSerializer( testNFTParams ) where -import Prelude (Show (..), String, IO, Maybe(..), return) -import PlutusTx -import Plutus.V2.Ledger.Api -import Cardano.Api.Shelley (writeFileTextEnvelope) -import qualified Data.ByteString as B -import Plutus.V2.Ledger.Api (TokenName) -import NFT (nftPolicySerializer, nftPlutusScript, nftCurrencySymbol, NFTParams(..)) -import Token (tokenPolicySerializer, tokenPlutusScript) -import Validator (validatorScriptSerializer, validatorPlutusScript) +import Cardano.Api.Shelley (writeFileTextEnvelope) +import qualified Data.ByteString as B +import NFT (NFTParams (..), nftCurrencySymbol, + nftPlutusScript, nftPolicySerializer, + nftUnappliedPlutusScript) +import Plutus.V2.Ledger.Api +import Plutus.V2.Ledger.Api (TokenName) +import PlutusTx +import Prelude (IO, Maybe (..), Show (..), String, + return) +import Token (tokenPlutusScript, tokenPolicySerializer, + tokenUnappliedPlutusScript) +import Validator (validatorPlutusScript, + validatorScriptSerializer, + validatorUnappliedPlutusScript) -- FOR TESTING -- @@ -39,8 +45,8 @@ testNFTTokenName = TokenName "Thread_NFT" testNftPolicySerializer :: B.ByteString testNftPolicySerializer = nftPolicySerializer testOref testNFTTokenName -testNFTParams :: NFTParams -testNFTParams = NFTParams +testNFTParams :: NFTParams +testNFTParams = NFTParams { policyId = nftCurrencySymbol testOref testNFTTokenName , name = testNFTTokenName @@ -63,4 +69,7 @@ createTestPlutusScripts = do _ <- writeFileTextEnvelope "./scripts/nft.json" Nothing (nftPlutusScript testOref testNFTTokenName) _ <- writeFileTextEnvelope "./scripts/token.json" Nothing (tokenPlutusScript testNFTParams testTokenName) _ <- writeFileTextEnvelope "./scripts/validator.json" Nothing (validatorPlutusScript testNFTParams) - return() \ No newline at end of file + _ <- writeFileTextEnvelope "./scripts/nft_unapplied.json" Nothing nftUnappliedPlutusScript + _ <- writeFileTextEnvelope "./scripts/token_unapplied.json" Nothing tokenUnappliedPlutusScript + _ <- writeFileTextEnvelope "./scripts/validator_unapplied.json" Nothing validatorUnappliedPlutusScript + return() diff --git a/src/Token.hs b/src/Token.hs index 8b4c627..fd08913 100644 --- a/src/Token.hs +++ b/src/Token.hs @@ -1,40 +1,53 @@ {-# LANGUAGE DataKinds #-} +{-# LANGUAGE ImportQualifiedPost #-} +{-# LANGUAGE MultiParamTypeClasses #-} {-# LANGUAGE NoImplicitPrelude #-} {-# LANGUAGE OverloadedStrings #-} -{-# LANGUAGE TemplateHaskell #-} -{-# LANGUAGE ImportQualifiedPost #-} {-# LANGUAGE ScopedTypeVariables #-} -{-# LANGUAGE MultiParamTypeClasses #-} +{-# LANGUAGE TemplateHaskell #-} module Token( tokenPolicySerializer, - tokenPlutusScript + tokenPlutusScript, + tokenUnappliedPlutusScript ) where -import Plutus.Script.Utils.Typed as Scripts +import Cardano.Api.Shelley (PlutusScript (PlutusScriptSerialised), + PlutusScriptV2, serialiseToCBOR, + writeFileTextEnvelope) +import qualified Codec.Serialise as Serialise +import qualified Data.ByteString as B +import Data.ByteString.Base16 as B16 import qualified Data.ByteString.Lazy as LBS -import Plutus.V2.Ledger.Api (TokenName(..), CurrencySymbol, MintingPolicy, - ScriptContext (scriptContextTxInfo), PubKeyHash(..), - txInfoInputs, - TxInInfo (txInInfoResolved), TxInfo (txInfoMint), - OutputDatum(..), Datum(Datum), mkMintingPolicyScript, +import qualified Data.ByteString.Short as SBS +import NFT (NFTParams (..), hasNFT) +import Plutus.Script.Utils.Typed as Scripts +import Plutus.V1.Ledger.Value (AssetClass (..), Value, + assetClassValueOf, flattenValue) +import Plutus.V2.Ledger.Api (CurrencySymbol, Datum (Datum), + MintingPolicy, OutputDatum (..), + PubKeyHash (..), + ScriptContext (scriptContextTxInfo), + TokenName (..), + TxInInfo (txInInfoResolved), + TxInfo (txInfoMint), + fromCompiledCode, + mkMintingPolicyScript, txInfoInputs, txOutValue, unMintingPolicyScript) import Plutus.V2.Ledger.Contexts (ownCurrencySymbol, txOutDatum) -import Plutus.V1.Ledger.Value (Value, flattenValue, AssetClass(..), assetClassValueOf) -import PlutusTx (fromBuiltinData, makeIsDataIndexed, makeLift, applyCode, compile, liftCode) -import PlutusTx.Prelude (traceIfFalse, traceError, Bool(..), Integer, all, elem, ($), (.), (>), (&&), (==), Maybe(..)) -import qualified Data.ByteString.Short as SBS -import qualified Codec.Serialise as Serialise -import Data.ByteString.Base16 as B16 -import Cardano.Api.Shelley (writeFileTextEnvelope, PlutusScript (PlutusScriptSerialised), - PlutusScriptV2,serialiseToCBOR) -import qualified Data.ByteString as B -import NFT (hasNFT, NFTParams(..)) -import Prelude (Show (..), String, IO, return) +import PlutusTx (CompiledCode, applyCode, compile, + fromBuiltinData, liftCode, + makeIsDataIndexed, makeLift, unsafeFromBuiltinData, toBuiltinData) +import PlutusTx.Prelude +import PlutusTx.Prelude (Bool (..), Integer, Maybe (..), all, + elem, traceError, traceIfFalse, ($), + (&&), (.), (==), (>)) +import Prelude (IO, Show (..), String, return) +import ScriptUtils (toPlutusScriptV2, tracedUnsafeFrom) -- Custom data type to hold the owners' public keys data ValidatorDatum = ValidatorDatum - { owners :: [PubKeyHash] + { owners :: [PubKeyHash] , minThreshold :: Integer } @@ -42,10 +55,10 @@ PlutusTx.makeIsDataIndexed ''ValidatorDatum [('ValidatorDatum, 0)] PlutusTx.makeLift ''ValidatorDatum --- Token policy that mints tokens only if input with specific NFT is consumed +-- Token policy that mints tokens only if input with specific NFT is consumed {-# INLINABLE mkTokenPolicy #-} mkTokenPolicy :: NFTParams -> TokenName -> () -> ScriptContext -> Bool -mkTokenPolicy nftparams tokenName _ ctx = +mkTokenPolicy nftparams tokenName _ ctx = let info :: TxInfo info = scriptContextTxInfo ctx @@ -61,38 +74,47 @@ mkTokenPolicy nftparams tokenName _ ctx = -- Check type of transaction: minting or burning isMinting :: Bool isMinting = mintedValue > 0 - - -- Check that Validator's output with NFT will be spent + + -- Check that Validator's output with NFT will be spent scriptValidationIsEnsured :: Bool - scriptValidationIsEnsured = - case [ o + scriptValidationIsEnsured = + case [ o | i <- txInfoInputs info , let o = txInInfoResolved i - , hasNFT nftparams $ txOutValue o + , hasNFT nftparams $ txOutValue o ] of [_] -> True - _ -> traceError "no NFT in input" + _ -> traceError "no NFT in input" in if isMinting then scriptValidationIsEnsured else True +-- NFTParams -> TokenName -> UntypedMintingPolicy +{-# INLINABLE policyUnapplied #-} +policyUnapplied :: CompiledCode (BuiltinData -> BuiltinData -> UntypedMintingPolicy) +policyUnapplied = + $$(PlutusTx.compile [|| wrap ||]) + where + wrap nparams tn = Scripts.mkUntypedMintingPolicy $ + mkTokenPolicy (tracedUnsafeFrom "Couldn't decode NFTParams" nparams) (tracedUnsafeFrom "Couldn't decode TokenName" tn) + policy :: NFTParams -> TokenName -> MintingPolicy policy nftparams tokenName = mkMintingPolicyScript $ - $$(PlutusTx.compile [|| wrap ||]) + policyUnapplied `PlutusTx.applyCode` - PlutusTx.liftCode nftparams + PlutusTx.liftCode (toBuiltinData nftparams) `PlutusTx.applyCode` - PlutusTx.liftCode tokenName - where - wrap nparams tn = Scripts.mkUntypedMintingPolicy $ mkTokenPolicy nparams tn + PlutusTx.liftCode (toBuiltinData tokenName) -- Serialization tokenPlutusScript :: NFTParams -> TokenName -> PlutusScript PlutusScriptV2 -tokenPlutusScript nftparams tokenName = - PlutusScriptSerialised $ - SBS.toShort . LBS.toStrict $ - Serialise.serialise $ +tokenPlutusScript nftparams tokenName = toPlutusScriptV2 $ unMintingPolicyScript $ policy nftparams tokenName +-- Serialization +tokenUnappliedPlutusScript :: PlutusScript PlutusScriptV2 +tokenUnappliedPlutusScript = toPlutusScriptV2 $ + fromCompiledCode $ policyUnapplied + tokenPolicySerializer :: NFTParams -> TokenName -> B.ByteString tokenPolicySerializer nftparams tokenName = B16.encode $ serialiseToCBOR $ tokenPlutusScript nftparams tokenName diff --git a/src/Validator.hs b/src/Validator.hs index 63bba7c..511e672 100644 --- a/src/Validator.hs +++ b/src/Validator.hs @@ -1,54 +1,61 @@ {-# LANGUAGE DataKinds #-} +{-# LANGUAGE DeriveAnyClass #-} +{-# LANGUAGE DerivingStrategies #-} +{-# LANGUAGE ImportQualifiedPost #-} +{-# LANGUAGE MultiParamTypeClasses #-} {-# LANGUAGE NoImplicitPrelude #-} -{-# LANGUAGE TemplateHaskell #-} +{-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE ScopedTypeVariables #-} +{-# LANGUAGE TemplateHaskell #-} {-# LANGUAGE TypeApplications #-} -{-# LANGUAGE OverloadedStrings #-} -{-# LANGUAGE ImportQualifiedPost #-} -{-# LANGUAGE MultiParamTypeClasses #-} -{-# LANGUAGE DerivingStrategies #-} -{-# LANGUAGE DeriveAnyClass #-} module Validator( validatorScriptSerializer, - validatorPlutusScript + validatorPlutusScript, + validatorUnappliedPlutusScript ) where -import Plutus.V2.Ledger.Api -import Plutus.V2.Ledger.Contexts as PV2 -import PlutusTx -import PlutusTx.Prelude as PP -import Plutus.V1.Ledger.Value as Value -import Plutus.V2.Ledger.Api qualified as V2 -import Plutus.Script.Utils.Typed as Scripts -import Data.ByteString.Lazy qualified as LBS -import Data.ByteString.Short qualified as SBS -import Data.ByteString.Base16 as B16 -import Data.ByteString as B -import Codec.Serialise as Serialise -import Prelude (Eq, Show, IO, show, String) -import Cardano.Api.Shelley (displayError, writeFileTextEnvelope, PlutusScript (PlutusScriptSerialised), - PlutusScriptV2, serialiseToCBOR) -import NFT (hasNFT, NFTParams(..)) - +import Cardano.Api.Shelley (PlutusScript (PlutusScriptSerialised), + PlutusScriptV2, displayError, + serialiseToCBOR, + writeFileTextEnvelope) +import Codec.Serialise as Serialise +import Data.ByteString as B +import Data.ByteString.Base16 as B16 +import qualified Data.ByteString.Lazy as LBS +import qualified Data.ByteString.Short as SBS +import NFT (NFTParams (..), hasNFT) +import Plutus.Script.Utils.Typed as Scripts +import Plutus.V1.Ledger.Value as Value +import Plutus.V2.Ledger.Api +import Plutus.V2.Ledger.Api (CurrencySymbol, MintingPolicy, + TokenName, fromCompiledCode, + mkMintingPolicyScript) +import qualified Plutus.V2.Ledger.Api as V2 +import Plutus.V2.Ledger.Contexts as PV2 +import PlutusTx (unsafeFromBuiltinData, toBuiltinData) +import PlutusTx +import PlutusTx.Prelude as PP +import Prelude (Eq, IO, Show, String, show) +import ScriptUtils (toPlutusScriptV2, tracedUnsafeFrom) -- Datum type data MultiSigDatum = MultiSigDatum - { owners :: [PubKeyHash] - , minSigs :: Integer + { owners :: [PubKeyHash] + , minSigs :: Integer } deriving (Show) PlutusTx.makeIsDataIndexed ''MultiSigDatum [('MultiSigDatum, 0)] PlutusTx.makeLift ''MultiSigDatum -- Redeemer type -data MultisigRedeemer = +data MultisigRedeemer = TokenMint - | AddOwner PubKeyHash Integer + | AddOwner PubKeyHash Integer | RemoveOwner PubKeyHash Integer | UpdateThreshold Integer deriving (Show) - + PlutusTx.makeIsDataIndexed ''MultisigRedeemer [ ('TokenMint, 0) , ('AddOwner, 1) , ('RemoveOwner, 2) @@ -59,22 +66,22 @@ PlutusTx.makeLift ''MultisigRedeemer {-# INLINABLE upgradeableOwnersValidator #-} upgradeableOwnersValidator :: NFTParams -> MultiSigDatum -> MultisigRedeemer -> ScriptContext -> Bool -upgradeableOwnersValidator nftparams datum redeemer ctx = +upgradeableOwnersValidator nftparams datum redeemer ctx = traceIfFalse "Not enough owners signed tx" checkMinSigs && case redeemer of - TokenMint -> traceIfFalse "Datum was changed" + TokenMint -> traceIfFalse "Datum was changed" (checkConsistencyOfOutputDatum (owners datum) (minSigs datum)) - AddOwner newOwner newThreshold -> traceIfFalse "Owner not added" + AddOwner newOwner newThreshold -> traceIfFalse "Owner not added" (checkConsistencyOfOutputDatum (newOwner : owners datum) newThreshold) && (checkThresholdInterval newThreshold (PP.length (owners datum) PP.+ 1)) - RemoveOwner oldOwner newThreshold -> traceIfFalse "Owner not removed" + RemoveOwner oldOwner newThreshold -> traceIfFalse "Owner not removed" (checkConsistencyOfOutputDatum (PP.filter (/= oldOwner) (owners datum)) newThreshold) && (checkThresholdInterval newThreshold (PP.length (owners datum) PP.- 1)) - UpdateThreshold newThreshold -> traceIfFalse "Threshold not updated" + UpdateThreshold newThreshold -> traceIfFalse "Threshold not updated" (checkConsistencyOfOutputDatum (owners datum) newThreshold) && (checkThresholdInterval newThreshold (PP.length (owners datum))) - - where + + where info :: TxInfo info = scriptContextTxInfo ctx @@ -90,28 +97,34 @@ upgradeableOwnersValidator nftparams datum redeemer ctx = getContinuingOutputDatum = case txOutDatum getOutputWithNFT of OutputDatum d -> case fromBuiltinData (getDatum d) of Nothing -> traceError "invalid datum type" - Just multiSigDatum -> multiSigDatum + Just multiSigDatum -> multiSigDatum _ -> traceError "no inline datum" checkConsistencyOfOutputDatum :: [PubKeyHash] -> Integer -> Bool - checkConsistencyOfOutputDatum expectedOwners expectedThreshold = - let + checkConsistencyOfOutputDatum expectedOwners expectedThreshold = + let outputDatum = getContinuingOutputDatum - in + in if expectedOwners == (owners outputDatum) && expectedThreshold == (minSigs outputDatum) then True else traceError "unexpected output datum" checkThresholdInterval :: Integer -> Integer -> Bool checkThresholdInterval expectedThreshold maxThreshold = expectedThreshold >= 2 && expectedThreshold <= maxThreshold -validator :: NFTParams -> V2.Validator -validator nftparams = V2.mkValidatorScript $ +-- NFTParams -> UntypedValidator +{-# INLINABLE validatorUnapplied #-} +validatorUnapplied :: CompiledCode (BuiltinData -> UntypedValidator) +validatorUnapplied = $$(PlutusTx.compile [|| wrap ||]) - `PlutusTx.applyCode` - PlutusTx.liftCode nftparams where - wrap nparams = Scripts.mkUntypedValidator $ upgradeableOwnersValidator nparams + wrap nparams = Scripts.mkUntypedValidator $ + upgradeableOwnersValidator (tracedUnsafeFrom "Couldn't decode NFTParams" nparams) +validator :: NFTParams -> V2.Validator +validator nftparams = V2.mkValidatorScript $ + validatorUnapplied + `PlutusTx.applyCode` + PlutusTx.liftCode (toBuiltinData nftparams) -- Serialization validatorPlutusScript :: NFTParams -> PlutusScript PlutusScriptV2 @@ -121,6 +134,9 @@ validatorPlutusScript nftparams = Serialise.serialise $ validator nftparams +validatorUnappliedPlutusScript :: PlutusScript PlutusScriptV2 +validatorUnappliedPlutusScript = toPlutusScriptV2 $ fromCompiledCode validatorUnapplied + validatorScriptSerializer :: NFTParams -> B.ByteString validatorScriptSerializer nftparams = B16.encode $ serialiseToCBOR $ validatorPlutusScript nftparams diff --git a/tests/offchain.ts b/tests/offchain.ts index c77aa07..736d699 100644 --- a/tests/offchain.ts +++ b/tests/offchain.ts @@ -1,33 +1,31 @@ import { Address, - Blockfrost, C, Constr, Data, + Emulator, Lucid, + MintingPolicy, + OutRef, PolicyId, Redeemer, + Script, ScriptType, SpendingValidator, TxHash, Unit, + applyParamsToScript, fromText, - getAddressDetails + getAddressDetails } from "lucid-cardano"; -import { Buffer } from 'buffer' - - const { PrivateKey } = C; -import { - blockfrostKey, - owner1PrivateKey, - owner2PrivateKey, - owner3PrivateKey -} from "./secret.js" import nftPlutusScript from "../scripts/nft.json" assert { type: "json" } +import nftUnappliedPlutusScript from "../scripts/nft_unapplied.json" assert { type: "json" } import tokenPlutusScript from "../scripts/token.json" assert { type: "json" } +import tokenUnappliedPlutusScript from "../scripts/token_unapplied.json" assert { type: "json" } import ValidatorPlutusScript from "../scripts/validator.json" assert { type: "json" } +import ValidatorUnappliedPlutusScript from "../scripts/validator_unapplied.json" assert { type: "json" } export type oref = { txHash: string, @@ -44,39 +42,59 @@ function delay(ms: number) { return new Promise( resolve => setTimeout(resolve, ms) ); } +// used for utxo for oneshot minting policy +const mp0Key = PrivateKey.generate_ed25519() +// owner keys +const owner1Key = PrivateKey.generate_ed25519() +const owner2Key = PrivateKey.generate_ed25519() +const owner3Key = PrivateKey.generate_ed25519() -// set blockfrost endpoint -const lucid = await Lucid.new( - new Blockfrost( - "https://cardano-preprod.blockfrost.io/api/v0", - blockfrostKey - ), - "Preprod" -); - -const owner1Key = PrivateKey.from_normal_bytes( - Buffer.from(owner1PrivateKey, "hex") -) -const owner2Key = PrivateKey.from_normal_bytes( - Buffer.from(owner2PrivateKey, "hex") -) -const owner3Key = PrivateKey.from_normal_bytes( - Buffer.from(owner3PrivateKey, "hex") -) - +const mp0KeyBech32 = mp0Key.to_bech32() const owner1KeyBech32 = owner1Key.to_bech32() const owner2KeyBech32 = owner2Key.to_bech32() const owner3KeyBech32 = owner3Key.to_bech32() -const addr2: Address = await (lucid.selectWalletFromPrivateKey(owner2KeyBech32)).wallet.address() -const addr3: Address = await (lucid.selectWalletFromPrivateKey(owner3KeyBech32)).wallet.address() -console.log("addr3: ", addr3) -const addr1: Address = await (lucid.selectWalletFromPrivateKey(owner1KeyBech32)).wallet.address() +const addr0 = await (await Lucid.new(undefined, "Custom")) + .selectWalletFromPrivateKey(mp0KeyBech32).wallet.address(); +const addr1 = await (await Lucid.new(undefined, "Custom")) + .selectWalletFromPrivateKey(owner1KeyBech32).wallet.address(); +const addr2 = await (await Lucid.new(undefined, "Custom")) + .selectWalletFromPrivateKey(owner2KeyBech32).wallet.address(); +const addr3 = await (await Lucid.new(undefined, "Custom")) + .selectWalletFromPrivateKey(owner3KeyBech32).wallet.address(); const pkh1: string = getAddressDetails(addr1).paymentCredential?.hash || ""; const pkh2: string = getAddressDetails(addr2).paymentCredential?.hash || ""; const pkh3: string = getAddressDetails(addr3).paymentCredential?.hash || ""; +const emulator = new Emulator([ + { + address: addr0, + assets: { lovelace: 3_000_000_000n }, + }, + { + address: addr0, + assets: { lovelace: 5_000_000n }, // collateral + }, + { + address: addr1, + assets: { lovelace: 3_000_000_000n }, + }, + { + address: addr1, + assets: { lovelace: 5_000_000n }, // collateral + }, + { + address: addr2, + assets: { lovelace: 3_000_000_000n }, + }, + { + address: addr2, + assets: { lovelace: 5_000_000n }, // collateral + }, +]); + +const lucid = await Lucid.new(emulator); function completeScript(policy: string) : { type: ScriptType; script: string; } { return { @@ -85,13 +103,64 @@ function completeScript(policy: string) : { type: ScriptType; script: string; } }; }; +// TODO: use +let outRefToData = (outRef: OutRef) => Data.to( + new Constr(0, [ + new Constr(0, [outRef.txHash]), + BigInt(outRef.outputIndex) + ]) + ); + +const NFT_TOKEN_NAME = "Thread_NFT"; + +// TODO: use +const nftParamsToData = (policy : Script) : Data => { + // console.log("nft hash?: ", lucid.utils.mintingPolicyToId(policy)); + return Data.to( new Constr(0, [ + lucid.utils.mintingPolicyToId(policy), // todo: check if its already hex encoded with above print!!! + fromText(NFT_TOKEN_NAME) + ])) +} + +const TokenNameSchema = Data.Bytes(); + +type TokenNameData = Data.Static; +const TokenNameData = TokenNameSchema as unknown as TokenNameData; + +// TODO: use +const applyNftPolicy = (outRef : OutRef) => applyParamsToScript( + nftUnappliedPlutusScript["cborHex"], + [ + outRefToData(outRef), + // Data.to( + fromText(NFT_TOKEN_NAME), + // TokenNameData, + // ) + ], + ) + +// TODO: use +const applyTokenPolicy = (nftParams : Data, token_name: string) => applyParamsToScript( + tokenUnappliedPlutusScript["cborHex"], + [ nftParams, + Data.to( fromText(token_name) ) + ], +) + +// TODO: use +const applyValidator = (nftParams : Data) => applyParamsToScript( + nftUnappliedPlutusScript["cborHex"], + [ nftParams + ], +) /* NFT */ const nftPolicy = nftPlutusScript["cborHex"] const nftPolicyId: PolicyId = lucid.utils.mintingPolicyToId(completeScript(nftPolicy)); const nftUnit: Unit = nftPolicyId + fromText("Thread_NFT"); const emptyRedeemer = Data.void(); - +// this changes to () but encoded as PlutusData, that ends up being `Constr 0 []` +const plutusDataUnit = Data.to(new Constr(0, [])) /* Token */ const tokenPolicy = tokenPlutusScript["cborHex"] @@ -119,32 +188,55 @@ const isTxValidated = async(txHash: string) => { throw ("Transaction wasn't validated") } +type ProtocolScripts = { + nftPolicy: MintingPolicy, + tokenPolicy: MintingPolicy, + validatorScript: SpendingValidator +}; + // Mint thread NFT for `upgradeableOwnersValidator` -export async function mintNFT(): Promise { +export async function mintNFT(): Promise<{ txHash: TxHash, scripts : ProtocolScripts }> { + // TODO: now this function should probably return already applied scripts const utxos = await lucid.wallet.getUtxos() - const utxo = utxos.find( - (utxo) => - utxo.txHash === threadOref.txHash && utxo.outputIndex === threadOref.outputIndex - ) + const utxo = utxos[0]; if (!utxo) throw new Error("Utxo is required to mint NFT") + const nftPolicy = completeScript(applyNftPolicy( { + txHash: utxo.txHash, + outputIndex: utxo.outputIndex, + })); + + // const nftParams = nftParamsToData(nftPolicy); + + // const tokenPolicy = completeScript(applyTokenPolicy(nftParams, "TToken" )); + + // const validatorScript: SpendingValidator = completeScript(applyValidator( nftParams )); + + const nftPolicyId: PolicyId = lucid.utils.mintingPolicyToId(nftPolicy); + const nftUnit: Unit = nftPolicyId + fromText("Thread_NFT"); + + const validatorAddress: Address = lucid.utils.validatorToAddress(validatorScript) + const tx = await lucid .newTx() .collectFrom([utxo]) - .mintAssets({ [nftUnit]: 1n }, emptyRedeemer) - .validTo(Date.now() + 100000) + .mintAssets({ [nftUnit]: 1n }, plutusDataUnit) + .validTo(emulator.now() + 100000) .payToContract( - validatorAddress, + validatorAddress, {inline: Data.to(testDatum, MultiSigDatum)}, {lovelace: 2000000n, [nftUnit]: 1n} ) - .attachMintingPolicy(completeScript(nftPolicy)) + .attachMintingPolicy(nftPolicy) .complete(); - + + console.log('built'); + const signedTx = await tx.sign().complete(); - + const txHash = await signedTx.submit(); - return txHash; + // return { txHash , scripts : { nftPolicy, tokenPolicy, validatorScript } }; + return { txHash , scripts : { nftPolicy, tokenPolicy : nftPolicy, validatorScript : nftPolicy } }; } /* Datum Scheme */ @@ -178,7 +270,7 @@ export async function mintTokenWithOwners12(token: Unit, amount: bigint) { .payToContract(validatorAddress, {inline: Data.to(testDatum, MultiSigDatum)}, {lovelace: 2000000n, [nftUnit]: 1n}) - .validTo(Date.now() + 100000) + .validTo(emulator.now() + 100000) .attachMintingPolicy(tokenScript) .attachSpendingValidator(validatorScript) .complete(); @@ -236,7 +328,7 @@ export async function notOwnerMinting(token: Unit, amount: bigint) { .payToContract(validatorAddress, {inline: Data.to(testDatum, MultiSigDatum)}, {lovelace: 2000000n, [nftUnit]: 1n}) - .validTo(Date.now() + 100000) + .validTo(emulator.now() + 100000) .attachMintingPolicy(tokenScript) .attachSpendingValidator(validatorScript) .complete(); @@ -270,7 +362,7 @@ export async function mintTokenWithOwners23(token: Unit, amount: bigint) { .payToContract(validatorAddress, {inline: Data.to(testDatum, MultiSigDatum)}, {lovelace: 2000000n, [nftUnit]: 1n}) - .validTo(Date.now() + 100000) + .validTo(emulator.now() + 100000) .attachMintingPolicy(tokenScript) .attachSpendingValidator(validatorScript) .complete(); @@ -318,7 +410,7 @@ export async function addOwner3WithOwners12() { .payToContract(validatorAddress, {inline: Data.to(testDatum, MultiSigDatum)}, {lovelace: 2000000n, [nftUnit]: 1n}) - .validTo(Date.now() + 100000) + .validTo(emulator.now() + 100000) .attachSpendingValidator(validatorScript) .complete(); @@ -347,7 +439,7 @@ export async function addOwner1WithOwners23(threshold: number) { .payToContract(validatorAddress, {inline: Data.to(testDatum, MultiSigDatum)}, {lovelace: 2000000n, [nftUnit]: 1n}) - .validTo(Date.now() + 100000) + .validTo(emulator.now() + 100000) .attachSpendingValidator(validatorScript) .complete(); @@ -377,7 +469,7 @@ export async function mintTokenWithThreeOwners(token: Unit, amount: bigint) { {inline: Data.to(testDatum, MultiSigDatum)}, {lovelace: 2000000n, [nftUnit]: 1n}) - .validTo(Date.now() + 100000) + .validTo(emulator.now() + 100000) .attachMintingPolicy(tokenScript) .attachSpendingValidator(validatorScript) .complete(); @@ -409,7 +501,7 @@ export async function removeFirstOwnerWithThreeOwners(threshold: number) { .payToContract(validatorAddress, {inline: Data.to(testDatum, MultiSigDatum)}, {lovelace: 2000000n, [nftUnit]: 1n}) - .validTo(Date.now() + 100000) + .validTo(emulator.now() + 100000) .attachSpendingValidator(validatorScript) .complete(); @@ -441,7 +533,7 @@ export async function updateThresholdWithOwners23(newThreshold: number) { .payToContract(validatorAddress, {inline: Data.to(testDatum, MultiSigDatum)}, {lovelace: 2000000n, [nftUnit]: 1n}) - .validTo(Date.now() + 100000) + .validTo(emulator.now() + 100000) .attachSpendingValidator(validatorScript) .complete(); @@ -472,7 +564,7 @@ export async function setToInitState(threshold: number) { .payToContract(validatorAddress, {inline: Data.to(testDatum, MultiSigDatum)}, {lovelace: 2000000n, [nftUnit]: 1n}) - .validTo(Date.now() + 100000) + .validTo(emulator.now() + 100000) .attachSpendingValidator(validatorScript) .complete(); @@ -493,8 +585,15 @@ const secondsToWait: number = 1000*40 const main = async() => { try { - //console.log("mint NFT: ", await mintNFT(testDatum)) - //delay(secondsToWait) + // this sets the wallet owner to the owner owning UTXO for one shot mint + // NOTE: at certain point only single key is being used for wallet + lucid.selectWalletFromPrivateKey(mp0KeyBech32) + + await delay(1000*5) + console.log("mint NFT: ", await mintNFT()) + await delay(secondsToWait) + + // todo: need to use the applied scripts below console.log( "\n***** Testing: MINTING *****\n", diff --git a/tests/offchain_preprod.ts b/tests/offchain_preprod.ts new file mode 100644 index 0000000..c77aa07 --- /dev/null +++ b/tests/offchain_preprod.ts @@ -0,0 +1,565 @@ +import { + Address, + Blockfrost, + C, + Constr, + Data, + Lucid, + PolicyId, + Redeemer, + ScriptType, + SpendingValidator, + TxHash, + Unit, + fromText, + getAddressDetails +} from "lucid-cardano"; + +import { Buffer } from 'buffer' + + +const { PrivateKey } = C; +import { + blockfrostKey, + owner1PrivateKey, + owner2PrivateKey, + owner3PrivateKey +} from "./secret.js" +import nftPlutusScript from "../scripts/nft.json" assert { type: "json" } +import tokenPlutusScript from "../scripts/token.json" assert { type: "json" } +import ValidatorPlutusScript from "../scripts/validator.json" assert { type: "json" } + +export type oref = { + txHash: string, + outputIndex: number +} + +export const threadOref: oref = { + txHash: "f160ee01ff83321e37289837d6998273c4629667fb8f85b1a938fab81e01806b", + outputIndex: 1 +} + +// due to delays in blockchain +function delay(ms: number) { + return new Promise( resolve => setTimeout(resolve, ms) ); +} + + +// set blockfrost endpoint +const lucid = await Lucid.new( + new Blockfrost( + "https://cardano-preprod.blockfrost.io/api/v0", + blockfrostKey + ), + "Preprod" +); + +const owner1Key = PrivateKey.from_normal_bytes( + Buffer.from(owner1PrivateKey, "hex") +) +const owner2Key = PrivateKey.from_normal_bytes( + Buffer.from(owner2PrivateKey, "hex") +) +const owner3Key = PrivateKey.from_normal_bytes( + Buffer.from(owner3PrivateKey, "hex") +) + +const owner1KeyBech32 = owner1Key.to_bech32() +const owner2KeyBech32 = owner2Key.to_bech32() +const owner3KeyBech32 = owner3Key.to_bech32() + +const addr2: Address = await (lucid.selectWalletFromPrivateKey(owner2KeyBech32)).wallet.address() +const addr3: Address = await (lucid.selectWalletFromPrivateKey(owner3KeyBech32)).wallet.address() +console.log("addr3: ", addr3) +const addr1: Address = await (lucid.selectWalletFromPrivateKey(owner1KeyBech32)).wallet.address() + +const pkh1: string = getAddressDetails(addr1).paymentCredential?.hash || ""; +const pkh2: string = getAddressDetails(addr2).paymentCredential?.hash || ""; +const pkh3: string = getAddressDetails(addr3).paymentCredential?.hash || ""; + + +function completeScript(policy: string) : { type: ScriptType; script: string; } { + return { + type: "PlutusV2", + script: policy + }; +}; + + +/* NFT */ +const nftPolicy = nftPlutusScript["cborHex"] +const nftPolicyId: PolicyId = lucid.utils.mintingPolicyToId(completeScript(nftPolicy)); +const nftUnit: Unit = nftPolicyId + fromText("Thread_NFT"); +const emptyRedeemer = Data.void(); + + +/* Token */ +const tokenPolicy = tokenPlutusScript["cborHex"] +const tokenScript: SpendingValidator = completeScript(tokenPolicy) +const tokenPolicyId: PolicyId = lucid.utils.mintingPolicyToId(tokenScript); +const tokenUnit: Unit = tokenPolicyId + fromText("TToken"); + + +/* Validator */ +const validator = ValidatorPlutusScript["cborHex"] +const validatorScript: SpendingValidator = completeScript(validator) +const validatorAddress: Address = lucid.utils.validatorToAddress(validatorScript) +const redemeerTokenMint = Data.to(new Constr(0, [])) as Redeemer +const redemeerAddOwner = (pkh: string, threshold: number) => Data.to(new Constr(1, [String(pkh), BigInt(threshold)])) as Redeemer +const redemeerRemoveOwner = (pkh: string, threshold: number) => Data.to(new Constr(2, [String(pkh), BigInt(threshold)])) as Redeemer +const redemeerUpdateThreshold = (threshold: number) => Data.to(new Constr(3, [BigInt(threshold)])) as Redeemer + + +const isTxValidated = async(txHash: string) => { + if(!txHash) + throw ("No transaction hash provided") + if(!(typeof 'TxHash' == typeof txHash)) + throw("Unappropriate type of transaction hash") + if(!await lucid.awaitTx(txHash)) + throw ("Transaction wasn't validated") +} + +// Mint thread NFT for `upgradeableOwnersValidator` +export async function mintNFT(): Promise { + const utxos = await lucid.wallet.getUtxos() + const utxo = utxos.find( + (utxo) => + utxo.txHash === threadOref.txHash && utxo.outputIndex === threadOref.outputIndex + ) + if (!utxo) throw new Error("Utxo is required to mint NFT") + + const tx = await lucid + .newTx() + .collectFrom([utxo]) + .mintAssets({ [nftUnit]: 1n }, emptyRedeemer) + .validTo(Date.now() + 100000) + .payToContract( + validatorAddress, + {inline: Data.to(testDatum, MultiSigDatum)}, + {lovelace: 2000000n, [nftUnit]: 1n} + ) + .attachMintingPolicy(completeScript(nftPolicy)) + .complete(); + + const signedTx = await tx.sign().complete(); + + const txHash = await signedTx.submit(); + return txHash; +} + +/* Datum Scheme */ +const MultiSigDatumSchema = Data.Object({ + owners: Data.Array(Data.Bytes()), + minSigs: Data.Integer() + }); + +type MultiSigDatum = Data.Static; +const MultiSigDatum = MultiSigDatumSchema as unknown as MultiSigDatum; + +// Global variable, init state +let testDatum: MultiSigDatum = { + owners: [String(pkh1), String(pkh2)], + minSigs: 2n +}; + +export async function mintTokenWithOwners12(token: Unit, amount: bigint) { + console.log(" - mint with owner 1 and owner 2"); + console.log("validator address: ", validatorAddress) + const utxWithThread = (await lucid.utxosAtWithUnit(validatorAddress, nftUnit))[0] + + const tx = await lucid + .newTx() + .mintAssets({ [token]: amount }, emptyRedeemer) + .collectFrom([utxWithThread], redemeerTokenMint) + + .addSignerKey(pkh1) + .addSignerKey(pkh2) + + .payToContract(validatorAddress, + {inline: Data.to(testDatum, MultiSigDatum)}, + {lovelace: 2000000n, [nftUnit]: 1n}) + .validTo(Date.now() + 100000) + .attachMintingPolicy(tokenScript) + .attachSpendingValidator(validatorScript) + .complete(); + + const signedTx = await tx.sign() + .signWithPrivateKey(owner2KeyBech32) + .complete(); + const txHash = await signedTx.submit(); + + await isTxValidated(txHash) + + console.log("✅ txHash from `mintTokenWithOwners12`: " + txHash + "\n"); +} + + +// helper +export async function transfer(datum: MultiSigDatum, to: Address, unit: Unit, amount: bigint) { + console.log(" - transfer"); + + const tx = await lucid + .newTx() + .payToContract( + to, + {inline: Data.to(datum, MultiSigDatum)}, + {lovelace: 2000000n, [unit]: amount} + ) + .complete(); + + const signedTx = await tx.sign().complete(); + const txHash = await signedTx.submit(); + + await isTxValidated(txHash) + + console.log("txHash from `transfer`: " + txHash + "\n"); +} + + +// 3d party can submit minting transaction to network and receive tokens +// but signatures from owner1 and owner2 are required +export async function notOwnerMinting(token: Unit, amount: bigint) { + console.log("- mint with 2 owners, tx is submitted by another address"); + + // not owner of token while running this function + lucid.selectWalletFromPrivateKey(owner3KeyBech32) + + const utxWithThread = (await lucid.utxosAtWithUnit(validatorAddress, nftUnit))[0] + + const tx = await lucid + .newTx() + .mintAssets({ [token]: amount }, emptyRedeemer) + .collectFrom([utxWithThread], redemeerTokenMint) + .addSignerKey(pkh3) + .addSignerKey(pkh1) + .addSignerKey(pkh2) + .payToContract(validatorAddress, + {inline: Data.to(testDatum, MultiSigDatum)}, + {lovelace: 2000000n, [nftUnit]: 1n}) + .validTo(Date.now() + 100000) + .attachMintingPolicy(tokenScript) + .attachSpendingValidator(validatorScript) + .complete(); + + const signedTx = await tx.sign() + .signWithPrivateKey(owner1KeyBech32) + .signWithPrivateKey(owner2KeyBech32) + .complete(); + const txHash = await signedTx.submit(); + + await isTxValidated(txHash) + + lucid.selectWalletFromPrivateKey(owner1KeyBech32) + + console.log("✅ txHash from `notOwnerMinting`: " + txHash + "\n"); +} + +export async function mintTokenWithOwners23(token: Unit, amount: bigint) { + console.log(" - mint with owner 3 and owner 2"); + + const utxWithThread = (await lucid.utxosAtWithUnit(validatorAddress, nftUnit))[0] + + const tx = await lucid + .newTx() + .mintAssets({ [token]: amount }, emptyRedeemer) + .collectFrom([utxWithThread], redemeerTokenMint) + + .addSignerKey(pkh2) + .addSignerKey(pkh3) + + .payToContract(validatorAddress, + {inline: Data.to(testDatum, MultiSigDatum)}, + {lovelace: 2000000n, [nftUnit]: 1n}) + .validTo(Date.now() + 100000) + .attachMintingPolicy(tokenScript) + .attachSpendingValidator(validatorScript) + .complete(); + + const signedTx = await tx.sign() + .signWithPrivateKey(owner2KeyBech32) + .complete(); + const txHash = await signedTx.submit(); + + await isTxValidated(txHash) + + console.log("✅ txHash from `mintTokenWithOwners23`: " + txHash + "\n"); +} + +// each token holder can burn their tokens without signatures from owners +export async function burnTokens(script: { type: ScriptType; script: string; }, unit: Unit, amount: bigint) { + console.log("- burn tokens with amount, ", amount) + + const tx = await lucid + .newTx() + .mintAssets({[unit]: amount}, Data.void()) + .attachMintingPolicy(script) + .complete(); + + const signedTx = await tx.sign().complete(); + const txHash = await signedTx.submit(); + + await isTxValidated(txHash) + + console.log("✅ txHash from `burnTokens`: " + txHash + "\n"); +} + +export async function addOwner3WithOwners12() { + console.log(" - add owner with 2 owners"); + testDatum.owners = [String(pkh3), String(pkh1), String(pkh2)] + + const utxWithThread = (await lucid.utxosAtWithUnit(validatorAddress, nftUnit))[0] + const tx = await lucid + .newTx() + .collectFrom([utxWithThread], redemeerAddOwner(pkh3, Number(testDatum.minSigs))) + + .addSignerKey(pkh1) + .addSignerKey(pkh2) + + .payToContract(validatorAddress, + {inline: Data.to(testDatum, MultiSigDatum)}, + {lovelace: 2000000n, [nftUnit]: 1n}) + .validTo(Date.now() + 100000) + .attachSpendingValidator(validatorScript) + .complete(); + + const signedTx = await tx.sign() + .signWithPrivateKey(owner2KeyBech32) + .complete(); + const txHash = await signedTx.submit(); + + await isTxValidated(txHash) + + console.log("✅ txHash from `addOwner3WithOwners12`: " + txHash + "\n"); +} + +export async function addOwner1WithOwners23(threshold: number) { + console.log(" - add owner1 with owner2 and owner3"); + testDatum.owners = [String(pkh1), String(pkh3), String(pkh2)] + + const utxWithThread = (await lucid.utxosAtWithUnit(validatorAddress, nftUnit))[0] + const tx = await lucid + .newTx() + .collectFrom([utxWithThread], redemeerAddOwner(pkh1, threshold)) + + .addSignerKey(pkh2) + .addSignerKey(pkh3) + + .payToContract(validatorAddress, + {inline: Data.to(testDatum, MultiSigDatum)}, + {lovelace: 2000000n, [nftUnit]: 1n}) + .validTo(Date.now() + 100000) + .attachSpendingValidator(validatorScript) + .complete(); + + const signedTx = await tx.sign() + .signWithPrivateKey(owner2KeyBech32) + .complete(); + const txHash = await signedTx.submit(); + + await isTxValidated(txHash) + + console.log("✅ txHash from `addOwner1WithOwners23`: " + txHash + "\n"); +} + +export async function mintTokenWithThreeOwners(token: Unit, amount: bigint) { + console.log(" - mint with 3 owners"); + const utxWithThread = (await lucid.utxosAtWithUnit(validatorAddress, nftUnit))[0] + const tx = await lucid + .newTx() + .mintAssets({ [token]: amount }, emptyRedeemer) + .collectFrom([utxWithThread], redemeerTokenMint) + + .addSignerKey(pkh1) + .addSignerKey(pkh2) + .addSignerKey(pkh3) + + .payToContract(validatorAddress, + {inline: Data.to(testDatum, MultiSigDatum)}, + {lovelace: 2000000n, [nftUnit]: 1n}) + + .validTo(Date.now() + 100000) + .attachMintingPolicy(tokenScript) + .attachSpendingValidator(validatorScript) + .complete(); + + const signedTx = await tx.sign() + .signWithPrivateKey(owner2KeyBech32) + .signWithPrivateKey(owner3KeyBech32) + .complete(); + const txHash = await signedTx.submit(); + + await isTxValidated(txHash) + + console.log("✅ txHash from `mintTokenWithThreeOwners`: " + txHash + "\n"); +} + + +export async function removeFirstOwnerWithThreeOwners(threshold: number) { + console.log(" - remove first owner with owners=3, threshold=2, signers are owner3 and owner2"); + testDatum.owners = [String(pkh3), String(pkh2)] + + const utxWithThread = (await lucid.utxosAtWithUnit(validatorAddress, nftUnit))[0] + const tx = await lucid + .newTx() + .collectFrom([utxWithThread], redemeerRemoveOwner(pkh1, threshold)) + + .addSignerKey(pkh2) + .addSignerKey(pkh3) + + .payToContract(validatorAddress, + {inline: Data.to(testDatum, MultiSigDatum)}, + {lovelace: 2000000n, [nftUnit]: 1n}) + .validTo(Date.now() + 100000) + .attachSpendingValidator(validatorScript) + .complete(); + + const signedTx = await tx.sign() + .signWithPrivateKey(owner2KeyBech32) + .complete(); + const txHash = await signedTx.submit(); + + await isTxValidated(txHash) + + console.log("✅ txHash from `removeFirstOwnerWithThreeOwners`: " + txHash + "\n"); +} + + +export async function updateThresholdWithOwners23(newThreshold: number) { + console.log(" - update threshold number, current threshold=",testDatum.minSigs, "new threshold=", BigInt(newThreshold)); + const utxWithThread = (await lucid.utxosAtWithUnit(validatorAddress, nftUnit))[0] + + testDatum.minSigs = BigInt(newThreshold) + + const tx = await lucid + .newTx() + .collectFrom([utxWithThread], redemeerUpdateThreshold(newThreshold)) + + .addSignerKey(pkh1) + .addSignerKey(pkh2) + .addSignerKey(pkh3) + + .payToContract(validatorAddress, + {inline: Data.to(testDatum, MultiSigDatum)}, + {lovelace: 2000000n, [nftUnit]: 1n}) + .validTo(Date.now() + 100000) + .attachSpendingValidator(validatorScript) + .complete(); + + const signedTx = await tx.sign() + .signWithPrivateKey(owner2KeyBech32) + .signWithPrivateKey(owner1KeyBech32) + .complete(); + const txHash = await signedTx.submit(); + + await isTxValidated(txHash) + + console.log("✅ txHash from `updateThresholdWithOwners23`: " + txHash + "\n"); +} + +export async function setToInitState(threshold: number) { + console.log(" - setToInitState: remove owner3 & set threshold=2 in one tx"); + testDatum = { owners : [String(pkh1), String(pkh2)], minSigs: 2n } + + const utxWithThread = (await lucid.utxosAtWithUnit(validatorAddress, nftUnit))[0] + const tx = await lucid + .newTx() + .collectFrom([utxWithThread], redemeerRemoveOwner(pkh3, threshold)) + + .addSignerKey(pkh1) + .addSignerKey(pkh2) + .addSignerKey(pkh3) + + .payToContract(validatorAddress, + {inline: Data.to(testDatum, MultiSigDatum)}, + {lovelace: 2000000n, [nftUnit]: 1n}) + .validTo(Date.now() + 100000) + .attachSpendingValidator(validatorScript) + .complete(); + + const signedTx = await tx.sign() + .signWithPrivateKey(owner2KeyBech32) + .signWithPrivateKey(owner3KeyBech32) + .complete(); + const txHash = await signedTx.submit(); + + await isTxValidated(txHash) + + console.log("✅ txHash from `setToInitState`: " + txHash + "\n"); +} + + +// can be adjusted. however, sometimes it can be not enough +const secondsToWait: number = 1000*40 + +const main = async() => { + try { + //console.log("mint NFT: ", await mintNFT(testDatum)) + //delay(secondsToWait) + + console.log( + "\n***** Testing: MINTING *****\n", + ) + await mintTokenWithOwners12(tokenUnit, 10n) + await delay(secondsToWait) + + await notOwnerMinting(tokenUnit, 7n) + await delay(secondsToWait) + + + console.log( + "\n***** Testing: BURNING *****\n", + ) + await burnTokens(tokenScript, tokenUnit, -3n) + + + console.log( + "\n***** Testing: ADD owner & MINT tokens *****\n", + ) + + await addOwner3WithOwners12() + await delay(secondsToWait) + + await mintTokenWithThreeOwners(tokenUnit, 5n) + await delay(secondsToWait) + + + console.log( + "\n***** Testing: REMOVE owner & MINT tokens *****\n", + ) + + lucid.selectWalletFromPrivateKey(owner3KeyBech32) + + await removeFirstOwnerWithThreeOwners(2) + await delay(secondsToWait) + + await mintTokenWithOwners23(tokenUnit, 14n) + await delay(secondsToWait) + + console.log( + "\n***** Testing: ADD owner & UPDATE threshold *****\n", + ) + await addOwner1WithOwners23(2) + await delay(secondsToWait) + + await updateThresholdWithOwners23(3) + await delay(secondsToWait) + + lucid.selectWalletFromPrivateKey(owner1KeyBech32) + await mintTokenWithThreeOwners(tokenUnit, 30n) + + console.log( + "\n***** Setting to initial state *****\n", + ) + //remove third owner and update threshold to `2` in one transaction + await setToInitState(2) + await delay(secondsToWait) + } catch(error) { + console.log("Error while running tests: ", error) + } +} + + +//console.log("Get wallet utxos: ", await lucid.wallet.getUtxos()) + +await main() + diff --git a/tests/package-lock.json b/tests/package-lock.json index 0e3dee6..cf8802f 100644 --- a/tests/package-lock.json +++ b/tests/package-lock.json @@ -6,8 +6,8 @@ "": { "dependencies": { "buffer": "^6.0.3", - "colors.ts": "^1.0.20", - "lucid-cardano": "^0.10.7" + "lucid-cardano": "^0.10.7", + "typescript": "^5.5.3" }, "devDependencies": { "@types/node": "^20.14.2" @@ -113,11 +113,6 @@ "ieee754": "^1.2.1" } }, - "node_modules/colors.ts": { - "version": "1.0.20", - "resolved": "https://registry.npmjs.org/colors.ts/-/colors.ts-1.0.20.tgz", - "integrity": "sha512-MnVQgqGe3S7KLlK0v7rsLQciRgB4NzfRPZ4OZuu8SWNgyJuV651pMqCq7LvJ7eQO586RVspwYvK2ere7xX/m1A==" - }, "node_modules/data-uri-to-buffer": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-4.0.1.tgz", @@ -247,6 +242,18 @@ "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz", "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==" }, + "node_modules/typescript": { + "version": "5.5.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.5.3.tgz", + "integrity": "sha512-/hreyEujaB0w76zKo6717l3L0o/qEUtRgdvUBvlkhoWeOVMjMuHNHk0BRBzikzuGDqNmPQbg5ifMEqsHLiIUcQ==", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, "node_modules/undici-types": { "version": "5.26.5", "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", diff --git a/tests/package.json b/tests/package.json index 3496b25..a28eb77 100644 --- a/tests/package.json +++ b/tests/package.json @@ -5,6 +5,7 @@ }, "dependencies": { "buffer": "^6.0.3", - "lucid-cardano": "^0.10.7" + "lucid-cardano": "^0.10.7", + "typescript": "^5.5.3" } } diff --git a/tests/tsconfig.json b/tests/tsconfig.json index 938ba08..8faf556 100644 --- a/tests/tsconfig.json +++ b/tests/tsconfig.json @@ -1,14 +1,14 @@ { "compilerOptions": { "esModuleInterop": true, - "lib": ["es2020"], + "lib": ["es2020", "dom"], "module": "nodenext", "moduleResolution": "nodenext", "target": "es2022", "outDir": "dist", + "sourceMap": true, "resolveJsonModule": true - }, - "include": ["./offchain.ts", "./secret.ts"], + "include": ["./offchain.ts", "./secret.ts", "offchain_emulated.ts"], "exclude": ["node_modules"] - } \ No newline at end of file + }