├── .gitignore ├── .mvn └── wrapper │ ├── MavenWrapperDownloader.java │ └── maven-wrapper.properties ├── README.md ├── mvnw ├── mvnw.cmd ├── pom.xml └── src ├── main └── java │ └── com │ └── bloxbean │ └── cardano │ └── client │ └── examples │ └── placeholder.tx └── test ├── java └── com │ └── bloxbean │ └── cardano │ └── client │ └── example │ ├── AccountGen.java │ ├── AdaTransactionTest.java │ ├── AdaTransactionWithMetadataTest.java │ ├── AlwaysSuccessContractCall.java │ ├── AssetTest.java │ ├── BaseTest.java │ ├── BlockServiceTest.java │ ├── Constant.java │ ├── ContractCall.java │ ├── GensisTest.java │ ├── MaxAdaTxnTest.java │ ├── MintAndBurn.java │ ├── MintTokenPolicyWithRegularAccountTest.java │ ├── MintTokenTest.java │ ├── MultiSigMint.java │ ├── MultiWitnessWithPaymentTransaction.java │ ├── MultisigMultiPartyDistribution.java │ ├── SignVerifyDataTest.java │ ├── TransactionSigningWithoutBackend.java │ ├── TransferFromMultisigScriptAddress.java │ ├── TransferTokenTest.java │ ├── cip8 │ └── CIP8CBORParser.java │ ├── derivation │ └── AddressDerivationFromPublicKey.java │ ├── function │ ├── TransferTransactionMultiSenderMultiReceiverTest.java │ ├── TransferTransactionTest.java │ ├── contract │ │ ├── ContractBaseTest.java │ │ ├── v1 │ │ │ ├── CustomGuessContractTest.java │ │ │ ├── Guess.java │ │ │ ├── MintContractAndDistributeAndAnotherContractCallTest.java │ │ │ ├── MintContractAndDistributeTest.java │ │ │ ├── MintContractTest.java │ │ │ └── MultipleContractCallInOneTxnTest.java │ │ └── v2 │ │ │ └── GuessSumContractTest.java │ └── minting │ │ ├── MintAndBurnTokenTest.java │ │ ├── MintTokenAndScriptTxn.java │ │ ├── MintTokenNFT.java │ │ ├── MintTokenTest.java │ │ └── MulitpleMintNFTsWithRefund.java │ ├── quicktx │ ├── AlwaysTrueScriptTest.java │ ├── Minting.java │ ├── MultiScriptMinting.java │ ├── P2PNFTTransfer.java │ ├── QuickTxBaseTest.java │ ├── ReferenceInputScriptTest.java │ ├── ScriptStakingTest.java │ ├── SimplePayment.java │ ├── SimplePaymentDifferentFeePayer.java │ └── StakingTest.java │ └── timelock │ ├── TimeLockPaymentScriptWithRegularAddressWithMultisigStakingCredential.java │ └── TimeLockScriptWithRegularAddress.java └── resources ├── log4j.properties └── multisig.script /.gitignore: -------------------------------------------------------------------------------- 1 | # Created by https://www.toptal.com/developers/gitignore/api/java,gradle,intellij 2 | # Edit at https://www.toptal.com/developers/gitignore?templates=java,gradle,intellij 3 | 4 | ### Intellij ### 5 | # Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio, WebStorm and Rider 6 | # Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839 7 | 8 | # User-specific stuff 9 | .idea 10 | .idea/**/workspace.xml 11 | .idea/**/tasks.xml 12 | .idea/**/usage.statistics.xml 13 | .idea/**/dictionaries 14 | .idea/**/shelf 15 | 16 | # Generated files 17 | .idea/**/contentModel.xml 18 | 19 | # Sensitive or high-churn files 20 | .idea/**/dataSources/ 21 | .idea/**/dataSources.ids 22 | .idea/**/dataSources.local.xml 23 | .idea/**/sqlDataSources.xml 24 | .idea/**/dynamic.xml 25 | .idea/**/uiDesigner.xml 26 | .idea/**/dbnavigator.xml 27 | 28 | # Gradle 29 | .idea/**/gradle.xml 30 | .idea/**/libraries 31 | 32 | # Gradle and Maven with auto-import 33 | # When using Gradle or Maven with auto-import, you should exclude module files, 34 | # since they will be recreated, and may cause churn. Uncomment if using 35 | # auto-import. 36 | # .idea/artifacts 37 | # .idea/compiler.xml 38 | # .idea/jarRepositories.xml 39 | # .idea/modules.xml 40 | # .idea/*.iml 41 | # .idea/modules 42 | # *.iml 43 | # *.ipr 44 | 45 | # CMake 46 | cmake-build-*/ 47 | 48 | # Mongo Explorer plugin 49 | .idea/**/mongoSettings.xml 50 | 51 | # File-based project format 52 | *.iws 53 | 54 | # IntelliJ 55 | out/ 56 | 57 | # mpeltonen/sbt-idea plugin 58 | .idea_modules/ 59 | 60 | # JIRA plugin 61 | atlassian-ide-plugin.xml 62 | 63 | # Cursive Clojure plugin 64 | .idea/replstate.xml 65 | 66 | # Crashlytics plugin (for Android Studio and IntelliJ) 67 | com_crashlytics_export_strings.xml 68 | crashlytics.properties 69 | crashlytics-build.properties 70 | fabric.properties 71 | 72 | # Editor-based Rest Client 73 | .idea/httpRequests 74 | 75 | # Android studio 3.1+ serialized cache file 76 | .idea/caches/build_file_checksums.ser 77 | 78 | ### Intellij Patch ### 79 | # Comment Reason: https://github.com/joeblau/gitignore.io/issues/186#issuecomment-215987721 80 | 81 | # *.iml 82 | # modules.xml 83 | # .idea/misc.xml 84 | # *.ipr 85 | 86 | # Sonarlint plugin 87 | # https://plugins.jetbrains.com/plugin/7973-sonarlint 88 | .idea/**/sonarlint/ 89 | 90 | # SonarQube Plugin 91 | # https://plugins.jetbrains.com/plugin/7238-sonarqube-community-plugin 92 | .idea/**/sonarIssues.xml 93 | 94 | # Markdown Navigator plugin 95 | # https://plugins.jetbrains.com/plugin/7896-markdown-navigator-enhanced 96 | .idea/**/markdown-navigator.xml 97 | .idea/**/markdown-navigator-enh.xml 98 | .idea/**/markdown-navigator/ 99 | 100 | # Cache file creation bug 101 | # See https://youtrack.jetbrains.com/issue/JBR-2257 102 | .idea/$CACHE_FILE$ 103 | 104 | # CodeStream plugin 105 | # https://plugins.jetbrains.com/plugin/12206-codestream 106 | .idea/codestream.xml 107 | 108 | ### Java ### 109 | # Compiled class file 110 | *.class 111 | 112 | # Log file 113 | *.log 114 | 115 | # BlueJ files 116 | *.ctxt 117 | 118 | # Mobile Tools for Java (J2ME) 119 | .mtj.tmp/ 120 | 121 | # Package Files # 122 | *.jar 123 | *.war 124 | *.nar 125 | *.ear 126 | *.zip 127 | *.tar.gz 128 | *.rar 129 | 130 | # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml 131 | hs_err_pid* 132 | 133 | ### Gradle ### 134 | .gradle 135 | build/ 136 | 137 | # Ignore Gradle GUI config 138 | gradle-app.setting 139 | 140 | # Avoid ignoring Gradle wrapper jar file (.jar files are usually ignored) 141 | !gradle-wrapper.jar 142 | 143 | # Cache of project 144 | .gradletasknamecache 145 | 146 | # # Work around https://youtrack.jetbrains.com/issue/IDEA-116898 147 | # gradle/wrapper/gradle-wrapper.properties 148 | 149 | ### Gradle Patch ### 150 | **/build/ 151 | 152 | ### Rust ## 153 | /rust/.idea 154 | /rust/target 155 | #/rust/Cargo.lock 156 | # End of https://www.toptal.com/developers/gitignore/api/java,gradle,intellij 157 | 158 | -------------------------------------------------------------------------------- /.mvn/wrapper/MavenWrapperDownloader.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2007-present the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import java.net.*; 18 | import java.io.*; 19 | import java.nio.channels.*; 20 | import java.util.Properties; 21 | 22 | public class MavenWrapperDownloader { 23 | 24 | private static final String WRAPPER_VERSION = "0.5.6"; 25 | /** 26 | * Default URL to download the maven-wrapper.jar from, if no 'downloadUrl' is provided. 27 | */ 28 | private static final String DEFAULT_DOWNLOAD_URL = "https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/" 29 | + WRAPPER_VERSION + "/maven-wrapper-" + WRAPPER_VERSION + ".jar"; 30 | 31 | /** 32 | * Path to the maven-wrapper.properties file, which might contain a downloadUrl property to 33 | * use instead of the default one. 34 | */ 35 | private static final String MAVEN_WRAPPER_PROPERTIES_PATH = 36 | ".mvn/wrapper/maven-wrapper.properties"; 37 | 38 | /** 39 | * Path where the maven-wrapper.jar will be saved to. 40 | */ 41 | private static final String MAVEN_WRAPPER_JAR_PATH = 42 | ".mvn/wrapper/maven-wrapper.jar"; 43 | 44 | /** 45 | * Name of the property which should be used to override the default download url for the wrapper. 46 | */ 47 | private static final String PROPERTY_NAME_WRAPPER_URL = "wrapperUrl"; 48 | 49 | public static void main(String args[]) { 50 | System.out.println("- Downloader started"); 51 | File baseDirectory = new File(args[0]); 52 | System.out.println("- Using base directory: " + baseDirectory.getAbsolutePath()); 53 | 54 | // If the maven-wrapper.properties exists, read it and check if it contains a custom 55 | // wrapperUrl parameter. 56 | File mavenWrapperPropertyFile = new File(baseDirectory, MAVEN_WRAPPER_PROPERTIES_PATH); 57 | String url = DEFAULT_DOWNLOAD_URL; 58 | if (mavenWrapperPropertyFile.exists()) { 59 | FileInputStream mavenWrapperPropertyFileInputStream = null; 60 | try { 61 | mavenWrapperPropertyFileInputStream = new FileInputStream(mavenWrapperPropertyFile); 62 | Properties mavenWrapperProperties = new Properties(); 63 | mavenWrapperProperties.load(mavenWrapperPropertyFileInputStream); 64 | url = mavenWrapperProperties.getProperty(PROPERTY_NAME_WRAPPER_URL, url); 65 | } catch (IOException e) { 66 | System.out.println("- ERROR loading '" + MAVEN_WRAPPER_PROPERTIES_PATH + "'"); 67 | } finally { 68 | try { 69 | if (mavenWrapperPropertyFileInputStream != null) { 70 | mavenWrapperPropertyFileInputStream.close(); 71 | } 72 | } catch (IOException e) { 73 | // Ignore ... 74 | } 75 | } 76 | } 77 | System.out.println("- Downloading from: " + url); 78 | 79 | File outputFile = new File(baseDirectory.getAbsolutePath(), MAVEN_WRAPPER_JAR_PATH); 80 | if (!outputFile.getParentFile().exists()) { 81 | if (!outputFile.getParentFile().mkdirs()) { 82 | System.out.println( 83 | "- ERROR creating output directory '" + outputFile.getParentFile().getAbsolutePath() + "'"); 84 | } 85 | } 86 | System.out.println("- Downloading to: " + outputFile.getAbsolutePath()); 87 | try { 88 | downloadFileFromURL(url, outputFile); 89 | System.out.println("Done"); 90 | System.exit(0); 91 | } catch (Throwable e) { 92 | System.out.println("- Error downloading"); 93 | e.printStackTrace(); 94 | System.exit(1); 95 | } 96 | } 97 | 98 | private static void downloadFileFromURL(String urlString, File destination) throws Exception { 99 | if (System.getenv("MVNW_USERNAME") != null && System.getenv("MVNW_PASSWORD") != null) { 100 | String username = System.getenv("MVNW_USERNAME"); 101 | char[] password = System.getenv("MVNW_PASSWORD").toCharArray(); 102 | Authenticator.setDefault(new Authenticator() { 103 | @Override 104 | protected PasswordAuthentication getPasswordAuthentication() { 105 | return new PasswordAuthentication(username, password); 106 | } 107 | }); 108 | } 109 | URL website = new URL(urlString); 110 | ReadableByteChannel rbc; 111 | rbc = Channels.newChannel(website.openStream()); 112 | FileOutputStream fos = new FileOutputStream(destination); 113 | fos.getChannel().transferFrom(rbc, 0, Long.MAX_VALUE); 114 | fos.close(); 115 | rbc.close(); 116 | } 117 | 118 | } 119 | -------------------------------------------------------------------------------- /.mvn/wrapper/maven-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.6.3/apache-maven-3.6.3-bin.zip 2 | wrapperUrl=https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar 3 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # cardano-client-example 2 | 3 | Examples for [cardano-client-lib](https://github.com/bloxbean/cardano-client-lib) 4 | 5 | Examples are under "test" source root 6 | 7 | Add Blockfrost testnet project id in Constant.java 8 | 9 | 10 | ## Quick Tx High Level api samples 11 | 12 | Check in branch 0.5.0 for the examples using new high-level api (QuickTx) 13 | -------------------------------------------------------------------------------- /mvnw: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # ---------------------------------------------------------------------------- 3 | # Licensed to the Apache Software Foundation (ASF) under one 4 | # or more contributor license agreements. See the NOTICE file 5 | # distributed with this work for additional information 6 | # regarding copyright ownership. The ASF licenses this file 7 | # to you under the Apache License, Version 2.0 (the 8 | # "License"); you may not use this file except in compliance 9 | # with the License. You may obtain a copy of the License at 10 | # 11 | # http://www.apache.org/licenses/LICENSE-2.0 12 | # 13 | # Unless required by applicable law or agreed to in writing, 14 | # software distributed under the License is distributed on an 15 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 | # KIND, either express or implied. See the License for the 17 | # specific language governing permissions and limitations 18 | # under the License. 19 | # ---------------------------------------------------------------------------- 20 | 21 | # ---------------------------------------------------------------------------- 22 | # Maven Start Up Batch script 23 | # 24 | # Required ENV vars: 25 | # ------------------ 26 | # JAVA_HOME - location of a JDK home dir 27 | # 28 | # Optional ENV vars 29 | # ----------------- 30 | # M2_HOME - location of maven2's installed home dir 31 | # MAVEN_OPTS - parameters passed to the Java VM when running Maven 32 | # e.g. to debug Maven itself, use 33 | # set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 34 | # MAVEN_SKIP_RC - flag to disable loading of mavenrc files 35 | # ---------------------------------------------------------------------------- 36 | 37 | if [ -z "$MAVEN_SKIP_RC" ] ; then 38 | 39 | if [ -f /etc/mavenrc ] ; then 40 | . /etc/mavenrc 41 | fi 42 | 43 | if [ -f "$HOME/.mavenrc" ] ; then 44 | . "$HOME/.mavenrc" 45 | fi 46 | 47 | fi 48 | 49 | # OS specific support. $var _must_ be set to either true or false. 50 | cygwin=false; 51 | darwin=false; 52 | mingw=false 53 | case "`uname`" in 54 | CYGWIN*) cygwin=true ;; 55 | MINGW*) mingw=true;; 56 | Darwin*) darwin=true 57 | # Use /usr/libexec/java_home if available, otherwise fall back to /Library/Java/Home 58 | # See https://developer.apple.com/library/mac/qa/qa1170/_index.html 59 | if [ -z "$JAVA_HOME" ]; then 60 | if [ -x "/usr/libexec/java_home" ]; then 61 | export JAVA_HOME="`/usr/libexec/java_home`" 62 | else 63 | export JAVA_HOME="/Library/Java/Home" 64 | fi 65 | fi 66 | ;; 67 | esac 68 | 69 | if [ -z "$JAVA_HOME" ] ; then 70 | if [ -r /etc/gentoo-release ] ; then 71 | JAVA_HOME=`java-config --jre-home` 72 | fi 73 | fi 74 | 75 | if [ -z "$M2_HOME" ] ; then 76 | ## resolve links - $0 may be a link to maven's home 77 | PRG="$0" 78 | 79 | # need this for relative symlinks 80 | while [ -h "$PRG" ] ; do 81 | ls=`ls -ld "$PRG"` 82 | link=`expr "$ls" : '.*-> \(.*\)$'` 83 | if expr "$link" : '/.*' > /dev/null; then 84 | PRG="$link" 85 | else 86 | PRG="`dirname "$PRG"`/$link" 87 | fi 88 | done 89 | 90 | saveddir=`pwd` 91 | 92 | M2_HOME=`dirname "$PRG"`/.. 93 | 94 | # make it fully qualified 95 | M2_HOME=`cd "$M2_HOME" && pwd` 96 | 97 | cd "$saveddir" 98 | # echo Using m2 at $M2_HOME 99 | fi 100 | 101 | # For Cygwin, ensure paths are in UNIX format before anything is touched 102 | if $cygwin ; then 103 | [ -n "$M2_HOME" ] && 104 | M2_HOME=`cygpath --unix "$M2_HOME"` 105 | [ -n "$JAVA_HOME" ] && 106 | JAVA_HOME=`cygpath --unix "$JAVA_HOME"` 107 | [ -n "$CLASSPATH" ] && 108 | CLASSPATH=`cygpath --path --unix "$CLASSPATH"` 109 | fi 110 | 111 | # For Mingw, ensure paths are in UNIX format before anything is touched 112 | if $mingw ; then 113 | [ -n "$M2_HOME" ] && 114 | M2_HOME="`(cd "$M2_HOME"; pwd)`" 115 | [ -n "$JAVA_HOME" ] && 116 | JAVA_HOME="`(cd "$JAVA_HOME"; pwd)`" 117 | fi 118 | 119 | if [ -z "$JAVA_HOME" ]; then 120 | javaExecutable="`which javac`" 121 | if [ -n "$javaExecutable" ] && ! [ "`expr \"$javaExecutable\" : '\([^ ]*\)'`" = "no" ]; then 122 | # readlink(1) is not available as standard on Solaris 10. 123 | readLink=`which readlink` 124 | if [ ! `expr "$readLink" : '\([^ ]*\)'` = "no" ]; then 125 | if $darwin ; then 126 | javaHome="`dirname \"$javaExecutable\"`" 127 | javaExecutable="`cd \"$javaHome\" && pwd -P`/javac" 128 | else 129 | javaExecutable="`readlink -f \"$javaExecutable\"`" 130 | fi 131 | javaHome="`dirname \"$javaExecutable\"`" 132 | javaHome=`expr "$javaHome" : '\(.*\)/bin'` 133 | JAVA_HOME="$javaHome" 134 | export JAVA_HOME 135 | fi 136 | fi 137 | fi 138 | 139 | if [ -z "$JAVACMD" ] ; then 140 | if [ -n "$JAVA_HOME" ] ; then 141 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then 142 | # IBM's JDK on AIX uses strange locations for the executables 143 | JAVACMD="$JAVA_HOME/jre/sh/java" 144 | else 145 | JAVACMD="$JAVA_HOME/bin/java" 146 | fi 147 | else 148 | JAVACMD="`which java`" 149 | fi 150 | fi 151 | 152 | if [ ! -x "$JAVACMD" ] ; then 153 | echo "Error: JAVA_HOME is not defined correctly." >&2 154 | echo " We cannot execute $JAVACMD" >&2 155 | exit 1 156 | fi 157 | 158 | if [ -z "$JAVA_HOME" ] ; then 159 | echo "Warning: JAVA_HOME environment variable is not set." 160 | fi 161 | 162 | CLASSWORLDS_LAUNCHER=org.codehaus.plexus.classworlds.launcher.Launcher 163 | 164 | # traverses directory structure from process work directory to filesystem root 165 | # first directory with .mvn subdirectory is considered project base directory 166 | find_maven_basedir() { 167 | 168 | if [ -z "$1" ] 169 | then 170 | echo "Path not specified to find_maven_basedir" 171 | return 1 172 | fi 173 | 174 | basedir="$1" 175 | wdir="$1" 176 | while [ "$wdir" != '/' ] ; do 177 | if [ -d "$wdir"/.mvn ] ; then 178 | basedir=$wdir 179 | break 180 | fi 181 | # workaround for JBEAP-8937 (on Solaris 10/Sparc) 182 | if [ -d "${wdir}" ]; then 183 | wdir=`cd "$wdir/.."; pwd` 184 | fi 185 | # end of workaround 186 | done 187 | echo "${basedir}" 188 | } 189 | 190 | # concatenates all lines of a file 191 | concat_lines() { 192 | if [ -f "$1" ]; then 193 | echo "$(tr -s '\n' ' ' < "$1")" 194 | fi 195 | } 196 | 197 | BASE_DIR=`find_maven_basedir "$(pwd)"` 198 | if [ -z "$BASE_DIR" ]; then 199 | exit 1; 200 | fi 201 | 202 | ########################################################################################## 203 | # Extension to allow automatically downloading the maven-wrapper.jar from Maven-central 204 | # This allows using the maven wrapper in projects that prohibit checking in binary data. 205 | ########################################################################################## 206 | if [ -r "$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" ]; then 207 | if [ "$MVNW_VERBOSE" = true ]; then 208 | echo "Found .mvn/wrapper/maven-wrapper.jar" 209 | fi 210 | else 211 | if [ "$MVNW_VERBOSE" = true ]; then 212 | echo "Couldn't find .mvn/wrapper/maven-wrapper.jar, downloading it ..." 213 | fi 214 | if [ -n "$MVNW_REPOURL" ]; then 215 | jarUrl="$MVNW_REPOURL/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar" 216 | else 217 | jarUrl="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar" 218 | fi 219 | while IFS="=" read key value; do 220 | case "$key" in (wrapperUrl) jarUrl="$value"; break ;; 221 | esac 222 | done < "$BASE_DIR/.mvn/wrapper/maven-wrapper.properties" 223 | if [ "$MVNW_VERBOSE" = true ]; then 224 | echo "Downloading from: $jarUrl" 225 | fi 226 | wrapperJarPath="$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" 227 | if $cygwin; then 228 | wrapperJarPath=`cygpath --path --windows "$wrapperJarPath"` 229 | fi 230 | 231 | if command -v wget > /dev/null; then 232 | if [ "$MVNW_VERBOSE" = true ]; then 233 | echo "Found wget ... using wget" 234 | fi 235 | if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then 236 | wget "$jarUrl" -O "$wrapperJarPath" 237 | else 238 | wget --http-user=$MVNW_USERNAME --http-password=$MVNW_PASSWORD "$jarUrl" -O "$wrapperJarPath" 239 | fi 240 | elif command -v curl > /dev/null; then 241 | if [ "$MVNW_VERBOSE" = true ]; then 242 | echo "Found curl ... using curl" 243 | fi 244 | if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then 245 | curl -o "$wrapperJarPath" "$jarUrl" -f 246 | else 247 | curl --user $MVNW_USERNAME:$MVNW_PASSWORD -o "$wrapperJarPath" "$jarUrl" -f 248 | fi 249 | 250 | else 251 | if [ "$MVNW_VERBOSE" = true ]; then 252 | echo "Falling back to using Java to download" 253 | fi 254 | javaClass="$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.java" 255 | # For Cygwin, switch paths to Windows format before running javac 256 | if $cygwin; then 257 | javaClass=`cygpath --path --windows "$javaClass"` 258 | fi 259 | if [ -e "$javaClass" ]; then 260 | if [ ! -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then 261 | if [ "$MVNW_VERBOSE" = true ]; then 262 | echo " - Compiling MavenWrapperDownloader.java ..." 263 | fi 264 | # Compiling the Java class 265 | ("$JAVA_HOME/bin/javac" "$javaClass") 266 | fi 267 | if [ -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then 268 | # Running the downloader 269 | if [ "$MVNW_VERBOSE" = true ]; then 270 | echo " - Running MavenWrapperDownloader.java ..." 271 | fi 272 | ("$JAVA_HOME/bin/java" -cp .mvn/wrapper MavenWrapperDownloader "$MAVEN_PROJECTBASEDIR") 273 | fi 274 | fi 275 | fi 276 | fi 277 | ########################################################################################## 278 | # End of extension 279 | ########################################################################################## 280 | 281 | export MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-"$BASE_DIR"} 282 | if [ "$MVNW_VERBOSE" = true ]; then 283 | echo $MAVEN_PROJECTBASEDIR 284 | fi 285 | MAVEN_OPTS="$(concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config") $MAVEN_OPTS" 286 | 287 | # For Cygwin, switch paths to Windows format before running java 288 | if $cygwin; then 289 | [ -n "$M2_HOME" ] && 290 | M2_HOME=`cygpath --path --windows "$M2_HOME"` 291 | [ -n "$JAVA_HOME" ] && 292 | JAVA_HOME=`cygpath --path --windows "$JAVA_HOME"` 293 | [ -n "$CLASSPATH" ] && 294 | CLASSPATH=`cygpath --path --windows "$CLASSPATH"` 295 | [ -n "$MAVEN_PROJECTBASEDIR" ] && 296 | MAVEN_PROJECTBASEDIR=`cygpath --path --windows "$MAVEN_PROJECTBASEDIR"` 297 | fi 298 | 299 | # Provide a "standardized" way to retrieve the CLI args that will 300 | # work with both Windows and non-Windows executions. 301 | MAVEN_CMD_LINE_ARGS="$MAVEN_CONFIG $@" 302 | export MAVEN_CMD_LINE_ARGS 303 | 304 | WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain 305 | 306 | exec "$JAVACMD" \ 307 | $MAVEN_OPTS \ 308 | -classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \ 309 | "-Dmaven.home=${M2_HOME}" "-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \ 310 | ${WRAPPER_LAUNCHER} $MAVEN_CONFIG "$@" 311 | -------------------------------------------------------------------------------- /mvnw.cmd: -------------------------------------------------------------------------------- 1 | @REM ---------------------------------------------------------------------------- 2 | @REM Licensed to the Apache Software Foundation (ASF) under one 3 | @REM or more contributor license agreements. See the NOTICE file 4 | @REM distributed with this work for additional information 5 | @REM regarding copyright ownership. The ASF licenses this file 6 | @REM to you under the Apache License, Version 2.0 (the 7 | @REM "License"); you may not use this file except in compliance 8 | @REM with the License. You may obtain a copy of the License at 9 | @REM 10 | @REM http://www.apache.org/licenses/LICENSE-2.0 11 | @REM 12 | @REM Unless required by applicable law or agreed to in writing, 13 | @REM software distributed under the License is distributed on an 14 | @REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | @REM KIND, either express or implied. See the License for the 16 | @REM specific language governing permissions and limitations 17 | @REM under the License. 18 | @REM ---------------------------------------------------------------------------- 19 | 20 | @REM ---------------------------------------------------------------------------- 21 | @REM Maven Start Up Batch script 22 | @REM 23 | @REM Required ENV vars: 24 | @REM JAVA_HOME - location of a JDK home dir 25 | @REM 26 | @REM Optional ENV vars 27 | @REM M2_HOME - location of maven2's installed home dir 28 | @REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands 29 | @REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a keystroke before ending 30 | @REM MAVEN_OPTS - parameters passed to the Java VM when running Maven 31 | @REM e.g. to debug Maven itself, use 32 | @REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 33 | @REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files 34 | @REM ---------------------------------------------------------------------------- 35 | 36 | @REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on' 37 | @echo off 38 | @REM set title of command window 39 | title %0 40 | @REM enable echoing by setting MAVEN_BATCH_ECHO to 'on' 41 | @if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO% 42 | 43 | @REM set %HOME% to equivalent of $HOME 44 | if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%") 45 | 46 | @REM Execute a user defined script before this one 47 | if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre 48 | @REM check for pre script, once with legacy .bat ending and once with .cmd ending 49 | if exist "%HOME%\mavenrc_pre.bat" call "%HOME%\mavenrc_pre.bat" 50 | if exist "%HOME%\mavenrc_pre.cmd" call "%HOME%\mavenrc_pre.cmd" 51 | :skipRcPre 52 | 53 | @setlocal 54 | 55 | set ERROR_CODE=0 56 | 57 | @REM To isolate internal variables from possible post scripts, we use another setlocal 58 | @setlocal 59 | 60 | @REM ==== START VALIDATION ==== 61 | if not "%JAVA_HOME%" == "" goto OkJHome 62 | 63 | echo. 64 | echo Error: JAVA_HOME not found in your environment. >&2 65 | echo Please set the JAVA_HOME variable in your environment to match the >&2 66 | echo location of your Java installation. >&2 67 | echo. 68 | goto error 69 | 70 | :OkJHome 71 | if exist "%JAVA_HOME%\bin\java.exe" goto init 72 | 73 | echo. 74 | echo Error: JAVA_HOME is set to an invalid directory. >&2 75 | echo JAVA_HOME = "%JAVA_HOME%" >&2 76 | echo Please set the JAVA_HOME variable in your environment to match the >&2 77 | echo location of your Java installation. >&2 78 | echo. 79 | goto error 80 | 81 | @REM ==== END VALIDATION ==== 82 | 83 | :init 84 | 85 | @REM Find the project base dir, i.e. the directory that contains the folder ".mvn". 86 | @REM Fallback to current working directory if not found. 87 | 88 | set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR% 89 | IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir 90 | 91 | set EXEC_DIR=%CD% 92 | set WDIR=%EXEC_DIR% 93 | :findBaseDir 94 | IF EXIST "%WDIR%"\.mvn goto baseDirFound 95 | cd .. 96 | IF "%WDIR%"=="%CD%" goto baseDirNotFound 97 | set WDIR=%CD% 98 | goto findBaseDir 99 | 100 | :baseDirFound 101 | set MAVEN_PROJECTBASEDIR=%WDIR% 102 | cd "%EXEC_DIR%" 103 | goto endDetectBaseDir 104 | 105 | :baseDirNotFound 106 | set MAVEN_PROJECTBASEDIR=%EXEC_DIR% 107 | cd "%EXEC_DIR%" 108 | 109 | :endDetectBaseDir 110 | 111 | IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig 112 | 113 | @setlocal EnableExtensions EnableDelayedExpansion 114 | for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a 115 | @endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS% 116 | 117 | :endReadAdditionalConfig 118 | 119 | SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe" 120 | set WRAPPER_JAR="%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar" 121 | set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain 122 | 123 | set DOWNLOAD_URL="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar" 124 | 125 | FOR /F "tokens=1,2 delims==" %%A IN ("%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties") DO ( 126 | IF "%%A"=="wrapperUrl" SET DOWNLOAD_URL=%%B 127 | ) 128 | 129 | @REM Extension to allow automatically downloading the maven-wrapper.jar from Maven-central 130 | @REM This allows using the maven wrapper in projects that prohibit checking in binary data. 131 | if exist %WRAPPER_JAR% ( 132 | if "%MVNW_VERBOSE%" == "true" ( 133 | echo Found %WRAPPER_JAR% 134 | ) 135 | ) else ( 136 | if not "%MVNW_REPOURL%" == "" ( 137 | SET DOWNLOAD_URL="%MVNW_REPOURL%/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar" 138 | ) 139 | if "%MVNW_VERBOSE%" == "true" ( 140 | echo Couldn't find %WRAPPER_JAR%, downloading it ... 141 | echo Downloading from: %DOWNLOAD_URL% 142 | ) 143 | 144 | powershell -Command "&{"^ 145 | "$webclient = new-object System.Net.WebClient;"^ 146 | "if (-not ([string]::IsNullOrEmpty('%MVNW_USERNAME%') -and [string]::IsNullOrEmpty('%MVNW_PASSWORD%'))) {"^ 147 | "$webclient.Credentials = new-object System.Net.NetworkCredential('%MVNW_USERNAME%', '%MVNW_PASSWORD%');"^ 148 | "}"^ 149 | "[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; $webclient.DownloadFile('%DOWNLOAD_URL%', '%WRAPPER_JAR%')"^ 150 | "}" 151 | if "%MVNW_VERBOSE%" == "true" ( 152 | echo Finished downloading %WRAPPER_JAR% 153 | ) 154 | ) 155 | @REM End of extension 156 | 157 | @REM Provide a "standardized" way to retrieve the CLI args that will 158 | @REM work with both Windows and non-Windows executions. 159 | set MAVEN_CMD_LINE_ARGS=%* 160 | 161 | %MAVEN_JAVA_EXE% %JVM_CONFIG_MAVEN_PROPS% %MAVEN_OPTS% %MAVEN_DEBUG_OPTS% -classpath %WRAPPER_JAR% "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" %WRAPPER_LAUNCHER% %MAVEN_CONFIG% %* 162 | if ERRORLEVEL 1 goto error 163 | goto end 164 | 165 | :error 166 | set ERROR_CODE=1 167 | 168 | :end 169 | @endlocal & set ERROR_CODE=%ERROR_CODE% 170 | 171 | if not "%MAVEN_SKIP_RC%" == "" goto skipRcPost 172 | @REM check for post script, once with legacy .bat ending and once with .cmd ending 173 | if exist "%HOME%\mavenrc_post.bat" call "%HOME%\mavenrc_post.bat" 174 | if exist "%HOME%\mavenrc_post.cmd" call "%HOME%\mavenrc_post.cmd" 175 | :skipRcPost 176 | 177 | @REM pause the script if MAVEN_BATCH_PAUSE is set to 'on' 178 | if "%MAVEN_BATCH_PAUSE%" == "on" pause 179 | 180 | if "%MAVEN_TERMINATE_CMD%" == "on" exit %ERROR_CODE% 181 | 182 | exit /B %ERROR_CODE% 183 | -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | com.bloxbean.cardano.client.samples 8 | cardano-client-examples 9 | 1.0-SNAPSHOT 10 | 11 | 12 | 11 13 | 11 14 | 0.5.0 15 | 16 | 17 | 18 | 19 | com.bloxbean.cardano 20 | cardano-client-lib 21 | ${cardano.client.version} 22 | 23 | 24 | com.bloxbean.cardano 25 | cardano-client-backend-blockfrost 26 | ${cardano.client.version} 27 | 28 | 29 | com.bloxbean.cardano 30 | cardano-client-backend-koios 31 | ${cardano.client.version} 32 | 33 | 34 | com.bloxbean.cardano 35 | cardano-client-backend-ogmios 36 | ${cardano.client.version} 37 | 38 | 39 | com.bloxbean.cardano 40 | aiken-java-binding 41 | 0.0.8 42 | 43 | 44 | net.i2p.crypto 45 | eddsa 46 | 0.3.0 47 | 48 | 49 | org.slf4j 50 | slf4j-log4j12 51 | 1.7.30 52 | 53 | 54 | 55 | 56 | org.junit.jupiter 57 | junit-jupiter-engine 58 | 5.8.1 59 | test 60 | 61 | 62 | org.assertj 63 | assertj-core 64 | 3.21.0 65 | test 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | -------------------------------------------------------------------------------- /src/main/java/com/bloxbean/cardano/client/examples/placeholder.tx: -------------------------------------------------------------------------------- 1 | placeholder 2 | -------------------------------------------------------------------------------- /src/test/java/com/bloxbean/cardano/client/example/AccountGen.java: -------------------------------------------------------------------------------- 1 | package com.bloxbean.cardano.client.example; 2 | 3 | import com.bloxbean.cardano.client.account.Account; 4 | import com.bloxbean.cardano.client.common.model.Networks; 5 | import org.junit.jupiter.api.Test; 6 | 7 | public class AccountGen { 8 | 9 | @Test 10 | public static void genAccount() { 11 | String mnemonic = "kit color frog trick speak employ suit sort bomb goddess jewel primary spoil fade person useless measure manage warfare reduce few scrub beyond era"; 12 | Account account = new Account(Networks.testnet(), mnemonic); 13 | 14 | String baseAddress = account.baseAddress(); 15 | System.out.println(baseAddress); 16 | } 17 | 18 | public static void main(String[] args) { 19 | genAccount(); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/test/java/com/bloxbean/cardano/client/example/AdaTransactionTest.java: -------------------------------------------------------------------------------- 1 | package com.bloxbean.cardano.client.example; 2 | 3 | import com.bloxbean.cardano.client.account.Account; 4 | import com.bloxbean.cardano.client.api.exception.ApiException; 5 | import com.bloxbean.cardano.client.api.helper.model.TransactionResult; 6 | import com.bloxbean.cardano.client.api.model.Result; 7 | import com.bloxbean.cardano.client.common.model.Networks; 8 | import com.bloxbean.cardano.client.exception.AddressExcepion; 9 | import com.bloxbean.cardano.client.exception.CborSerializationException; 10 | import com.bloxbean.cardano.client.transaction.model.PaymentTransaction; 11 | import com.bloxbean.cardano.client.transaction.model.TransactionDetailsParams; 12 | import org.junit.jupiter.api.Test; 13 | 14 | import java.math.BigInteger; 15 | 16 | import static com.bloxbean.cardano.client.common.CardanoConstants.LOVELACE; 17 | import static org.junit.jupiter.api.Assertions.assertTrue; 18 | 19 | public class AdaTransactionTest extends BaseTest { 20 | 21 | @Test 22 | public void transfer() throws ApiException, AddressExcepion, CborSerializationException { 23 | String senderMnemonic = "kit color frog trick speak employ suit sort bomb goddess jewel primary spoil fade person useless measure manage warfare reduce few scrub beyond era"; 24 | Account sender = new Account(Networks.testnet(), senderMnemonic); 25 | 26 | String receiver = "addr_test1qzs3037mcmh77wpq6katwk24v5eq6qk085jnu8uhrduzhf4zl94kwevfv9hpuz4hc0p5vjye3q45umskhdyhwj6ptzrq8tjm23"; 27 | 28 | PaymentTransaction paymentTransaction = 29 | PaymentTransaction.builder() 30 | .sender(sender) 31 | .receiver(receiver) 32 | .amount(BigInteger.valueOf(2500000)) 33 | .unit(LOVELACE) 34 | .build(); 35 | 36 | long ttl = blockService.getLatestBlock().getValue().getSlot() + 1000; 37 | TransactionDetailsParams detailsParams = 38 | TransactionDetailsParams.builder() 39 | .ttl(ttl) 40 | .build(); 41 | 42 | BigInteger fee = feeCalculationService.calculateFee(paymentTransaction, detailsParams 43 | , null); 44 | 45 | paymentTransaction.setFee(fee); 46 | 47 | Result result = transactionHelperService.transfer(paymentTransaction, detailsParams); 48 | 49 | if (result.isSuccessful()) 50 | System.out.println("Transaction Id: " + result.getValue()); 51 | else 52 | System.out.println("Transaction failed: " + result); 53 | 54 | assertTrue(result.isSuccessful()); 55 | waitForTransaction(result); 56 | } 57 | 58 | } 59 | -------------------------------------------------------------------------------- /src/test/java/com/bloxbean/cardano/client/example/AdaTransactionWithMetadataTest.java: -------------------------------------------------------------------------------- 1 | package com.bloxbean.cardano.client.example; 2 | 3 | import com.bloxbean.cardano.client.account.Account; 4 | import com.bloxbean.cardano.client.api.exception.ApiException; 5 | import com.bloxbean.cardano.client.api.helper.model.TransactionResult; 6 | import com.bloxbean.cardano.client.api.model.Result; 7 | import com.bloxbean.cardano.client.common.model.Networks; 8 | import com.bloxbean.cardano.client.exception.AddressExcepion; 9 | import com.bloxbean.cardano.client.exception.CborSerializationException; 10 | import com.bloxbean.cardano.client.metadata.Metadata; 11 | import com.bloxbean.cardano.client.metadata.cbor.CBORMetadata; 12 | import com.bloxbean.cardano.client.metadata.cbor.CBORMetadataList; 13 | import com.bloxbean.cardano.client.metadata.cbor.CBORMetadataMap; 14 | import com.bloxbean.cardano.client.transaction.model.PaymentTransaction; 15 | import com.bloxbean.cardano.client.transaction.model.TransactionDetailsParams; 16 | import org.junit.jupiter.api.Test; 17 | 18 | import java.math.BigInteger; 19 | 20 | import static com.bloxbean.cardano.client.common.CardanoConstants.LOVELACE; 21 | import static org.junit.jupiter.api.Assertions.assertTrue; 22 | 23 | public class AdaTransactionWithMetadataTest extends BaseTest { 24 | 25 | @Test 26 | public void transfer() throws ApiException, AddressExcepion, CborSerializationException { 27 | 28 | String senderMnemonic = "kit color frog trick speak employ suit sort bomb goddess jewel primary spoil fade person useless measure manage warfare reduce few scrub beyond era"; 29 | Account sender = new Account(Networks.testnet(), senderMnemonic); 30 | 31 | String receiver = "addr_test1qqwpl7h3g84mhr36wpetk904p7fchx2vst0z696lxk8ujsjyruqwmlsm344gfux3nsj6njyzj3ppvrqtt36cp9xyydzqzumz82"; 32 | 33 | CBORMetadataMap productDetailsMap 34 | = new CBORMetadataMap() 35 | .put("code", "PROD-800") 36 | .put("slno", "SL20000039484"); 37 | 38 | CBORMetadataList tagList 39 | = new CBORMetadataList() 40 | .add("laptop") 41 | .add("computer"); 42 | 43 | Metadata metadata = new CBORMetadata() 44 | .put(new BigInteger("670001"), productDetailsMap) 45 | .put(new BigInteger("670002"), tagList); 46 | 47 | PaymentTransaction paymentTransaction = 48 | PaymentTransaction.builder() 49 | .sender(sender) 50 | .receiver(receiver) 51 | .amount(BigInteger.valueOf(20000000)) 52 | .unit(LOVELACE) 53 | .build(); 54 | 55 | long ttl = blockService.getLatestBlock().getValue().getSlot() + 1000; 56 | TransactionDetailsParams detailsParams = 57 | TransactionDetailsParams.builder() 58 | .ttl(ttl) 59 | .build(); 60 | 61 | BigInteger fee = feeCalculationService.calculateFee(paymentTransaction, detailsParams, metadata); 62 | paymentTransaction.setFee(fee); 63 | 64 | Result result 65 | = transactionHelperService.transfer(paymentTransaction, detailsParams, metadata); 66 | 67 | if (result.isSuccessful()) 68 | System.out.println("Transaction Id: " + result.getValue()); 69 | else 70 | System.out.println("Transaction failed: " + result); 71 | 72 | assertTrue(result.isSuccessful()); 73 | waitForTransaction(result); 74 | } 75 | 76 | } 77 | -------------------------------------------------------------------------------- /src/test/java/com/bloxbean/cardano/client/example/AssetTest.java: -------------------------------------------------------------------------------- 1 | package com.bloxbean.cardano.client.example; 2 | 3 | import com.bloxbean.cardano.client.api.exception.ApiException; 4 | import com.bloxbean.cardano.client.api.model.Result; 5 | import com.bloxbean.cardano.client.backend.model.Asset; 6 | import com.bloxbean.cardano.client.util.HexUtil; 7 | import com.bloxbean.cardano.client.util.JsonUtil; 8 | import org.junit.jupiter.api.Test; 9 | 10 | import java.nio.charset.StandardCharsets; 11 | 12 | public class AssetTest extends BaseTest { 13 | 14 | public AssetTest() { 15 | super(); 16 | } 17 | 18 | @Test 19 | public void getAssets() throws ApiException { 20 | String policyId = "d11b0562dcac7042636c9dbb44897b38675da0d613d30f98a541a290"; 21 | String assetName = HexUtil.encodeHexString("TestCoin".getBytes(StandardCharsets.UTF_8)); 22 | 23 | Result asset = assetService.getAsset(policyId + assetName); 24 | 25 | System.out.println(JsonUtil.getPrettyJson(asset.getValue())); 26 | } 27 | 28 | public static void main(String[] args) throws ApiException { 29 | AssetTest assetTest = new AssetTest(); 30 | assetTest.getAssets(); 31 | System.exit(1); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/test/java/com/bloxbean/cardano/client/example/BaseTest.java: -------------------------------------------------------------------------------- 1 | package com.bloxbean.cardano.client.example; 2 | 3 | import com.bloxbean.cardano.client.api.ProtocolParamsSupplier; 4 | import com.bloxbean.cardano.client.api.UtxoSupplier; 5 | import com.bloxbean.cardano.client.api.exception.ApiException; 6 | import com.bloxbean.cardano.client.api.helper.FeeCalculationService; 7 | import com.bloxbean.cardano.client.api.helper.TransactionHelperService; 8 | import com.bloxbean.cardano.client.api.helper.UtxoTransactionBuilder; 9 | import com.bloxbean.cardano.client.api.helper.model.TransactionResult; 10 | import com.bloxbean.cardano.client.api.model.Result; 11 | import com.bloxbean.cardano.client.api.model.Utxo; 12 | import com.bloxbean.cardano.client.backend.api.*; 13 | import com.bloxbean.cardano.client.backend.blockfrost.common.Constants; 14 | import com.bloxbean.cardano.client.backend.blockfrost.service.BFBackendService; 15 | import com.bloxbean.cardano.client.backend.model.Block; 16 | import com.bloxbean.cardano.client.backend.model.TransactionContent; 17 | import com.bloxbean.cardano.client.transaction.spec.Asset; 18 | import com.bloxbean.cardano.client.transaction.spec.MultiAsset; 19 | import com.bloxbean.cardano.client.transaction.spec.TransactionOutput; 20 | import com.bloxbean.cardano.client.util.AssetUtil; 21 | import com.bloxbean.cardano.client.util.JsonUtil; 22 | import com.bloxbean.cardano.client.util.Tuple; 23 | 24 | import java.math.BigInteger; 25 | import java.util.ArrayList; 26 | import java.util.Arrays; 27 | import java.util.List; 28 | import java.util.Optional; 29 | 30 | import static com.bloxbean.cardano.client.common.CardanoConstants.LOVELACE; 31 | 32 | public class BaseTest { 33 | 34 | protected BackendService backendService; 35 | protected FeeCalculationService feeCalculationService; 36 | protected TransactionHelperService transactionHelperService; 37 | protected TransactionService transactionService; 38 | protected BlockService blockService; 39 | protected AssetService assetService; 40 | protected NetworkInfoService networkInfoService; 41 | protected UtxoService utxoService; 42 | protected EpochService epochService; 43 | protected UtxoTransactionBuilder utxoTransactionBuilder; 44 | 45 | protected UtxoSupplier utxoSupplier; 46 | protected ProtocolParamsSupplier protocolParamsSupplier; 47 | 48 | public BaseTest() { 49 | backendService = 50 | new BFBackendService(Constants.BLOCKFROST_PREPROD_URL, Constant.BF_PROJECT_KEY); 51 | // new KoiosBackendService(KOIOS_TESTNET_URL); 52 | 53 | feeCalculationService = backendService.getFeeCalculationService(); 54 | transactionHelperService = backendService.getTransactionHelperService(); 55 | transactionService = backendService.getTransactionService(); 56 | blockService = backendService.getBlockService(); 57 | assetService = backendService.getAssetService(); 58 | utxoService = backendService.getUtxoService(); 59 | networkInfoService = backendService.getNetworkInfoService(); 60 | epochService = backendService.getEpochService(); 61 | utxoTransactionBuilder = backendService.getUtxoTransactionBuilder(); 62 | utxoSupplier = new DefaultUtxoSupplier(backendService.getUtxoService()); 63 | protocolParamsSupplier = new DefaultProtocolParamsSupplier(epochService); 64 | } 65 | 66 | protected long getTtl() throws ApiException { 67 | Block block = blockService.getLatestBlock().getValue(); 68 | long slot = block.getSlot(); 69 | return slot + 2000; 70 | } 71 | 72 | protected void waitForTransaction(Result result) { 73 | try { 74 | if (result.isSuccessful()) { //Wait for transaction to be mined 75 | int count = 0; 76 | while (count < 180) { 77 | Result txnResult = transactionService.getTransaction(result.getValue().getTransactionId()); 78 | if (txnResult.isSuccessful()) { 79 | System.out.println(JsonUtil.getPrettyJson(txnResult.getValue())); 80 | break; 81 | } else { 82 | System.out.println("Waiting for transaction to be processed ...."); 83 | } 84 | 85 | count++; 86 | Thread.sleep(2000); 87 | } 88 | } 89 | } catch (Exception e) { 90 | e.printStackTrace(); 91 | } 92 | } 93 | 94 | protected void waitForTransactionHash(Result result) { 95 | try { 96 | if (result.isSuccessful()) { //Wait for transaction to be mined 97 | int count = 0; 98 | while (count < 180) { 99 | Result txnResult = transactionService.getTransaction(result.getValue()); 100 | if (txnResult.isSuccessful()) { 101 | System.out.println(JsonUtil.getPrettyJson(txnResult.getValue())); 102 | break; 103 | } else { 104 | System.out.println("Waiting for transaction to be processed ...."); 105 | } 106 | 107 | count++; 108 | Thread.sleep(2000); 109 | } 110 | } 111 | } catch (Exception e) { 112 | e.printStackTrace(); 113 | } 114 | } 115 | 116 | /** 117 | * Copy utxo content to TransactionOutput 118 | * 119 | * @param changeOutput 120 | * @param utxo 121 | */ 122 | protected void copyUtxoValuesToChangeOutput(TransactionOutput changeOutput, Utxo utxo) { 123 | utxo.getAmount().forEach(utxoAmt -> { //For each amt in utxo 124 | String utxoUnit = utxoAmt.getUnit(); 125 | BigInteger utxoQty = utxoAmt.getQuantity(); 126 | if (utxoUnit.equals(LOVELACE)) { 127 | BigInteger existingCoin = changeOutput.getValue().getCoin(); 128 | if (existingCoin == null) existingCoin = BigInteger.ZERO; 129 | changeOutput.getValue().setCoin(existingCoin.add(utxoQty)); 130 | } else { 131 | Tuple policyIdAssetName = AssetUtil.getPolicyIdAndAssetName(utxoUnit); 132 | 133 | //Find if the policy id is available 134 | Optional multiAssetOptional = 135 | changeOutput.getValue().getMultiAssets().stream().filter(ma -> policyIdAssetName._1.equals(ma.getPolicyId())).findFirst(); 136 | if (multiAssetOptional.isPresent()) { 137 | Optional assetOptional = multiAssetOptional.get().getAssets().stream() 138 | .filter(ast -> policyIdAssetName._2.equals(ast.getName())) 139 | .findFirst(); 140 | if (assetOptional.isPresent()) { 141 | BigInteger changeVal = assetOptional.get().getValue().add(utxoQty); 142 | assetOptional.get().setValue(changeVal); 143 | } else { 144 | Asset asset = new Asset(policyIdAssetName._2, utxoQty); 145 | multiAssetOptional.get().getAssets().add(asset); 146 | } 147 | } else { 148 | Asset asset = new Asset(policyIdAssetName._2, utxoQty); 149 | MultiAsset multiAsset = new MultiAsset(policyIdAssetName._1, new ArrayList<>(Arrays.asList(asset))); 150 | changeOutput.getValue().getMultiAssets().add(multiAsset); 151 | } 152 | } 153 | }); 154 | 155 | //Remove any empty MultiAssets 156 | List multiAssets = changeOutput.getValue().getMultiAssets(); 157 | List markedForRemoval = new ArrayList<>(); 158 | if (multiAssets != null && multiAssets.size() > 0) { 159 | multiAssets.forEach(ma -> { 160 | if (ma.getAssets() == null || ma.getAssets().size() == 0) 161 | markedForRemoval.add(ma); 162 | }); 163 | 164 | if (markedForRemoval != null && !markedForRemoval.isEmpty()) multiAssets.removeAll(markedForRemoval); 165 | } 166 | } 167 | 168 | } 169 | -------------------------------------------------------------------------------- /src/test/java/com/bloxbean/cardano/client/example/BlockServiceTest.java: -------------------------------------------------------------------------------- 1 | package com.bloxbean.cardano.client.example; 2 | 3 | import com.bloxbean.cardano.client.api.exception.ApiException; 4 | import com.bloxbean.cardano.client.api.model.Result; 5 | import com.bloxbean.cardano.client.backend.model.Block; 6 | import com.bloxbean.cardano.client.util.JsonUtil; 7 | import org.junit.jupiter.api.Test; 8 | import org.slf4j.Logger; 9 | import org.slf4j.LoggerFactory; 10 | 11 | public class BlockServiceTest extends BaseTest { 12 | Logger LOG = LoggerFactory.getLogger(BaseTest.class); 13 | 14 | public BlockServiceTest() { 15 | super(); 16 | } 17 | 18 | @Test 19 | public void fetchLatestBlock() throws ApiException { 20 | Result blockResult = blockService.getLatestBlock(); 21 | 22 | System.out.println(JsonUtil.getPrettyJson(blockResult.getValue())); 23 | LOG.info("Block fetched"); 24 | } 25 | 26 | public static void main(String[] args) throws ApiException { 27 | new BlockServiceTest().fetchLatestBlock(); 28 | System.exit(1); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/test/java/com/bloxbean/cardano/client/example/Constant.java: -------------------------------------------------------------------------------- 1 | package com.bloxbean.cardano.client.example; 2 | 3 | public class Constant { 4 | public static final String BF_PROJECT_KEY = ""; 5 | } 6 | -------------------------------------------------------------------------------- /src/test/java/com/bloxbean/cardano/client/example/GensisTest.java: -------------------------------------------------------------------------------- 1 | package com.bloxbean.cardano.client.example; 2 | 3 | import com.bloxbean.cardano.client.api.exception.ApiException; 4 | import com.bloxbean.cardano.client.api.model.Result; 5 | import com.bloxbean.cardano.client.backend.model.Genesis; 6 | import org.junit.jupiter.api.Test; 7 | 8 | public class GensisTest extends BaseTest { 9 | 10 | @Test 11 | public void getGenesis() throws ApiException { 12 | Result result = networkInfoService.getNetworkInfo(); 13 | System.out.println(result.getValue()); 14 | } 15 | 16 | public static void main(String[] args) throws ApiException { 17 | new GensisTest().getGenesis(); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/test/java/com/bloxbean/cardano/client/example/MaxAdaTxnTest.java: -------------------------------------------------------------------------------- 1 | package com.bloxbean.cardano.client.example; 2 | 3 | import com.bloxbean.cardano.client.account.Account; 4 | import com.bloxbean.cardano.client.api.exception.ApiException; 5 | import com.bloxbean.cardano.client.api.model.Amount; 6 | import com.bloxbean.cardano.client.api.model.Result; 7 | import com.bloxbean.cardano.client.api.model.Utxo; 8 | import com.bloxbean.cardano.client.coinselection.UtxoSelectionStrategy; 9 | import com.bloxbean.cardano.client.coinselection.impl.DefaultUtxoSelectionStrategyImpl; 10 | import com.bloxbean.cardano.client.common.model.Networks; 11 | import com.bloxbean.cardano.client.exception.CborSerializationException; 12 | import com.bloxbean.cardano.client.transaction.spec.*; 13 | import org.junit.jupiter.api.Test; 14 | 15 | import java.math.BigInteger; 16 | import java.util.ArrayList; 17 | import java.util.Collections; 18 | import java.util.List; 19 | 20 | import static com.bloxbean.cardano.client.common.ADAConversionUtil.adaToLovelace; 21 | import static com.bloxbean.cardano.client.common.CardanoConstants.LOVELACE; 22 | import static org.junit.jupiter.api.Assertions.assertTrue; 23 | 24 | public class MaxAdaTxnTest extends BaseTest { 25 | 26 | @Test 27 | public void run() throws CborSerializationException, ApiException { 28 | new MaxAdaTxnTest().sendGroupTxn(); 29 | } 30 | 31 | public void sendGroupTxn() throws ApiException, CborSerializationException { 32 | String senderMnemonic = "enjoy slender universe autumn tragic horse matrix welcome mandate goose fitness problem effort solid remain present razor conduct acquire rule select sorry awesome diet"; 33 | Account sender = new Account(Networks.testnet(), senderMnemonic); 34 | 35 | UtxoSelectionStrategy utxoSelectionStrategy = new DefaultUtxoSelectionStrategyImpl(utxoSupplier); 36 | List utxos = utxoSelectionStrategy.selectUtxos(sender.baseAddress(), LOVELACE, adaToLovelace(1000), Collections.emptySet()); 37 | 38 | List inputs = new ArrayList<>(); 39 | BigInteger totalInuputLoveLace = BigInteger.ZERO; 40 | for (Utxo utxo : utxos) { 41 | inputs.add(TransactionInput.builder() 42 | .transactionId(utxo.getTxHash()) 43 | .index(utxo.getOutputIndex()).build()); 44 | 45 | Amount amount = utxo.getAmount().stream().filter(amt -> LOVELACE.equals(amt.getUnit())).findFirst().get(); 46 | totalInuputLoveLace = totalInuputLoveLace.add(amount.getQuantity()); 47 | } 48 | 49 | TransactionOutput change = TransactionOutput 50 | .builder() 51 | .address(sender.baseAddress()) 52 | .value(new Value(BigInteger.ZERO, new ArrayList<>())) 53 | .build(); 54 | utxos.stream().forEach(utxo -> copyUtxoValuesToChangeOutput(change, utxo)); 55 | 56 | List outputs = new ArrayList<>(); 57 | outputs.add(change); 58 | 59 | int index = 1; 60 | BigInteger totalTransferAmt = BigInteger.ZERO; 61 | while (true) { 62 | Account receiverAcc = new Account(Networks.testnet(), senderMnemonic, index++); 63 | BigInteger amtToTransfer = adaToLovelace(1.5); 64 | 65 | TransactionOutput output = TransactionOutput 66 | .builder() 67 | .address(receiverAcc.enterpriseAddress()) 68 | .value(new Value(amtToTransfer, new ArrayList<>())) 69 | .build(); 70 | 71 | outputs.add(output); 72 | 73 | byte[] size = createTxnAndSignForSizeCheck(sender, inputs, outputs); 74 | if (size.length < 16384) { //16kb 75 | totalTransferAmt = totalTransferAmt.add(amtToTransfer); 76 | continue; 77 | } else { 78 | System.out.println("No of transfers >> " + --index); 79 | outputs.remove(output); 80 | break; 81 | } 82 | } 83 | 84 | //Create the transaction body with dummy fee 85 | TransactionBody body = TransactionBody.builder() 86 | .inputs(inputs) 87 | .outputs(outputs) 88 | .ttl(getTtl()) 89 | .fee(BigInteger.valueOf(170000)) 90 | .build(); 91 | 92 | Transaction transaction = Transaction.builder() 93 | .body(body) 94 | .build(); 95 | //Sign the transaction. so that we get the actual size of the transaction to calculate the fee 96 | Transaction signTxn = sender.sign(transaction); //cbor encoded bytes in Hex format 97 | 98 | BigInteger fee = feeCalculationService.calculateFee(signTxn); 99 | 100 | //Final change amount 101 | BigInteger changeAmt = totalInuputLoveLace.subtract(totalTransferAmt).subtract(fee); 102 | body.setFee(fee); 103 | change.getValue().setCoin(changeAmt); 104 | 105 | signTxn = sender.sign(transaction); 106 | 107 | Result result = transactionService.submitTransaction(signTxn.serialize()); 108 | 109 | System.out.println(result); 110 | assertTrue(result.isSuccessful()); 111 | 112 | if (result.isSuccessful()) { 113 | waitForTransactionHash(result); 114 | } else { 115 | System.out.println("Failed : " + result); 116 | } 117 | } 118 | 119 | //Dummy txn for size check 120 | private byte[] createTxnAndSignForSizeCheck(Account sender, List inputs, List outputs) throws CborSerializationException { 121 | //Create the transaction body with dummy fee 122 | TransactionBody body = TransactionBody.builder() 123 | .inputs(inputs) 124 | .outputs(outputs) 125 | .ttl(230000003) 126 | .fee(BigInteger.valueOf(170000)) 127 | .build(); 128 | 129 | Transaction transaction = Transaction.builder() 130 | .body(body) 131 | .build(); 132 | Transaction signTxn = sender.sign(transaction); //cbor encoded bytes in Hex format 133 | 134 | byte[] size = signTxn.serialize(); 135 | return size; 136 | } 137 | } 138 | -------------------------------------------------------------------------------- /src/test/java/com/bloxbean/cardano/client/example/MintTokenPolicyWithRegularAccountTest.java: -------------------------------------------------------------------------------- 1 | package com.bloxbean.cardano.client.example; 2 | 3 | import com.bloxbean.cardano.client.account.Account; 4 | import com.bloxbean.cardano.client.api.exception.ApiException; 5 | import com.bloxbean.cardano.client.api.helper.model.TransactionResult; 6 | import com.bloxbean.cardano.client.api.model.Result; 7 | import com.bloxbean.cardano.client.common.model.Networks; 8 | import com.bloxbean.cardano.client.crypto.SecretKey; 9 | import com.bloxbean.cardano.client.crypto.VerificationKey; 10 | import com.bloxbean.cardano.client.exception.AddressExcepion; 11 | import com.bloxbean.cardano.client.exception.CborSerializationException; 12 | import com.bloxbean.cardano.client.transaction.model.MintTransaction; 13 | import com.bloxbean.cardano.client.transaction.model.TransactionDetailsParams; 14 | import com.bloxbean.cardano.client.transaction.spec.Asset; 15 | import com.bloxbean.cardano.client.transaction.spec.MultiAsset; 16 | import com.bloxbean.cardano.client.transaction.spec.script.ScriptPubkey; 17 | import com.bloxbean.cardano.client.util.JsonUtil; 18 | import org.junit.jupiter.api.Test; 19 | 20 | import java.math.BigInteger; 21 | import java.util.Arrays; 22 | 23 | import static org.junit.jupiter.api.Assertions.assertTrue; 24 | 25 | public class MintTokenPolicyWithRegularAccountTest extends BaseTest { 26 | 27 | @Test 28 | public void run() throws AddressExcepion, CborSerializationException, ApiException { 29 | new MintTokenPolicyWithRegularAccountTest().mintToken(); 30 | } 31 | 32 | public void mintToken() throws CborSerializationException, ApiException, AddressExcepion { 33 | String senderMnemonic = "kit color frog trick speak employ suit sort bomb goddess jewel primary spoil fade person useless measure manage warfare reduce few scrub beyond era"; 34 | Account sender = new Account(Networks.testnet(), senderMnemonic); 35 | 36 | String scriptAccountMnemonic = "episode same use wreck force already grief spike kiss host magic spoon cry lecture tuition style old detect session creek champion cry service exchange"; 37 | Account scriptAccount = new Account(Networks.testnet(), scriptAccountMnemonic); 38 | 39 | byte[] prvKeyBytes = scriptAccount.privateKeyBytes(); 40 | byte[] pubKeyBytes = scriptAccount.publicKeyBytes(); 41 | 42 | SecretKey sk = SecretKey.create(prvKeyBytes); 43 | VerificationKey vkey = VerificationKey.create(pubKeyBytes); 44 | 45 | ScriptPubkey scriptPubkey = ScriptPubkey.create(vkey); 46 | String policyId = scriptPubkey.getPolicyId(); 47 | 48 | MultiAsset multiAsset = new MultiAsset(); 49 | multiAsset.setPolicyId(policyId); 50 | 51 | Asset asset = new Asset("token_12", BigInteger.valueOf(6000)); 52 | multiAsset.getAssets().add(asset); 53 | 54 | MintTransaction mintTransaction = MintTransaction.builder() 55 | .sender(sender) 56 | // .receiver(receiver) 57 | .mintAssets(Arrays.asList(multiAsset)) 58 | .policyScript(scriptPubkey) 59 | .policyKeys(Arrays.asList(sk)) 60 | .build(); 61 | 62 | TransactionDetailsParams detailsParams = 63 | TransactionDetailsParams.builder() 64 | .ttl(getTtl()) 65 | .build(); 66 | 67 | //Calculate fee 68 | BigInteger fee 69 | = feeCalculationService.calculateFee(mintTransaction, detailsParams, null); 70 | mintTransaction.setFee(fee); 71 | 72 | Result result = transactionHelperService.mintToken(mintTransaction, 73 | TransactionDetailsParams.builder().ttl(getTtl()).build()); 74 | 75 | System.out.println(JsonUtil.getPrettyJson(result)); 76 | 77 | if (result.isSuccessful()) 78 | System.out.println("Transaction Id: " + result.getValue()); 79 | else 80 | System.out.println("Transaction failed: " + result); 81 | 82 | assertTrue(result.isSuccessful()); 83 | waitForTransaction(result); 84 | } 85 | 86 | } 87 | -------------------------------------------------------------------------------- /src/test/java/com/bloxbean/cardano/client/example/MintTokenTest.java: -------------------------------------------------------------------------------- 1 | package com.bloxbean.cardano.client.example; 2 | 3 | import com.bloxbean.cardano.client.account.Account; 4 | import com.bloxbean.cardano.client.api.exception.ApiException; 5 | import com.bloxbean.cardano.client.api.helper.model.TransactionResult; 6 | import com.bloxbean.cardano.client.api.model.Result; 7 | import com.bloxbean.cardano.client.common.model.Networks; 8 | import com.bloxbean.cardano.client.crypto.KeyGenUtil; 9 | import com.bloxbean.cardano.client.crypto.Keys; 10 | import com.bloxbean.cardano.client.crypto.SecretKey; 11 | import com.bloxbean.cardano.client.crypto.VerificationKey; 12 | import com.bloxbean.cardano.client.exception.AddressExcepion; 13 | import com.bloxbean.cardano.client.exception.CborSerializationException; 14 | import com.bloxbean.cardano.client.metadata.Metadata; 15 | import com.bloxbean.cardano.client.metadata.cbor.CBORMetadata; 16 | import com.bloxbean.cardano.client.metadata.cbor.CBORMetadataList; 17 | import com.bloxbean.cardano.client.metadata.cbor.CBORMetadataMap; 18 | import com.bloxbean.cardano.client.transaction.model.MintTransaction; 19 | import com.bloxbean.cardano.client.transaction.model.TransactionDetailsParams; 20 | import com.bloxbean.cardano.client.transaction.spec.Asset; 21 | import com.bloxbean.cardano.client.transaction.spec.MultiAsset; 22 | import com.bloxbean.cardano.client.transaction.spec.script.ScriptPubkey; 23 | import com.bloxbean.cardano.client.util.JsonUtil; 24 | import org.junit.jupiter.api.Test; 25 | 26 | import java.math.BigInteger; 27 | import java.util.Arrays; 28 | 29 | import static org.junit.jupiter.api.Assertions.assertTrue; 30 | 31 | public class MintTokenTest extends BaseTest { 32 | 33 | @Test 34 | public void run() throws AddressExcepion, CborSerializationException, ApiException { 35 | new MintTokenTest().mintToken(); 36 | } 37 | 38 | public void mintToken() throws CborSerializationException, ApiException, AddressExcepion { 39 | Keys keys = KeyGenUtil.generateKey(); 40 | VerificationKey vkey = keys.getVkey(); 41 | SecretKey skey = keys.getSkey(); 42 | 43 | ScriptPubkey scriptPubkey = ScriptPubkey.create(vkey); 44 | String policyId = scriptPubkey.getPolicyId(); 45 | 46 | String senderMnemonic = "kit color frog trick speak employ suit sort bomb goddess jewel primary spoil fade person useless measure manage warfare reduce few scrub beyond era"; 47 | Account sender = new Account(Networks.testnet(), senderMnemonic); 48 | // String receiver = "addr_test1qqwpl7h3g84mhr36wpetk904p7fchx2vst0z696lxk8ujsjyruqwmlsm344gfux3nsj6njyzj3ppvrqtt36cp9xyydzqzumz82"; 49 | 50 | MultiAsset multiAsset = new MultiAsset(); 51 | multiAsset.setPolicyId(policyId); 52 | Asset asset = new Asset("TestCoin", BigInteger.valueOf(250000)); 53 | multiAsset.getAssets().add(asset); 54 | 55 | //Metadata 56 | CBORMetadataMap tokenInfoMap 57 | = new CBORMetadataMap() 58 | .put("token", "Test Token") 59 | .put("symbol", "TTOK"); 60 | 61 | CBORMetadataList tagList 62 | = new CBORMetadataList() 63 | .add("tag1") 64 | .add("tag2"); 65 | 66 | Metadata metadata = new CBORMetadata() 67 | .put(new BigInteger("670001"), tokenInfoMap) 68 | .put(new BigInteger("670002"), tagList); 69 | 70 | MintTransaction paymentTransaction = 71 | MintTransaction.builder() 72 | .sender(sender) 73 | .receiver(sender.baseAddress()) 74 | .mintAssets(Arrays.asList(multiAsset)) 75 | .policyScript(scriptPubkey) 76 | .policyKeys(Arrays.asList(skey)) 77 | .build(); 78 | 79 | TransactionDetailsParams detailsParams = TransactionDetailsParams.builder().ttl(getTtl()).build(); 80 | 81 | BigInteger fee = feeCalculationService.calculateFee(paymentTransaction, detailsParams, metadata); 82 | paymentTransaction.setFee(fee); 83 | 84 | Result result = transactionHelperService.mintToken(paymentTransaction, detailsParams, metadata); 85 | System.out.println(result); 86 | 87 | System.out.println("Request: \n" + JsonUtil.getPrettyJson(paymentTransaction)); 88 | if (result.isSuccessful()) 89 | System.out.println("Transaction Id: " + result.getValue()); 90 | else 91 | System.out.println("Transaction failed: " + result); 92 | 93 | assertTrue(result.isSuccessful()); 94 | waitForTransaction(result); 95 | } 96 | } 97 | -------------------------------------------------------------------------------- /src/test/java/com/bloxbean/cardano/client/example/MultiWitnessWithPaymentTransaction.java: -------------------------------------------------------------------------------- 1 | package com.bloxbean.cardano.client.example; 2 | 3 | import com.bloxbean.cardano.client.account.Account; 4 | import com.bloxbean.cardano.client.address.AddressProvider; 5 | import com.bloxbean.cardano.client.api.exception.ApiException; 6 | import com.bloxbean.cardano.client.api.model.ProtocolParams; 7 | import com.bloxbean.cardano.client.api.model.Result; 8 | import com.bloxbean.cardano.client.common.model.Networks; 9 | import com.bloxbean.cardano.client.exception.AddressExcepion; 10 | import com.bloxbean.cardano.client.exception.CborDeserializationException; 11 | import com.bloxbean.cardano.client.exception.CborSerializationException; 12 | import com.bloxbean.cardano.client.transaction.model.PaymentTransaction; 13 | import com.bloxbean.cardano.client.transaction.model.TransactionDetailsParams; 14 | import com.bloxbean.cardano.client.transaction.spec.Transaction; 15 | import com.bloxbean.cardano.client.transaction.spec.TransactionOutput; 16 | import com.bloxbean.cardano.client.transaction.spec.TransactionWitnessSet; 17 | import com.bloxbean.cardano.client.transaction.spec.script.ScriptAtLeast; 18 | import com.bloxbean.cardano.client.transaction.spec.script.ScriptPubkey; 19 | import com.bloxbean.cardano.client.util.HexUtil; 20 | import org.junit.jupiter.api.Test; 21 | 22 | import java.math.BigInteger; 23 | import java.util.Arrays; 24 | 25 | import static com.bloxbean.cardano.client.common.CardanoConstants.LOVELACE; 26 | import static com.bloxbean.cardano.client.common.CardanoConstants.ONE_ADA; 27 | 28 | /** 29 | * Example to transfer ADA from a multisig script address. 30 | * This example uses high-level api to build transaction and then handles witnesses. 31 | */ 32 | public class MultiWitnessWithPaymentTransaction extends BaseTest { 33 | 34 | public void transfer() throws ApiException, AddressExcepion, CborSerializationException, CborDeserializationException { 35 | //String multisigScriptAddr = "addr_test1wzchaw4vxmmpws44ffh99eqzmlg6wr3swg36pqug8xn20ygxgqher"; 36 | String multisigScriptAddr = AddressProvider.getEntAddress(getMultisigScript(), Networks.testnet()).toBech32(); 37 | 38 | String receiverAddress = "addr_test1qr2y2yf2lwj0xn2nrhmyqe26t52twp06cp4lm2r62undytvj5ggkj79y993ds6645ewwfus90su92j554u2294wtm93s25m8cz"; 39 | 40 | BigInteger amountToTransfer = ONE_ADA.multiply(BigInteger.valueOf(7)); 41 | 42 | //Create a payment transaction 43 | //Sender is a ReadOnlyAccount. 44 | //ReadOnlyAccount extends Account. Only needs to override baseAddress() for now. This will be simplified in future release. 45 | PaymentTransaction paymentTransaction = 46 | PaymentTransaction.builder() 47 | .sender(new ReadOnlyAccount(multisigScriptAddr)) 48 | .receiver(receiverAddress) 49 | .amount(amountToTransfer) 50 | .unit(LOVELACE) 51 | .build(); 52 | 53 | TransactionDetailsParams detailsParams = 54 | TransactionDetailsParams.builder() 55 | .ttl(getTtl()) 56 | .build(); 57 | 58 | ProtocolParams protocolParams = epochService.getProtocolParameters().getValue(); 59 | 60 | //Select utxos and build transaction using UtxoTransactionBuilder 61 | Transaction transaction = utxoTransactionBuilder.buildTransaction(Arrays.asList(paymentTransaction), detailsParams, null, protocolParams); 62 | 63 | //Add script witness 64 | TransactionWitnessSet transactionWitnessSet = new TransactionWitnessSet(); 65 | transactionWitnessSet.setNativeScripts(Arrays.asList(getMultisigScript())); 66 | transaction.setWitnessSet(transactionWitnessSet); 67 | 68 | //Set some default fee for exact fee calculation. This will be replace by actual fee later 69 | //Set this after transaction build by utxoTransaction Builder 70 | transaction.getBody().setFee(BigInteger.valueOf(17000000)); 71 | 72 | //Signers 73 | String signerAcc1Mnemonic = "around submit turtle canvas friend remind push vehicle debate drop blouse piece obvious crane tone avoid aspect power milk eye brand cradle tide wrist"; 74 | String signerAcc2Mnemonic = "prison glide olympic diamond rib payment crucial ski vintage example dinner matrix cruise upper antenna surge drink divorce brother half figure skate jar stand"; 75 | 76 | Account signer1 = new Account(Networks.testnet(), signerAcc1Mnemonic); 77 | Account signer2 = new Account(Networks.testnet(), signerAcc2Mnemonic); 78 | 79 | //Sign the transaction. so that we get the actual size of the transaction to calculate the fee 80 | Transaction signTxn = signer1.sign(transaction); //cbor encoded bytes in Hex format 81 | signTxn = signer2.sign(signTxn); 82 | 83 | //Calculate final fee 84 | BigInteger fee = feeCalculationService.calculateFee(signTxn); 85 | 86 | //Update fee in transaction body 87 | transaction.getBody().setFee(fee); 88 | 89 | //Final change amount after fee calculation 90 | //Find change output and the update fee and change amount 91 | for (TransactionOutput output : transaction.getBody().getOutputs()) { 92 | if (output.getAddress().equals(multisigScriptAddr)) { //find change ouput. 93 | BigInteger finalChangeAmt = output.getValue().getCoin().subtract(fee); //substract fee 94 | output.getValue().setCoin(finalChangeAmt); 95 | } 96 | } 97 | 98 | //TODO Sign the transaction by signer1 to add witness and then sign the signed transaction again by signer2 to append signer2's witness 99 | //String finalSignedTxn = signTransactionOneAfterAnother(transaction, signer1, signer2); 100 | 101 | //TODO Uncomment if want to sign independently and then assembly. Orignal transaction can be serialized and distribute to signing party 102 | String finalSignedTxn = signOriginalTransactionBySigner1AndSigner2AndThenAssemble(transaction, signer1, signer2); 103 | 104 | Result result = transactionService.submitTransaction(HexUtil.decodeHexString(finalSignedTxn)); 105 | 106 | System.out.println(result); 107 | if (result.isSuccessful()) 108 | waitForTransactionHash(result); 109 | else 110 | System.out.println("Transaction failed : " + result); 111 | } 112 | 113 | public ScriptAtLeast getMultisigScript() { 114 | ScriptPubkey key1 = new ScriptPubkey(); 115 | key1.setKeyHash("74cfebcf5e97474d7b89c862d7ee7cff22efbb032d4133a1b84cbdcd"); 116 | 117 | ScriptPubkey key2 = new ScriptPubkey(); 118 | key2.setKeyHash("710ee487dbbcdb59b5841a00d1029a56a407c722b3081c02470b516d"); 119 | 120 | ScriptPubkey key3 = new ScriptPubkey(); 121 | key3.setKeyHash("beed26382ec96254a6714928c3c5bb8227abecbbb095cfeab9fb2dd1"); 122 | 123 | ScriptAtLeast scriptAtLeast = new ScriptAtLeast(2); 124 | scriptAtLeast.addScript(key1) 125 | .addScript(key2) 126 | .addScript(key3); 127 | 128 | return scriptAtLeast; 129 | } 130 | 131 | /** 132 | * Sign the transaction first by signer1 and then sign the signed transactioin by signer2 133 | * 134 | * @param transaction 135 | * @param signer1 136 | * @param signer2 137 | * @return 138 | * @throws CborSerializationException 139 | */ 140 | private Transaction signTransactionOneAfterAnother(Transaction transaction, Account signer1, Account signer2) throws CborSerializationException { 141 | Transaction signedTxn = signer1.sign(transaction); 142 | signedTxn = signer2.sign(signedTxn); 143 | 144 | return signedTxn; 145 | } 146 | 147 | private String signOriginalTransactionBySigner1AndSigner2AndThenAssemble(Transaction transaction, Account signer1, Account signer2) 148 | throws CborSerializationException, CborDeserializationException { 149 | //Signer 1 sign the transaction 150 | Transaction signer1Txn = signer1.sign(transaction); 151 | 152 | //Signer 2 sign the transaction 153 | Transaction signer2Txn = signer2.sign(transaction); 154 | 155 | //Get witness from signer1 signed txn and signer2 signed transaction and add to witnesses 156 | //transaction.setValid(true); //Set the transaction validity to true. 157 | transaction.getWitnessSet().getVkeyWitnesses().add(signer1Txn.getWitnessSet().getVkeyWitnesses().get(0)); 158 | transaction.getWitnessSet().getVkeyWitnesses().add(signer2Txn.getWitnessSet().getVkeyWitnesses().get(0)); 159 | 160 | return transaction.serializeToHex(); 161 | } 162 | 163 | class ReadOnlyAccount extends Account { 164 | private String address; 165 | 166 | public ReadOnlyAccount(String address) { 167 | this.address = address; 168 | } 169 | 170 | @Override 171 | public String baseAddress() { 172 | return address; 173 | } 174 | } 175 | 176 | @Test 177 | public void run() throws AddressExcepion, CborSerializationException, ApiException, CborDeserializationException { 178 | MultiWitnessWithPaymentTransaction multiWitnessWithPaymentTransaction = new MultiWitnessWithPaymentTransaction(); 179 | multiWitnessWithPaymentTransaction.transfer(); 180 | } 181 | } 182 | -------------------------------------------------------------------------------- /src/test/java/com/bloxbean/cardano/client/example/MultisigMultiPartyDistribution.java: -------------------------------------------------------------------------------- 1 | package com.bloxbean.cardano.client.example; 2 | 3 | import com.bloxbean.cardano.client.account.Account; 4 | import com.bloxbean.cardano.client.address.AddressProvider; 5 | import com.bloxbean.cardano.client.api.exception.ApiException; 6 | import com.bloxbean.cardano.client.api.model.Result; 7 | import com.bloxbean.cardano.client.cip.cip20.MessageMetadata; 8 | import com.bloxbean.cardano.client.common.model.Networks; 9 | import com.bloxbean.cardano.client.crypto.VerificationKey; 10 | import com.bloxbean.cardano.client.exception.CborSerializationException; 11 | import com.bloxbean.cardano.client.function.Output; 12 | import com.bloxbean.cardano.client.function.TxBuilder; 13 | import com.bloxbean.cardano.client.function.TxBuilderContext; 14 | import com.bloxbean.cardano.client.function.TxSigner; 15 | import com.bloxbean.cardano.client.function.helper.AuxDataProviders; 16 | import com.bloxbean.cardano.client.function.helper.BalanceTxBuilders; 17 | import com.bloxbean.cardano.client.function.helper.InputBuilders; 18 | import com.bloxbean.cardano.client.function.helper.SignerProviders; 19 | import com.bloxbean.cardano.client.transaction.spec.Transaction; 20 | import com.bloxbean.cardano.client.transaction.spec.script.ScriptAll; 21 | import com.bloxbean.cardano.client.transaction.spec.script.ScriptPubkey; 22 | import org.junit.jupiter.api.Test; 23 | 24 | import static com.bloxbean.cardano.client.common.ADAConversionUtil.adaToLovelace; 25 | import static com.bloxbean.cardano.client.common.CardanoConstants.LOVELACE; 26 | import static org.junit.jupiter.api.Assertions.assertTrue; 27 | 28 | public class MultisigMultiPartyDistribution extends BaseTest { 29 | private String mnemonicA = "day witness total swallow soul digital teach all emotion gate fly toward gentle worry bicycle nurse proud milk search lucky twelve trap elder bitter"; 30 | private String mnemonicB = "spice addict bubble city truly cage debris pig smile away enhance cereal dice cotton nominee now alcohol health exclude depend stumble glide observe donate"; 31 | private String mnemonicC = "method payment either organ brave orphan zero dismiss more avoid abuse budget end radar ship drink input neutral leisure glad sentence mobile skin begin"; 32 | 33 | private String addressD = "addr_test1qqtxrmaw9ljc67jup0p3qa98hs6taaqh7vm7j5wrp5xdkwn27lrqsdpyfnhjrnlfx0as3nqz5ex94lfsj6u5lrll5yvqpn6rt8"; 34 | private String addressE = "addr_test1qqc23365wjfapsly5drw2md9paynamw7hs4nnm8k545gcwjrc7ugd6mcsgfc29qyak4dvtjmss8xewfaeal77jdrnxpsujk2h5"; 35 | private String addressF = "addr_test1qpk54sjd6xj823c2d6kmps84jacr933ymq92pf0xnh5lnt27wqtc8xnkda520vnwmgalzl3guxghyy9q2q07grgrm28sh9gld4"; 36 | 37 | private Account senderA; 38 | private Account senderB; 39 | private Account senderC; 40 | 41 | private String nativeScriptAddress; 42 | private ScriptAll scriptAll; 43 | 44 | public MultisigMultiPartyDistribution() throws CborSerializationException { 45 | senderA = new Account(Networks.testnet(), mnemonicA); 46 | senderB = new Account(Networks.testnet(), mnemonicB); 47 | senderC = new Account(Networks.testnet(), mnemonicC); 48 | 49 | //Create native script with ScriptAll 50 | ScriptPubkey scriptPubkeyA = ScriptPubkey.create(VerificationKey.create(senderA.publicKeyBytes())); 51 | ScriptPubkey scriptPubkeyB = ScriptPubkey.create(VerificationKey.create(senderB.publicKeyBytes())); 52 | ScriptPubkey scriptPubkeyC = ScriptPubkey.create(VerificationKey.create(senderC.publicKeyBytes())); 53 | 54 | scriptAll = new ScriptAll(); 55 | scriptAll.addScript(scriptPubkeyA); 56 | scriptAll.addScript(scriptPubkeyB); 57 | scriptAll.addScript(scriptPubkeyC); 58 | 59 | System.out.println(scriptAll); 60 | nativeScriptAddress = AddressProvider.getEntAddress(scriptAll, Networks.testnet()).toBech32(); 61 | System.out.println("Multisig address : " + nativeScriptAddress); 62 | } 63 | 64 | public void transfer() throws CborSerializationException, ApiException { 65 | 66 | //Define outputs 67 | //Output for D 68 | Output outputD = Output.builder() 69 | .address(addressD) 70 | .assetName(LOVELACE) 71 | .qty(adaToLovelace(2)).build(); 72 | 73 | //Output for E 74 | Output outputE = Output.builder() 75 | .address(addressE) 76 | .assetName(LOVELACE) 77 | .qty(adaToLovelace(3)).build(); 78 | 79 | //Output for F 80 | Output outputF = Output.builder() 81 | .address(addressF) 82 | .assetName(LOVELACE) 83 | .qty(adaToLovelace(4)).build(); 84 | 85 | //Define Tx 86 | TxBuilder txBuilder = outputD.outputBuilder() 87 | .and(outputE.outputBuilder()) 88 | .and(outputF.outputBuilder()) 89 | .buildInputs(InputBuilders.createFromSender(nativeScriptAddress, nativeScriptAddress)) 90 | .andThen(AuxDataProviders.metadataProvider(MessageMetadata.create().add("Multisig script txn (A,B,C) ---> (D,E,F) using CCL"))) 91 | .andThen((context, transaction) -> { 92 | //Add script to the witness. Need to find a way to inject through another helper later instead of manual step 93 | transaction.getWitnessSet().getNativeScripts().add(scriptAll); 94 | }) 95 | .andThen(BalanceTxBuilders.balanceTx(nativeScriptAddress, 3)); 96 | 97 | //Define singers 98 | TxSigner txSigner = SignerProviders.signerFrom(senderA, senderB, senderC); 99 | 100 | //Build and sign multisig txn 101 | Transaction signedTxn = TxBuilderContext.init(utxoSupplier, protocolParamsSupplier) 102 | .buildAndSign(txBuilder, txSigner); 103 | 104 | Result result = transactionService.submitTransaction(signedTxn.serialize()); 105 | 106 | System.out.println(result); 107 | assertTrue(result.isSuccessful()); 108 | waitForTransactionHash(result); 109 | } 110 | 111 | @Test 112 | public void run() throws Exception { 113 | MultisigMultiPartyDistribution multisigMultiPartyDistribution = new MultisigMultiPartyDistribution(); 114 | multisigMultiPartyDistribution.transfer(); 115 | } 116 | } 117 | -------------------------------------------------------------------------------- /src/test/java/com/bloxbean/cardano/client/example/SignVerifyDataTest.java: -------------------------------------------------------------------------------- 1 | package com.bloxbean.cardano.client.example; 2 | 3 | import com.bloxbean.cardano.client.account.Account; 4 | import com.bloxbean.cardano.client.address.Address; 5 | import com.bloxbean.cardano.client.cip.cip30.CIP30DataSigner; 6 | import com.bloxbean.cardano.client.cip.cip30.DataSignature; 7 | import com.bloxbean.cardano.client.common.model.Networks; 8 | import org.junit.jupiter.api.Test; 9 | 10 | public class SignVerifyDataTest { 11 | 12 | @Test 13 | public void run() throws Exception { 14 | new SignVerifyDataTest().verifyNamiSignature(); 15 | // new SignVerifyDataTest().signAndVerify(); 16 | } 17 | 18 | public void verifyNamiSignature() throws Exception { 19 | String json = "{\n" + 20 | " \"signature\" : \"845846a2012767616464726573735839003175d03902583e82037438cc86732f6e539f803f9a8b2d4ee164b9d0c77e617030631811f60a1f8a8be26d65a57ff71825b336cc6b76361da166686173686564f44b48656c6c6f20576f726c64584036c2151e1230364b0bf9e40cb65dbdca4c5decf4187e3c5511945d410ea59a1e733b5e68178c234979053ed75b0226ba826fb951c5a79fabf10bddcabda8dc05\",\n" + 21 | " \"key\" : \"a4010103272006215820a5f73966e73d0bb9eadc75c5857eafd054a0202d716ac6dde00303ee9c0019e3\"\n" + 22 | "}"; 23 | 24 | //Load signature 25 | DataSignature dataSignature = DataSignature.from(json); 26 | //verify 27 | boolean verified = CIP30DataSigner.INSTANCE.verify(dataSignature); 28 | 29 | System.out.println("Verification Status: " + verified); 30 | } 31 | 32 | public void signAndVerify() throws Exception { 33 | String mnemonic = "nice orient enjoy teach jump office alert inquiry apart unaware seat tumble unveil device have bullet morning eyebrow time image embody divide version uniform"; 34 | Account account = new Account(Networks.testnet(), mnemonic); 35 | 36 | byte[] payload = "Hello".getBytes(); 37 | 38 | //Sign 39 | Address address = new Address(account.baseAddress()); 40 | DataSignature dataSignature = CIP30DataSigner.INSTANCE.signData(address.getBytes(), payload, account); 41 | 42 | //Verify 43 | boolean verified = CIP30DataSigner.INSTANCE.verify(dataSignature); 44 | 45 | System.out.println("Verification status: " + verified); 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /src/test/java/com/bloxbean/cardano/client/example/TransactionSigningWithoutBackend.java: -------------------------------------------------------------------------------- 1 | package com.bloxbean.cardano.client.example; 2 | 3 | import com.bloxbean.cardano.client.account.Account; 4 | import com.bloxbean.cardano.client.common.model.Networks; 5 | import com.bloxbean.cardano.client.exception.CborDeserializationException; 6 | import com.bloxbean.cardano.client.exception.CborSerializationException; 7 | import com.bloxbean.cardano.client.transaction.spec.*; 8 | import org.junit.jupiter.api.Test; 9 | 10 | import java.math.BigInteger; 11 | import java.util.Arrays; 12 | import java.util.List; 13 | 14 | //Sample : How to build and sign a Transaction manually 15 | public class TransactionSigningWithoutBackend { 16 | 17 | @Test 18 | public void run() throws CborSerializationException, CborDeserializationException { 19 | createAndSignTransaction(); 20 | } 21 | 22 | public static void createAndSignTransaction() throws CborSerializationException, CborDeserializationException { 23 | 24 | String senderMnemonic = "deny anchor replace squirrel type early local kitten dinner burst afford room hub cool diary buyer believe frequent evoke churn process pupil exotic notice"; 25 | Account sender = new Account(Networks.testnet(), senderMnemonic); 26 | String receiverAddress = "addr_test1qr2y2yf2lwj0xn2nrhmyqe26t52twp06cp4lm2r62undytvj5ggkj79y993ds6645ewwfus90su92j554u2294wtm93s25m8cz"; 27 | 28 | //Find utxos first and then create inputs 29 | List inputs = Arrays.asList( 30 | TransactionInput.builder() 31 | .transactionId("2a95e941761fa6187d0eaeec3ea0a8f68f439ec806ebb0e4550e640e8e0d189c") 32 | .index(0).build() 33 | ); 34 | 35 | TransactionOutput output = TransactionOutput 36 | .builder() 37 | .address(receiverAddress) 38 | .value(new Value(BigInteger.valueOf(20000000L), null)) 39 | .build(); 40 | 41 | TransactionOutput change = TransactionOutput 42 | .builder() 43 | .address(sender.baseAddress()) 44 | .value(new Value(BigInteger.valueOf(400000000L), null)) 45 | .build(); 46 | 47 | List outputs = Arrays.asList(output, change); 48 | 49 | //Create the transaction body with dummy fee 50 | TransactionBody body = TransactionBody.builder() 51 | .inputs(inputs) 52 | .outputs(outputs) 53 | .ttl(230000003) 54 | .fee(BigInteger.valueOf(170000)) 55 | .build(); 56 | 57 | Transaction transaction = Transaction.builder() 58 | .body(body) 59 | .build(); 60 | 61 | //Sign the transaction. so that we get the actual size of the transaction to calculate the fee 62 | Transaction signTxn = sender.sign(transaction); //cbor encoded bytes in Hex format 63 | 64 | //Calculate fees 65 | byte[] signTxnBytes = signTxn.serialize(); 66 | //Current protocol parameters in Cardano 67 | Integer minFeeA = 44; 68 | Integer minFeeB = 155381; 69 | BigInteger estimatedFee = BigInteger.valueOf((minFeeA * signTxnBytes.length) + minFeeB); 70 | 71 | //Now set the actual fee 72 | transaction.getBody().setFee(estimatedFee); 73 | 74 | //Sign the final transaction with correct fee 75 | signTxn = sender.sign(transaction); //cbor encoded bytes in Hex 76 | byte[] signedCBorBytes = signTxn.serialize(); 77 | 78 | System.out.println(signTxn); 79 | System.out.println(signedCBorBytes.length); 80 | 81 | //You can also deserialize the txn from the cbor bytes 82 | Transaction txn = Transaction.deserialize(signedCBorBytes); 83 | 84 | //Submit signedCBorBytes to Cardano Node 85 | 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /src/test/java/com/bloxbean/cardano/client/example/TransferFromMultisigScriptAddress.java: -------------------------------------------------------------------------------- 1 | package com.bloxbean.cardano.client.example; 2 | 3 | import com.bloxbean.cardano.client.account.Account; 4 | import com.bloxbean.cardano.client.api.exception.ApiException; 5 | import com.bloxbean.cardano.client.api.model.Result; 6 | import com.bloxbean.cardano.client.api.model.Utxo; 7 | import com.bloxbean.cardano.client.coinselection.UtxoSelectionStrategy; 8 | import com.bloxbean.cardano.client.coinselection.impl.DefaultUtxoSelectionStrategyImpl; 9 | import com.bloxbean.cardano.client.common.model.Networks; 10 | import com.bloxbean.cardano.client.exception.CborDeserializationException; 11 | import com.bloxbean.cardano.client.exception.CborSerializationException; 12 | import com.bloxbean.cardano.client.transaction.spec.*; 13 | import com.bloxbean.cardano.client.transaction.spec.script.ScriptAtLeast; 14 | import com.bloxbean.cardano.client.transaction.spec.script.ScriptPubkey; 15 | import com.bloxbean.cardano.client.util.HexUtil; 16 | import org.junit.jupiter.api.Test; 17 | 18 | import java.io.IOException; 19 | import java.math.BigInteger; 20 | import java.util.ArrayList; 21 | import java.util.Arrays; 22 | import java.util.Collections; 23 | import java.util.List; 24 | 25 | import static com.bloxbean.cardano.client.common.CardanoConstants.LOVELACE; 26 | import static com.bloxbean.cardano.client.common.CardanoConstants.ONE_ADA; 27 | import static org.junit.jupiter.api.Assertions.assertTrue; 28 | 29 | public class TransferFromMultisigScriptAddress extends BaseTest { 30 | 31 | @Test 32 | public void run() throws CborDeserializationException, CborSerializationException, ApiException, IOException { 33 | TransferFromMultisigScriptAddress transferFromMultisigScriptAddress = new TransferFromMultisigScriptAddress(); 34 | transferFromMultisigScriptAddress.transfer(); 35 | } 36 | 37 | public TransferFromMultisigScriptAddress() { 38 | 39 | } 40 | 41 | public void transfer() throws ApiException, CborSerializationException, CborDeserializationException, IOException { 42 | String multisigScriptAddr = "addr_test1wzchaw4vxmmpws44ffh99eqzmlg6wr3swg36pqug8xn20ygxgqher"; 43 | String receiverAddress = "addr_test1qr2y2yf2lwj0xn2nrhmyqe26t52twp06cp4lm2r62undytvj5ggkj79y993ds6645ewwfus90su92j554u2294wtm93s25m8cz"; 44 | 45 | BigInteger amountToTransfer = ONE_ADA.multiply(BigInteger.valueOf(7)); 46 | 47 | //Find required utxos 48 | UtxoSelectionStrategy utxoSelectionStrategy = new DefaultUtxoSelectionStrategyImpl(utxoSupplier); 49 | List utxos = utxoSelectionStrategy.selectUtxos(multisigScriptAddr, LOVELACE, 50 | amountToTransfer.add(ONE_ADA.multiply(BigInteger.valueOf(2))), Collections.EMPTY_SET); //transfer amount + 2 ADA to cover fee and min ada 51 | 52 | //Find utxos first and then create inputs 53 | List inputs = new ArrayList<>(); 54 | for (Utxo utxo : utxos) { 55 | TransactionInput input = TransactionInput.builder() 56 | .transactionId(utxo.getTxHash()) 57 | .index(utxo.getOutputIndex()).build(); 58 | inputs.add(input); 59 | } 60 | 61 | TransactionOutput output = TransactionOutput 62 | .builder() 63 | .address(receiverAddress) 64 | .value(new Value(amountToTransfer, null)) 65 | .build(); 66 | 67 | TransactionOutput change = TransactionOutput 68 | .builder() 69 | .address(multisigScriptAddr) 70 | .value(Value.builder() 71 | .coin(BigInteger.ZERO).build() 72 | ) 73 | .build(); 74 | utxos.forEach(utxo -> copyUtxoValuesToChangeOutput(change, utxo)); 75 | 76 | List outputs = Arrays.asList(output, change); 77 | 78 | //Create the transaction body with dummy fee 79 | TransactionBody body = TransactionBody.builder() 80 | .inputs(inputs) 81 | .outputs(outputs) 82 | .ttl(getTtl()) 83 | .fee(BigInteger.valueOf(170000)) 84 | .build(); 85 | 86 | //script file 87 | //TODO Not able to deserialize from file through ObjectMapper as there is no default constructor in ScriptAtLeast class. 88 | // This will be fixed in future release 89 | // InputStream ins = this.getClass().getClassLoader().getResourceAsStream("multisig.script"); 90 | // ScriptAtLeast multiSigScript = objectMapper.readValue(ins, ScriptAtLeast.class); 91 | 92 | ScriptAtLeast multiSigScript = getMultisigScript(); 93 | TransactionWitnessSet witnessSet = new TransactionWitnessSet(); 94 | witnessSet.getNativeScripts().add(multiSigScript); 95 | 96 | Transaction transaction = Transaction.builder() 97 | .body(body) 98 | .witnessSet(witnessSet) 99 | .build(); 100 | 101 | //Signers 102 | String signerAcc1Mnemonic = "around submit turtle canvas friend remind push vehicle debate drop blouse piece obvious crane tone avoid aspect power milk eye brand cradle tide wrist"; 103 | String signerAcc2Mnemonic = "prison glide olympic diamond rib payment crucial ski vintage example dinner matrix cruise upper antenna surge drink divorce brother half figure skate jar stand"; 104 | 105 | Account signer1 = new Account(Networks.testnet(), signerAcc1Mnemonic); 106 | Account signer2 = new Account(Networks.testnet(), signerAcc2Mnemonic); 107 | 108 | //Sign the transaction. so that we get the actual size of the transaction to calculate the fee 109 | Transaction signTxn = signer1.sign(transaction); //cbor encoded bytes in Hex format 110 | signTxn = signer2.sign(signTxn); 111 | 112 | BigInteger fee = feeCalculationService.calculateFee(signTxn); 113 | 114 | //Update fee in transaction body 115 | body.setFee(fee); 116 | 117 | //Final change amount after amountToTransfer + fee 118 | BigInteger finalChangeAmt = change.getValue().getCoin().subtract(amountToTransfer.add(fee)); 119 | change.getValue().setCoin(finalChangeAmt); 120 | 121 | //TODO Sign the transaction by signer1 to add witness and then sign the signed transaction again by signer2 to append signer2's witness 122 | String finalSignedTxn = signTransactionOneAfterAnother(transaction, signer1, signer2); 123 | 124 | //TODO Uncomment if want to sign independently and then assemble. Orignal transaction can be serialized and distribute to signing party 125 | // String finalSignedTxn = signOriginalTransactionBySigner1AndSigner2AndThenAssemble(transaction, signer1, signer2); 126 | 127 | Result result = transactionService.submitTransaction(HexUtil.decodeHexString(finalSignedTxn)); 128 | 129 | System.out.println(result); 130 | assertTrue(result.isSuccessful()); 131 | if (result.isSuccessful()) 132 | waitForTransactionHash(result); 133 | else 134 | System.out.println("Transaction failed : " + result); 135 | } 136 | 137 | /** 138 | * Sign the transaction first by signer1 and then sign the signed transactioin by signer2 139 | * 140 | * @param transaction 141 | * @param signer1 142 | * @param signer2 143 | * @return 144 | * @throws CborSerializationException 145 | */ 146 | private String signTransactionOneAfterAnother(Transaction transaction, Account signer1, Account signer2) throws CborSerializationException { 147 | Transaction signedTxn = signer1.sign(transaction); 148 | signedTxn = signer2.sign(signedTxn); 149 | 150 | return signedTxn.serializeToHex(); 151 | } 152 | 153 | private String signOriginalTransactionBySigner1AndSigner2AndThenAssemble(Transaction transaction, Account signer1, Account signer2) 154 | throws CborSerializationException, CborDeserializationException { 155 | //Signer 1 sign the transaction 156 | Transaction signer1Txn = signer1.sign(transaction); 157 | 158 | //Signer 2 sign the transaction 159 | Transaction signer2Txn = signer2.sign(transaction); 160 | 161 | //Get witness from signer1 signed txn and signer2 signed transaction and add to witnesses 162 | transaction.setValid(true); //Set the transaction validity to true. 163 | transaction.getWitnessSet().getVkeyWitnesses().add(signer1Txn.getWitnessSet().getVkeyWitnesses().get(0)); 164 | transaction.getWitnessSet().getVkeyWitnesses().add(signer2Txn.getWitnessSet().getVkeyWitnesses().get(0)); 165 | 166 | return transaction.serializeToHex(); 167 | } 168 | 169 | public ScriptAtLeast getMultisigScript() { 170 | ScriptPubkey key1 = new ScriptPubkey(); 171 | key1.setKeyHash("74cfebcf5e97474d7b89c862d7ee7cff22efbb032d4133a1b84cbdcd"); 172 | 173 | ScriptPubkey key2 = new ScriptPubkey(); 174 | key2.setKeyHash("710ee487dbbcdb59b5841a00d1029a56a407c722b3081c02470b516d"); 175 | 176 | ScriptPubkey key3 = new ScriptPubkey(); 177 | key3.setKeyHash("beed26382ec96254a6714928c3c5bb8227abecbbb095cfeab9fb2dd1"); 178 | 179 | ScriptAtLeast scriptAtLeast = new ScriptAtLeast(2); 180 | scriptAtLeast.addScript(key1) 181 | .addScript(key2) 182 | .addScript(key3); 183 | 184 | return scriptAtLeast; 185 | } 186 | 187 | } 188 | -------------------------------------------------------------------------------- /src/test/java/com/bloxbean/cardano/client/example/TransferTokenTest.java: -------------------------------------------------------------------------------- 1 | package com.bloxbean.cardano.client.example; 2 | 3 | import com.bloxbean.cardano.client.account.Account; 4 | import com.bloxbean.cardano.client.api.exception.ApiException; 5 | import com.bloxbean.cardano.client.api.helper.model.TransactionResult; 6 | import com.bloxbean.cardano.client.api.model.Result; 7 | import com.bloxbean.cardano.client.common.model.Networks; 8 | import com.bloxbean.cardano.client.exception.AddressExcepion; 9 | import com.bloxbean.cardano.client.exception.CborSerializationException; 10 | import com.bloxbean.cardano.client.transaction.model.PaymentTransaction; 11 | import com.bloxbean.cardano.client.transaction.model.TransactionDetailsParams; 12 | import org.junit.jupiter.api.Test; 13 | 14 | import java.math.BigInteger; 15 | 16 | import static org.junit.jupiter.api.Assertions.assertTrue; 17 | 18 | public class TransferTokenTest extends BaseTest { 19 | 20 | @Test 21 | public void run() throws AddressExcepion, ApiException, CborSerializationException { 22 | new TransferTokenTest().transfer(); 23 | } 24 | 25 | public void transfer() throws ApiException, AddressExcepion, CborSerializationException { 26 | 27 | String senderMnemonic = "kit color frog trick speak employ suit sort bomb goddess jewel primary spoil fade person useless measure manage warfare reduce few scrub beyond era"; 28 | Account sender = new Account(Networks.testnet(), senderMnemonic); 29 | 30 | String receiver = "addr_test1qqwpl7h3g84mhr36wpetk904p7fchx2vst0z696lxk8ujsjyruqwmlsm344gfux3nsj6njyzj3ppvrqtt36cp9xyydzqzumz82"; 31 | 32 | PaymentTransaction paymentTransaction = 33 | PaymentTransaction.builder() 34 | .sender(sender) 35 | .receiver(receiver) 36 | .amount(BigInteger.valueOf(3000)) 37 | .unit("57fca08abbaddee36da742a839f7d83a7e1d2419f1507fcbf3916522534245525259") 38 | .build(); 39 | 40 | long ttl = blockService.getLatestBlock().getValue().getSlot() + 1000; 41 | TransactionDetailsParams detailsParams = 42 | TransactionDetailsParams.builder() 43 | .ttl(ttl) 44 | .build(); 45 | 46 | BigInteger fee = feeCalculationService.calculateFee(paymentTransaction, detailsParams 47 | , null); 48 | 49 | paymentTransaction.setFee(fee); 50 | 51 | Result result = transactionHelperService.transfer(paymentTransaction, detailsParams); 52 | 53 | if (result.isSuccessful()) 54 | System.out.println("Transaction Id: " + result.getValue()); 55 | else 56 | System.out.println("Transaction failed: " + result); 57 | 58 | assertTrue(result.isSuccessful()); 59 | waitForTransaction(result); 60 | } 61 | 62 | } 63 | -------------------------------------------------------------------------------- /src/test/java/com/bloxbean/cardano/client/example/cip8/CIP8CBORParser.java: -------------------------------------------------------------------------------- 1 | package com.bloxbean.cardano.client.example.cip8; 2 | 3 | import co.nstant.in.cbor.CborDecoder; 4 | import co.nstant.in.cbor.model.*; 5 | import com.bloxbean.cardano.client.common.cbor.CborSerializationUtil; 6 | import com.bloxbean.cardano.client.crypto.CryptoException; 7 | import com.bloxbean.cardano.client.util.HexUtil; 8 | import net.i2p.crypto.eddsa.EdDSAEngine; 9 | import net.i2p.crypto.eddsa.spec.EdDSANamedCurveTable; 10 | import net.i2p.crypto.eddsa.spec.EdDSAParameterSpec; 11 | import net.i2p.crypto.eddsa.spec.EdDSAPublicKeySpec; 12 | import org.junit.jupiter.api.Test; 13 | 14 | import java.security.MessageDigest; 15 | import java.security.Signature; 16 | import java.util.List; 17 | 18 | import static org.junit.jupiter.api.Assertions.assertTrue; 19 | 20 | public class CIP8CBORParser { 21 | private static final EdDSAParameterSpec spec = EdDSANamedCurveTable.getByName(EdDSANamedCurveTable.ED_25519); 22 | 23 | @Test 24 | public void parse() throws Exception { 25 | //Payload = "hello" 26 | String coseSignMsgInHex = "845869a30127045820674d11e432450118d70ea78673d5e31d5cc1aec63de0ff6284784876544be3406761646472657373583901d2eb831c6cad4aba700eb35f86966fbeff19d077954430e32ce65e8da79a3abe84f4ce817fad066acc1435be2ffc6bd7dce2ec1cc6cca6cba166686173686564f44568656c6c6f5840a3b5acd99df5f3b5e4449c5a116078e9c0fcfc126a4d4e2f6a9565f40b0c77474cafd89845e768fae3f6eec0df4575fcfe7094672c8c02169d744b415c617609"; 27 | 28 | //CBOR parsing starts here ################### 29 | List dataItemList = CborDecoder.decode(HexUtil.decodeHexString(coseSignMsgInHex)); 30 | 31 | List topArray = ((Array) dataItemList.get(0)).getDataItems(); 32 | ByteString protectedHeaderBs = (ByteString) topArray.get(0); 33 | Map unprotectedMap = (Map) topArray.get(1); 34 | ByteString messageToSignBS = (ByteString) topArray.get(2); 35 | ByteString signatureArrayBS = (ByteString) topArray.get(3); 36 | 37 | byte[] message = messageToSignBS.getBytes(); 38 | byte[] signature = signatureArrayBS.getBytes(); 39 | 40 | System.out.println(new String(message)); 41 | 42 | //parse protected header map bytestring 43 | List protectedHeaderMapDIList = CborDecoder.decode(protectedHeaderBs.getBytes()); 44 | Map protectedHeaderMap = (Map) protectedHeaderMapDIList.get(0); 45 | 46 | ByteString publicKeyBS = (ByteString) protectedHeaderMap.get(new UnsignedInteger(4)); 47 | byte[] publicKeyBytes = publicKeyBS.getBytes(); 48 | 49 | ByteString addressBS = (ByteString)protectedHeaderMap.get(new UnicodeString("address")); 50 | System.out.println("Address >> " + HexUtil.encodeHexString(addressBS.getBytes())); 51 | //CBOR parsing ends her ################### 52 | 53 | //Create SignatureStructure. This is passed as message during signature verification 54 | Array sigStructArray = new Array(); 55 | sigStructArray.add(new UnicodeString("Signature1")); 56 | sigStructArray.add(protectedHeaderBs); 57 | sigStructArray.add(new ByteString(new byte[0])); 58 | sigStructArray.add(messageToSignBS); 59 | 60 | byte[] messageToVerify = CborSerializationUtil.serialize(sigStructArray); //serialize 61 | //End SignatureStructure 62 | 63 | boolean verified = verify(messageToVerify, signature, publicKeyBytes); 64 | System.out.println("Verification status >> " + verified); 65 | 66 | assertTrue(verified); 67 | } 68 | 69 | public boolean verify(byte[] message, byte[] signatureBytes, byte[] publicKeyBytes) { 70 | 71 | try{ 72 | net.i2p.crypto.eddsa.EdDSAPublicKey publicKey = new net.i2p.crypto.eddsa.EdDSAPublicKey(new EdDSAPublicKeySpec(publicKeyBytes, spec)); 73 | Signature signature = new EdDSAEngine(MessageDigest.getInstance(spec.getHashAlgorithm())); 74 | signature.initVerify(publicKey); 75 | signature.setParameter(EdDSAEngine.ONE_SHOT_MODE); 76 | signature.update(message); 77 | return signature.verify(signatureBytes); 78 | }catch(Exception e){ 79 | throw new CryptoException("Extended signing error", e); 80 | } 81 | } 82 | 83 | public static void main(String[] args) throws Exception { 84 | new CIP8CBORParser().parse(); 85 | } 86 | } 87 | -------------------------------------------------------------------------------- /src/test/java/com/bloxbean/cardano/client/example/derivation/AddressDerivationFromPublicKey.java: -------------------------------------------------------------------------------- 1 | package com.bloxbean.cardano.client.example.derivation; 2 | 3 | 4 | import com.bloxbean.cardano.client.account.Account; 5 | import com.bloxbean.cardano.client.address.Address; 6 | import com.bloxbean.cardano.client.address.AddressProvider; 7 | import com.bloxbean.cardano.client.common.model.Networks; 8 | import com.bloxbean.cardano.client.crypto.Bech32; 9 | import com.bloxbean.cardano.client.crypto.bip32.HdKeyGenerator; 10 | import com.bloxbean.cardano.client.crypto.bip32.key.HdPublicKey; 11 | import org.junit.jupiter.api.Test; 12 | 13 | import java.util.ArrayList; 14 | import java.util.List; 15 | 16 | import static org.assertj.core.api.Assertions.assertThat; 17 | 18 | /** 19 | * This class demonstrates how to derive multiple addresses (base and enterprise) from a given account level public key. 20 | * Derivation path according to CIP1852 m / purpose' / coin_type' / account' / role / index . Example: m / 1852' / 1815' / 0' / 0 / 0 21 | * As keys at role/index level are not hardened, they can be derived from the account level public key. 22 | */ 23 | public class AddressDerivationFromPublicKey { 24 | 25 | 26 | /** 27 | * Derive multiple addresses (base and enterprise) from a given account level public key. 28 | * Get the account level public key from your wallet. In Eternl wallet, you can get the account public key from "Wallet & Account Settings". 29 | * The following account pub key is taken from Eternl wallet. 30 | * 31 | * In the following method, we derive 20 base addresses and 20 enterprise addresses from the given wallet's account public key (account = 0) 32 | * @return 33 | */ 34 | public List deriveFromPublicKey() { 35 | 36 | // Account Key:0 (m/1852'/1815'/0') 37 | String accoutPubKey = "xpub1ytx7lt4rs28wehx47gt6xkyl8tphjy9lznpjh7wy3jpdnuveegq4sstrxvvhl0elm9aulpzjhfkvfjtvncp3xnstd6ypa2m9my9kl9cmprz00"; 38 | byte[] accountPubKeyBytes = Bech32.decode(accoutPubKey).data; 39 | HdPublicKey accountKey = HdPublicKey.fromBytes(accountPubKeyBytes); 40 | 41 | HdKeyGenerator hdKeyGenerator = new HdKeyGenerator(); 42 | 43 | //Derive Stake Key and Address 44 | //role = 2, staking key (m/1852'/1815'/0'/2/0) 45 | HdPublicKey stakeRolePublicKey = hdKeyGenerator.getChildPublicKey(accountKey, 2); 46 | HdPublicKey stakePublicKey = hdKeyGenerator.getChildPublicKey(stakeRolePublicKey, 0); 47 | Address stakeAddress = AddressProvider.getRewardAddress(stakePublicKey, Networks.testnet()); 48 | 49 | System.out.println("Account Public Key: " + accoutPubKey); 50 | System.out.println("Stake Address: " + stakeAddress.toBech32()); 51 | System.out.println("------------------------------------------------"); 52 | 53 | //Derive base/ent addresses from account key at index 0 to 19 54 | //Role=0 55 | HdPublicKey role0Key = hdKeyGenerator.getChildPublicKey(accountKey, 0); 56 | 57 | //(m/1852'/1815'/0'/0/i) where i=0 to 19 58 | List addresses = new ArrayList<>(); 59 | for (int i=0; i<20; i++) { 60 | HdPublicKey indexKey = hdKeyGenerator.getChildPublicKey(role0Key, i); 61 | Address indexAddress = AddressProvider.getBaseAddress(indexKey, stakePublicKey, Networks.testnet()); 62 | Address entAddress = AddressProvider.getEntAddress(indexKey, Networks.testnet()); 63 | 64 | System.out.println("Derivation Path: m/1852'/1815'/0'/" + i); 65 | System.out.println("BaseAddress:" + indexAddress.toBech32()); 66 | System.out.println("Enterprise Address: " + entAddress.toBech32()); 67 | System.out.println("------------------------------------------------"); 68 | 69 | addresses.add(indexAddress.toBech32()); 70 | } 71 | 72 | return addresses; 73 | } 74 | 75 | //Test method to verify derived addresses from account key with mnemonic derived addresses 76 | @Test 77 | public void verifyAccountKeyAddressWithMnemonicDerivedAddresses() { 78 | String originalMnemonic = "skull imitate fatal brain extra stem dress until patrol yellow rule mobile case acoustic invest raw second vacuum that average huge artwork dilemma claw"; 79 | 80 | var accountKeyDerivedAddresses = deriveFromPublicKey(); 81 | 82 | List addresses = new ArrayList<>(); 83 | for (int i=0; i<20; i++) { 84 | Account account = new Account(Networks.testnet(), originalMnemonic, i); 85 | addresses.add(account.baseAddress()); 86 | } 87 | 88 | assertThat(addresses).containsAll(accountKeyDerivedAddresses); 89 | 90 | } 91 | 92 | public static void main(String[] args) { 93 | AddressDerivationFromPublicKey publicKeyDerivation = new AddressDerivationFromPublicKey(); 94 | publicKeyDerivation.deriveFromPublicKey(); 95 | } 96 | } 97 | -------------------------------------------------------------------------------- /src/test/java/com/bloxbean/cardano/client/example/function/TransferTransactionMultiSenderMultiReceiverTest.java: -------------------------------------------------------------------------------- 1 | package com.bloxbean.cardano.client.example.function; 2 | 3 | import com.bloxbean.cardano.client.account.Account; 4 | import com.bloxbean.cardano.client.api.exception.ApiException; 5 | import com.bloxbean.cardano.client.api.model.Result; 6 | import com.bloxbean.cardano.client.cip.cip20.MessageMetadata; 7 | import com.bloxbean.cardano.client.common.model.Networks; 8 | import com.bloxbean.cardano.client.example.BaseTest; 9 | import com.bloxbean.cardano.client.exception.AddressExcepion; 10 | import com.bloxbean.cardano.client.exception.CborSerializationException; 11 | import com.bloxbean.cardano.client.function.Output; 12 | import com.bloxbean.cardano.client.function.TxBuilder; 13 | import com.bloxbean.cardano.client.function.TxBuilderContext; 14 | import com.bloxbean.cardano.client.transaction.spec.Transaction; 15 | import org.junit.jupiter.api.Test; 16 | 17 | import static com.bloxbean.cardano.client.common.ADAConversionUtil.adaToLovelace; 18 | import static com.bloxbean.cardano.client.common.CardanoConstants.LOVELACE; 19 | import static com.bloxbean.cardano.client.function.helper.AuxDataProviders.metadataProvider; 20 | import static com.bloxbean.cardano.client.function.helper.BalanceTxBuilders.balanceTx; 21 | import static com.bloxbean.cardano.client.function.helper.InputBuilders.createFromSender; 22 | import static com.bloxbean.cardano.client.function.helper.SignerProviders.signerFrom; 23 | import static org.junit.jupiter.api.Assertions.assertTrue; 24 | 25 | public class TransferTransactionMultiSenderMultiReceiverTest extends BaseTest { 26 | 27 | @Test 28 | public void run() throws AddressExcepion, CborSerializationException, ApiException { 29 | new TransferTransactionMultiSenderMultiReceiverTest().transfer(); 30 | } 31 | 32 | public void transfer() throws CborSerializationException, ApiException, AddressExcepion { 33 | String senderMnemonic = "kit color frog trick speak employ suit sort bomb goddess jewel primary spoil fade person useless measure manage warfare reduce few scrub beyond era"; 34 | Account sender = new Account(Networks.testnet(), senderMnemonic); 35 | String senderAddress = sender.baseAddress(); 36 | 37 | String sender2Mnemonic = "essence pilot click armor alpha noise mixture soldier able advice multiply inject ticket pride airport uncover honey desert curtain sun true toast valve half"; 38 | Account sender2 = new Account(Networks.testnet(), sender2Mnemonic); 39 | String sender2Address = sender2.baseAddress(); 40 | 41 | String receiverAddress1 = "addr_test1qqwpl7h3g84mhr36wpetk904p7fchx2vst0z696lxk8ujsjyruqwmlsm344gfux3nsj6njyzj3ppvrqtt36cp9xyydzqzumz82"; 42 | String receiverAddress2 = "addr_test1qqqvjp4ffcdqg3fmx0k8rwamnn06wp8e575zcv8d0m3tjn2mmexsnkxp7az774522ce4h3qs4tjp9rxjjm46qf339d9sk33rqn"; 43 | String receiver3Address3 = "addr_test1qznuey056aczwykcs3t90yjm8up24rjda5vm7czs6uycueqasp723sny4y96tnzl8smzc7z3jmh0sxpu5hy59u50wp3q3mwvly"; 44 | 45 | Output output1 = Output.builder() 46 | .address(receiverAddress1) 47 | .assetName(LOVELACE) 48 | .qty(adaToLovelace(2.1)) 49 | .build(); 50 | 51 | Output output2 = Output.builder() 52 | .address(receiverAddress2) 53 | .assetName(LOVELACE) 54 | .qty(adaToLovelace(2.1)) 55 | .build(); 56 | 57 | Output output3 = Output.builder() 58 | .address(receiver3Address3) 59 | .assetName(LOVELACE) 60 | .qty(adaToLovelace(2.1)) 61 | .build(); 62 | 63 | MessageMetadata metadata = MessageMetadata.create() 64 | .add("This is a sample transfer transaction") 65 | .add("with multiple receiver and senders"); 66 | 67 | TxBuilder txBuilder = (output1.outputBuilder() 68 | .and(output2.outputBuilder()) 69 | .and(output3.outputBuilder()) 70 | .buildInputs(createFromSender(senderAddress, senderAddress)) 71 | ).andThen(output1.outputBuilder() 72 | .and(output2.outputBuilder()) 73 | .and(output3.outputBuilder()) 74 | .buildInputs(createFromSender(sender2Address, sender2Address)) 75 | ) 76 | .andThen(metadataProvider(metadata)) 77 | .andThen(balanceTx(senderAddress, 2)); 78 | 79 | Transaction signedTransaction = TxBuilderContext.init(utxoSupplier, protocolParamsSupplier) 80 | .buildAndSign(txBuilder, signerFrom(sender, sender2)); 81 | 82 | Result result = transactionService.submitTransaction(signedTransaction.serialize()); 83 | System.out.println(result); 84 | 85 | if (result.isSuccessful()) 86 | System.out.println("Transaction Id: " + result.getValue()); 87 | else 88 | System.out.println("Transaction failed: " + result); 89 | 90 | assertTrue(result.isSuccessful()); 91 | waitForTransactionHash(result); 92 | } 93 | } 94 | -------------------------------------------------------------------------------- /src/test/java/com/bloxbean/cardano/client/example/function/TransferTransactionTest.java: -------------------------------------------------------------------------------- 1 | package com.bloxbean.cardano.client.example.function; 2 | 3 | import com.bloxbean.cardano.client.account.Account; 4 | import com.bloxbean.cardano.client.api.exception.ApiException; 5 | import com.bloxbean.cardano.client.api.model.Result; 6 | import com.bloxbean.cardano.client.cip.cip20.MessageMetadata; 7 | import com.bloxbean.cardano.client.common.model.Networks; 8 | import com.bloxbean.cardano.client.example.BaseTest; 9 | import com.bloxbean.cardano.client.exception.AddressExcepion; 10 | import com.bloxbean.cardano.client.exception.CborSerializationException; 11 | import com.bloxbean.cardano.client.function.Output; 12 | import com.bloxbean.cardano.client.function.TxBuilder; 13 | import com.bloxbean.cardano.client.function.TxBuilderContext; 14 | import com.bloxbean.cardano.client.transaction.spec.Transaction; 15 | import org.junit.jupiter.api.Test; 16 | 17 | import static com.bloxbean.cardano.client.common.ADAConversionUtil.adaToLovelace; 18 | import static com.bloxbean.cardano.client.common.CardanoConstants.LOVELACE; 19 | import static com.bloxbean.cardano.client.function.helper.AuxDataProviders.metadataProvider; 20 | import static com.bloxbean.cardano.client.function.helper.BalanceTxBuilders.balanceTx; 21 | import static com.bloxbean.cardano.client.function.helper.InputBuilders.createFromSender; 22 | import static com.bloxbean.cardano.client.function.helper.SignerProviders.signerFrom; 23 | 24 | public class TransferTransactionTest extends BaseTest { 25 | 26 | @Test 27 | public void run() throws AddressExcepion, CborSerializationException, ApiException { 28 | new TransferTransactionTest().transfer(); 29 | } 30 | 31 | public void transfer() throws CborSerializationException, ApiException, AddressExcepion { 32 | String senderMnemonic = "kit color frog trick speak employ suit sort bomb goddess jewel primary spoil fade person useless measure manage warfare reduce few scrub beyond era"; 33 | Account sender = new Account(Networks.testnet(), senderMnemonic); 34 | String senderAddress = sender.baseAddress(); 35 | 36 | String receiverAddress = "addr_test1qqwpl7h3g84mhr36wpetk904p7fchx2vst0z696lxk8ujsjyruqwmlsm344gfux3nsj6njyzj3ppvrqtt36cp9xyydzqzumz82"; 37 | 38 | Output output = Output.builder() 39 | .address(receiverAddress) 40 | .assetName(LOVELACE) 41 | .qty(adaToLovelace(2.1)) 42 | .build(); 43 | 44 | MessageMetadata metadata = MessageMetadata.create() 45 | .add("This is a sample transfer transaction"); 46 | 47 | TxBuilder txBuilder = output.outputBuilder() 48 | .buildInputs(createFromSender(senderAddress, senderAddress)) 49 | .andThen(metadataProvider(metadata)) 50 | .andThen(balanceTx(senderAddress, 1)); 51 | 52 | Transaction signedTransaction = TxBuilderContext.init(utxoSupplier, protocolParamsSupplier) 53 | .buildAndSign(txBuilder, signerFrom(sender)); 54 | 55 | Result result = transactionService.submitTransaction(signedTransaction.serialize()); 56 | System.out.println(result); 57 | 58 | if (result.isSuccessful()) 59 | System.out.println("Transaction Id: " + result.getValue()); 60 | else 61 | System.out.println("Transaction failed: " + result); 62 | 63 | waitForTransactionHash(result); 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /src/test/java/com/bloxbean/cardano/client/example/function/contract/v1/CustomGuessContractTest.java: -------------------------------------------------------------------------------- 1 | package com.bloxbean.cardano.client.example.function.contract.v1; 2 | 3 | import com.bloxbean.cardano.client.account.Account; 4 | import com.bloxbean.cardano.client.address.AddressProvider; 5 | import com.bloxbean.cardano.client.api.model.Result; 6 | import com.bloxbean.cardano.client.api.model.Utxo; 7 | import com.bloxbean.cardano.client.common.model.Networks; 8 | import com.bloxbean.cardano.client.example.function.contract.ContractBaseTest; 9 | import com.bloxbean.cardano.client.function.Output; 10 | import com.bloxbean.cardano.client.function.TxBuilder; 11 | import com.bloxbean.cardano.client.function.TxBuilderContext; 12 | import com.bloxbean.cardano.client.function.TxSigner; 13 | import com.bloxbean.cardano.client.function.helper.SignerProviders; 14 | import com.bloxbean.cardano.client.function.helper.model.ScriptCallContext; 15 | import com.bloxbean.cardano.client.plutus.spec.ExUnits; 16 | import com.bloxbean.cardano.client.plutus.spec.PlutusV1Script; 17 | import com.bloxbean.cardano.client.transaction.spec.Transaction; 18 | import com.bloxbean.cardano.client.util.Tuple; 19 | import org.junit.jupiter.api.Test; 20 | 21 | import java.math.BigInteger; 22 | import java.util.List; 23 | 24 | import static com.bloxbean.cardano.client.common.CardanoConstants.LOVELACE; 25 | import static com.bloxbean.cardano.client.function.helper.BalanceTxBuilders.balanceTx; 26 | import static com.bloxbean.cardano.client.function.helper.CollateralBuilders.collateralFrom; 27 | import static com.bloxbean.cardano.client.function.helper.InputBuilders.createFromUtxos; 28 | import static com.bloxbean.cardano.client.function.helper.ScriptCallContextProviders.createFromScriptCallContext; 29 | import static org.junit.jupiter.api.Assertions.assertTrue; 30 | 31 | //https://github.com/input-output-hk/cardano-node/blob/28c34d813b8176afc653d6612d59fdd37dfeecfb/plutus-example/src/Cardano/PlutusExample/CustomDatumRedeemerGuess.hs#L1 32 | public class CustomGuessContractTest extends ContractBaseTest { 33 | String senderMnemonic = "kit color frog trick speak employ suit sort bomb goddess jewel primary spoil fade person useless measure manage warfare reduce few scrub beyond era"; 34 | Account sender = new Account(Networks.testnet(), senderMnemonic); 35 | String senderAddress = sender.baseAddress(); 36 | 37 | @Test 38 | public void run() throws Exception { 39 | CustomGuessContractTest customGuessContractTest = new CustomGuessContractTest(); 40 | customGuessContractTest.call(); 41 | } 42 | 43 | public void call() throws Exception { 44 | PlutusV1Script plutusScript = PlutusV1Script.builder() 45 | .type("PlutusScriptV1") 46 | .cborHex("590a15590a120100003323322332232323332223233322232333333332222222232333222323333222232323322323332223233322232323322332232323333322222332233223322332233223322223223223232533530333330083333573466e1cd55cea8032400046eb4d5d09aab9e500723504935304a335738921035054310004b499263333573466e1cd55cea8022400046eb4d5d09aab9e500523504935304a3357389201035054310004b499263333573466e1cd55cea8012400046601664646464646464646464646666ae68cdc39aab9d500a480008cccccccccc064cd409c8c8c8cccd5cd19b8735573aa004900011980f981d1aba15002302c357426ae8940088d4164d4c168cd5ce249035054310005b49926135573ca00226ea8004d5d0a80519a8138141aba150093335502e75ca05a6ae854020ccd540b9d728169aba1500733502704335742a00c66a04e66aa0a8098eb4d5d0a8029919191999ab9a3370e6aae754009200023350213232323333573466e1cd55cea80124000466a05266a084eb4d5d0a80118239aba135744a00446a0ba6a60bc66ae712401035054310005f49926135573ca00226ea8004d5d0a8011919191999ab9a3370e6aae7540092000233502733504275a6ae854008c11cd5d09aba2500223505d35305e3357389201035054310005f49926135573ca00226ea8004d5d09aba2500223505935305a3357389201035054310005b49926135573ca00226ea8004d5d0a80219a813bae35742a00666a04e66aa0a8eb88004d5d0a801181c9aba135744a00446a0aa6a60ac66ae71241035054310005749926135744a00226ae8940044d5d1280089aba25001135744a00226ae8940044d5d1280089aba25001135573ca00226ea8004d5d0a8011919191999ab9a3370ea00290031180f181d9aba135573ca00646666ae68cdc3a801240084603a608a6ae84d55cf280211999ab9a3370ea00690011180e98181aba135573ca00a46666ae68cdc3a80224000460406eb8d5d09aab9e50062350503530513357389201035054310005249926499264984d55cea80089baa001357426ae8940088d4124d4c128cd5ce249035054310004b49926104a1350483530493357389201035054350004a4984d55cf280089baa0011375400226ea80048848cc00400c0088004888888888848cccccccccc00402c02802402001c01801401000c00880048848cc00400c008800448848cc00400c0084800448848cc00400c0084800448848cc00400c00848004848888c010014848888c00c014848888c008014848888c004014800448c88c008dd6000990009aa81a111999aab9f0012500e233500d30043574200460066ae880080cc8c8c8c8cccd5cd19b8735573aa006900011998039919191999ab9a3370e6aae754009200023300d303135742a00466a02605a6ae84d5d1280111a81b1a981b99ab9c491035054310003849926135573ca00226ea8004d5d0a801999aa805bae500a35742a00466a01eeb8d5d09aba25002235032353033335738921035054310003449926135744a00226aae7940044dd50009110919980080200180110009109198008018011000899aa800bae75a224464460046eac004c8004d540b888c8cccd55cf80112804919a80419aa81898031aab9d5002300535573ca00460086ae8800c0b84d5d08008891001091091198008020018900089119191999ab9a3370ea002900011a80418029aba135573ca00646666ae68cdc3a801240044a01046a0526a605466ae712401035054310002b499264984d55cea80089baa001121223002003112200112001232323333573466e1cd55cea8012400046600c600e6ae854008dd69aba135744a00446a0466a604866ae71241035054310002549926135573ca00226ea80048848cc00400c00880048c8cccd5cd19b8735573aa002900011bae357426aae7940088d407cd4c080cd5ce24810350543100021499261375400224464646666ae68cdc3a800a40084a00e46666ae68cdc3a8012400446a014600c6ae84d55cf280211999ab9a3370ea00690001280511a8111a981199ab9c490103505431000244992649926135573aa00226ea8004484888c00c0104488800844888004480048c8cccd5cd19b8750014800880188cccd5cd19b8750024800080188d4068d4c06ccd5ce249035054310001c499264984d55ce9baa0011220021220012001232323232323333573466e1d4005200c200b23333573466e1d4009200a200d23333573466e1d400d200823300b375c6ae854014dd69aba135744a00a46666ae68cdc3a8022400c46601a6eb8d5d0a8039bae357426ae89401c8cccd5cd19b875005480108cc048c050d5d0a8049bae357426ae8940248cccd5cd19b875006480088c050c054d5d09aab9e500b23333573466e1d401d2000230133016357426aae7940308d407cd4c080cd5ce2481035054310002149926499264992649926135573aa00826aae79400c4d55cf280109aab9e500113754002424444444600e01044244444446600c012010424444444600a010244444440082444444400644244444446600401201044244444446600201201040024646464646666ae68cdc3a800a400446660106eb4d5d0a8021bad35742a0066eb4d5d09aba2500323333573466e1d400920002300a300b357426aae7940188d4040d4c044cd5ce2490350543100012499264984d55cea80189aba25001135573ca00226ea80048488c00800c888488ccc00401401000c80048c8c8cccd5cd19b875001480088c018dd71aba135573ca00646666ae68cdc3a80124000460106eb8d5d09aab9e500423500a35300b3357389201035054310000c499264984d55cea80089baa001212230020032122300100320011122232323333573466e1cd55cea80124000466aa016600c6ae854008c014d5d09aba25002235007353008335738921035054310000949926135573ca00226ea8004498480048004448848cc00400c008448004448c8c00400488cc00cc008008004ccc888c8c8ccc888ccc888cccccccc88888888cc88ccccc88888cccc8888cc88cc88cc88ccc888cc88cc88ccc888cc88cc88cc88cc88888cc894cd4c0e4008400440e8ccd40d540d800d205433350355036002481508848cc00400c0088004888888888848cccccccccc00402c02802402001c01801401000c00880048848cc00400c008800488848ccc00401000c00880044488008488488cc00401000c48004448848cc00400c0084480048848cc00400c008800448488c00800c44880044800448848cc00400c0084800448848cc00400c0084800448848cc00400c00848004484888c00c010448880084488800448004848888c010014848888c00c014848888c008014848888c00401480048848cc00400c0088004848888888c01c0208848888888cc018024020848888888c014020488888880104888888800c8848888888cc0080240208848888888cc00402402080048488c00800c888488ccc00401401000c80048488c00800c8488c00400c800448004488ccd5cd19b87002001005004122002122001200101") 47 | .build(); 48 | String scriptAddress = AddressProvider.getEntAddress(plutusScript, Networks.testnet()).getAddress(); 49 | System.out.println("Script Address: " + scriptAddress); 50 | 51 | //Setup ----- Collateral setup for test and find script utxo 52 | Tuple collateralTuple = collateralSetup(sender); 53 | if (collateralTuple == null) { 54 | System.out.println("Collateral cannot be found or created. "); 55 | return; 56 | } 57 | 58 | Guess guess = new Guess(Integer.valueOf(42)); 59 | Tuple scriptUtxoTuple = getScriptUtxo(sender, scriptAddress, guess, collateralTuple); 60 | 61 | Utxo scriptUtxo = scriptUtxoTuple._1; 62 | BigInteger claimableAmt = scriptUtxoTuple._2; 63 | //---------- 64 | 65 | System.out.println("Script utxo >>>>>>>> " + scriptUtxo.getTxHash()); 66 | 67 | Output scriptOutput = Output.builder() 68 | .address(sender.baseAddress()) 69 | .assetName(LOVELACE) 70 | .qty(claimableAmt) 71 | .build(); 72 | 73 | ExUnits exUnits = ExUnits.builder() 74 | .mem(BigInteger.valueOf(4676948)) 75 | .steps(BigInteger.valueOf(630892334)).build(); 76 | 77 | ScriptCallContext scriptCallContext = ScriptCallContext.builder() 78 | .script(plutusScript) 79 | .utxo(scriptUtxo) 80 | .datum(guess) 81 | .redeemer(guess) 82 | .exUnits(exUnits).build(); 83 | 84 | TxBuilder builder = 85 | scriptOutput.outputBuilder() 86 | .buildInputs(createFromUtxos(List.of(scriptUtxo), null, null)) //Transfer everything at script utxo 87 | .andThen(collateralFrom(collateralTuple._1, collateralTuple._2)) //Set collateral 88 | .andThen(createFromScriptCallContext(scriptCallContext)) //Script call specific data 89 | .andThen(balanceTx(senderAddress, 1)); 90 | 91 | TxSigner signer = SignerProviders.signerFrom(sender); 92 | Transaction signedTxn = TxBuilderContext.init(utxoSupplier, protocolParamsSupplier) 93 | .buildAndSign(builder, signer); 94 | 95 | System.out.println(signedTxn); 96 | 97 | Result result = transactionService.submitTransaction(signedTxn.serialize()); 98 | System.out.println(result); 99 | 100 | assertTrue(result.isSuccessful()); 101 | waitForTransactionHash(result); 102 | } 103 | } 104 | 105 | -------------------------------------------------------------------------------- /src/test/java/com/bloxbean/cardano/client/example/function/contract/v1/Guess.java: -------------------------------------------------------------------------------- 1 | package com.bloxbean.cardano.client.example.function.contract.v1; 2 | 3 | import com.bloxbean.cardano.client.plutus.annotation.Constr; 4 | import com.bloxbean.cardano.client.plutus.annotation.PlutusField; 5 | 6 | @Constr 7 | class Guess { 8 | @PlutusField 9 | Integer number; 10 | 11 | public Guess(int number) { 12 | this.number = number; 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/test/java/com/bloxbean/cardano/client/example/function/contract/v1/MintContractAndDistributeTest.java: -------------------------------------------------------------------------------- 1 | package com.bloxbean.cardano.client.example.function.contract.v1; 2 | 3 | import com.bloxbean.cardano.client.account.Account; 4 | import com.bloxbean.cardano.client.address.AddressProvider; 5 | import com.bloxbean.cardano.client.api.model.Result; 6 | import com.bloxbean.cardano.client.cip.cip20.MessageMetadata; 7 | import com.bloxbean.cardano.client.common.model.Networks; 8 | import com.bloxbean.cardano.client.example.function.contract.ContractBaseTest; 9 | import com.bloxbean.cardano.client.function.Output; 10 | import com.bloxbean.cardano.client.function.TxBuilder; 11 | import com.bloxbean.cardano.client.function.TxBuilderContext; 12 | import com.bloxbean.cardano.client.function.TxSigner; 13 | import com.bloxbean.cardano.client.function.helper.*; 14 | import com.bloxbean.cardano.client.plutus.spec.*; 15 | import com.bloxbean.cardano.client.transaction.spec.*; 16 | import com.bloxbean.cardano.client.util.Tuple; 17 | import org.junit.jupiter.api.Test; 18 | 19 | import java.math.BigInteger; 20 | import java.util.Arrays; 21 | 22 | import static org.junit.jupiter.api.Assertions.assertTrue; 23 | import static org.junit.jupiter.api.Assertions.fail; 24 | 25 | //Minthttps://github.com/input-output-hk/cardano-node/blob/28c34d813b8176afc653d6612d59fdd37dfeecfb/plutus-example/src/Cardano/PlutusExample/MintingScript.hs#L1 26 | public class MintContractAndDistributeTest extends ContractBaseTest { 27 | String senderMnemonic = "kit color frog trick speak employ suit sort bomb goddess jewel primary spoil fade person useless measure manage warfare reduce few scrub beyond era"; 28 | Account sender = new Account(Networks.testnet(), senderMnemonic); 29 | String senderAddress = sender.baseAddress(); 30 | 31 | @Test 32 | public void run() throws Exception { 33 | new MintContractAndDistributeTest().mint(); 34 | } 35 | 36 | void mint() throws Exception { 37 | String receiver1 = "addr_test1qrs2a2hjfs2wt8r3smzwmptezmave3yjgws068hp0qsflmcypglx0rl69tp49396282ns02caz4cx7a2n290h2df0j3qjku4dy"; 38 | String receiver2 = "addr_test1qz9q4mps4skpu7wc63vk6yd4jj2qkheydkuznwgkfg89v397hm954glfvxv4hzcjvladwfh4c0l39uh5pkkcuj789zfs8awfnq"; 39 | String receiver3 = "addr_test1qrth48wp98vampmpw602ryh29e0snhzzasmkt4aqfduk6hu0wcpcxeexmya86slcnh8ug6dl8njh2vn8v4tj2z0lv75swkcw3g"; 40 | String receiver4 = "addr_test1qpy34jdakhx5nuenlv8v2ydwlkpa6e24v5l6ka2xnq4rtj6zx7td26wen4smhe8vjne4r4k3tm2g03radqv3g8ez6jyqzhqvh5"; 41 | 42 | //-- Mint Script 43 | PlutusV1Script mintScript = PlutusV1Script.builder() 44 | .type("PlutusScriptV1") 45 | .cborHex("59083159082e010000323322332232323233322232333222323333333322222222323332223233332222323233223233322232333222323233223322323233333222223322332233223322332233222232325335302f332203330430043333573466e1cd55cea8012400046600e64646464646464646464646666ae68cdc39aab9d500a480008cccccccccc054cd408c8c8c8cccd5cd19b8735573aa004900011980d981b1aba150023028357426ae8940088d4158d4c15ccd5ce249035054310005849926135573ca00226ea8004d5d0a80519a8118121aba150093335502a75ca0526ae854020ccd540a9d728149aba1500733502303f35742a00c66a04666aa0a2090eb4d5d0a8029919191999ab9a3370e6aae7540092000233501d3232323333573466e1cd55cea80124000466a04a66a07ceb4d5d0a80118219aba135744a00446a0b46a60b666ae712401035054310005c49926135573ca00226ea8004d5d0a8011919191999ab9a3370e6aae7540092000233502333503e75a6ae854008c10cd5d09aba2500223505a35305b3357389201035054310005c49926135573ca00226ea8004d5d09aba250022350563530573357389201035054310005849926135573ca00226ea8004d5d0a80219a811bae35742a00666a04666aa0a2eb8140d5d0a801181a9aba135744a00446a0a46a60a666ae712401035054310005449926135744a00226ae8940044d5d1280089aba25001135744a00226ae8940044d5d1280089aba25001135573ca00226ea8004d5d0a8011919191999ab9a3370ea00290031180d181b9aba135573ca00646666ae68cdc3a801240084603260826ae84d55cf280211999ab9a3370ea00690011180c98161aba135573ca00a46666ae68cdc3a80224000460386eb8d5d09aab9e500623504d35304e3357389201035054310004f49926499264984d55cea80089baa001357426ae8940088d4118d4c11ccd5ce2490350543100048499261047135045353046335738920103505435000474984d55cf280089baa0012212330010030022001222222222212333333333300100b00a00900800700600500400300220012212330010030022001122123300100300212001122123300100300212001122123300100300212001212222300400521222230030052122223002005212222300100520011232230023758002640026aa06a446666aae7c004940388cd4034c010d5d080118019aba200203423232323333573466e1cd55cea801a4000466600e6464646666ae68cdc39aab9d5002480008cc034c0c4d5d0a80119a8098169aba135744a00446a06e6a607066ae712401035054310003949926135573ca00226ea8004d5d0a801999aa805bae500a35742a00466a01eeb8d5d09aba25002235033353034335738921035054310003549926135744a00226aae7940044dd50009110919980080200180110009109198008018011000899aa800bae75a224464460046eac004c8004d540bc88c8cccd55cf80112804919a80419aa81918031aab9d5002300535573ca00460086ae8800c0bc4d5d08008891001091091198008020018900089119191999ab9a3370ea002900011a80418029aba135573ca00646666ae68cdc3a801240044a01046a0546a605666ae712401035054310002c499264984d55cea80089baa001121223002003112200112001232323333573466e1cd55cea8012400046600c600e6ae854008dd69aba135744a00446a0486a604a66ae71241035054310002649926135573ca00226ea80048848cc00400c00880048c8cccd5cd19b8735573aa002900011bae357426aae7940088d4080d4c084cd5ce24810350543100022499261375400224464646666ae68cdc3a800a40084a00e46666ae68cdc3a8012400446a014600c6ae84d55cf280211999ab9a3370ea00690001280511a8119a981219ab9c490103505431000254992649926135573aa00226ea8004484888c00c0104488800844888004480048c8cccd5cd19b8750014800880188cccd5cd19b8750024800080188d406cd4c070cd5ce249035054310001d499264984d55ce9baa0011220021220012001232323232323333573466e1d4005200c200b23333573466e1d4009200a200d23333573466e1d400d200823300b375c6ae854014dd69aba135744a00a46666ae68cdc3a8022400c46601a6eb8d5d0a8039bae357426ae89401c8cccd5cd19b875005480108cc048c050d5d0a8049bae357426ae8940248cccd5cd19b875006480088c050c054d5d09aab9e500b23333573466e1d401d2000230133016357426aae7940308d4080d4c084cd5ce2481035054310002249926499264992649926135573aa00826aae79400c4d55cf280109aab9e500113754002424444444600e01044244444446600c012010424444444600a010244444440082444444400644244444446600401201044244444446600201201040024646464646666ae68cdc3a800a400446660106eb4d5d0a8021bad35742a0066eb4d5d09aba2500323333573466e1d400920002300a300b357426aae7940188d4044d4c048cd5ce2490350543100013499264984d55cea80189aba25001135573ca00226ea80048488c00800c888488ccc00401401000c80048c8c8cccd5cd19b875001480088c018dd71aba135573ca00646666ae68cdc3a80124000460106eb8d5d09aab9e500423500b35300c3357389201035054310000d499264984d55cea80089baa0012122300200321223001003200120011122232323333573466e1cd55cea80124000466aa016600c6ae854008c014d5d09aba25002235007353008335738921035054310000949926135573ca00226ea8004498480048004448848cc00400c008448004448c8c00400488cc00cc0080080041") 46 | .build(); 47 | 48 | String mintScriptAddress = AddressProvider.getEntAddress(mintScript, Networks.testnet()).getAddress(); 49 | System.out.println("Mint Script Address: " + mintScriptAddress); 50 | 51 | //-- Setup collateral 52 | String collateral = "ab44e0f5faf56154cc33e757c9d98a60666346179d5a7a0b9d77734c23c42082"; 53 | int collateralIndex = 0; 54 | 55 | Tuple collateralTuple = checkCollateral(sender, collateral, collateralIndex); 56 | if (collateralTuple == null) { 57 | System.out.println("Collateral cannot be found or created. " + collateral); 58 | fail(); 59 | } 60 | collateral = collateralTuple._1; 61 | collateralIndex = collateralTuple._2; 62 | 63 | PlutusData redeemerData = new BigIntPlutusData(BigInteger.valueOf(4444)); //any redeemer .. doesn't matter 64 | 65 | long totalToken = 4000; 66 | String tokenName = "STT"; 67 | MultiAsset multiAsset = MultiAsset.builder() 68 | .policyId(mintScript.getPolicyId()) 69 | .assets(Arrays.asList( 70 | Asset.builder() 71 | .name("STT") 72 | .value(BigInteger.valueOf(totalToken)) 73 | .build())) 74 | .build(); 75 | 76 | Output output1 = Output.builder() 77 | .address(receiver1) 78 | .policyId(mintScript.getPolicyId()) 79 | .assetName(tokenName) 80 | .qty(BigInteger.valueOf(1000)).build(); 81 | 82 | Output output2 = Output.builder() 83 | .address(receiver2) 84 | .policyId(mintScript.getPolicyId()) 85 | .assetName(tokenName) 86 | .qty(BigInteger.valueOf(1000)).build(); 87 | 88 | Output output3 = Output.builder() 89 | .address(receiver3) 90 | .policyId(mintScript.getPolicyId()) 91 | .assetName(tokenName) 92 | .qty(BigInteger.valueOf(500)).build(); 93 | 94 | Output output4 = Output.builder() 95 | .address(receiver4) 96 | .policyId(mintScript.getPolicyId()) 97 | .assetName(tokenName) 98 | .qty(BigInteger.valueOf(1500)).build(); 99 | 100 | MessageMetadata metadata = MessageMetadata.create() 101 | .add("NFT minted by Plutus script"); 102 | 103 | ExUnits exUnits = ExUnits.builder() 104 | .mem(BigInteger.valueOf(2289624)) 105 | .steps(BigInteger.valueOf(1214842019)).build(); 106 | 107 | TxBuilder txBuilder = 108 | output1.mintOutputBuilder() 109 | .and(output2.mintOutputBuilder()) 110 | .and(output3.mintOutputBuilder()) 111 | .and(output4.mintOutputBuilder()) 112 | .buildInputs(InputBuilders.createFromSender(senderAddress, senderAddress)) 113 | .andThen(CollateralBuilders.collateralFrom(collateral, collateralIndex)) 114 | .andThen(MintCreators.mintCreator(mintScript, multiAsset)) 115 | .andThen(ScriptCallContextProviders.scriptCallContext(mintScript, null, null, redeemerData, RedeemerTag.Mint, exUnits)) 116 | .andThen(AuxDataProviders.metadataProvider(metadata)) 117 | .andThen(BalanceTxBuilders.balanceTx(senderAddress, 1)); 118 | 119 | TxSigner signer = SignerProviders.signerFrom(sender); 120 | 121 | Transaction signTxn = TxBuilderContext.init(utxoSupplier, protocolParamsSupplier) 122 | .buildAndSign(txBuilder, signer); 123 | 124 | System.out.println(signTxn); 125 | Result result = transactionService.submitTransaction(signTxn.serialize()); 126 | System.out.println(result); 127 | 128 | assertTrue(result.isSuccessful()); 129 | waitForTransactionHash(result); 130 | } 131 | } 132 | -------------------------------------------------------------------------------- /src/test/java/com/bloxbean/cardano/client/example/function/contract/v1/MintContractTest.java: -------------------------------------------------------------------------------- 1 | package com.bloxbean.cardano.client.example.function.contract.v1; 2 | 3 | import com.bloxbean.cardano.client.account.Account; 4 | import com.bloxbean.cardano.client.address.AddressProvider; 5 | import com.bloxbean.cardano.client.api.model.Result; 6 | import com.bloxbean.cardano.client.cip.cip20.MessageMetadata; 7 | import com.bloxbean.cardano.client.common.model.Networks; 8 | import com.bloxbean.cardano.client.example.function.contract.ContractBaseTest; 9 | import com.bloxbean.cardano.client.function.TxBuilder; 10 | import com.bloxbean.cardano.client.function.TxBuilderContext; 11 | import com.bloxbean.cardano.client.function.TxSigner; 12 | import com.bloxbean.cardano.client.function.helper.*; 13 | import com.bloxbean.cardano.client.plutus.spec.*; 14 | import com.bloxbean.cardano.client.transaction.spec.*; 15 | import com.bloxbean.cardano.client.util.Tuple; 16 | import org.junit.jupiter.api.Test; 17 | 18 | import java.math.BigInteger; 19 | import java.util.Arrays; 20 | 21 | import static org.junit.jupiter.api.Assertions.assertTrue; 22 | 23 | //Minthttps://github.com/input-output-hk/cardano-node/blob/28c34d813b8176afc653d6612d59fdd37dfeecfb/plutus-example/src/Cardano/PlutusExample/MintingScript.hs#L1 24 | public class MintContractTest extends ContractBaseTest { 25 | String senderMnemonic = "kit color frog trick speak employ suit sort bomb goddess jewel primary spoil fade person useless measure manage warfare reduce few scrub beyond era"; 26 | Account sender = new Account(Networks.testnet(), senderMnemonic); 27 | String senderAddress = sender.baseAddress(); 28 | 29 | @Test 30 | public void run() throws Exception { 31 | new MintContractTest().mint(); 32 | } 33 | 34 | void mint() throws Exception { 35 | String receiverAddress = senderAddress; 36 | 37 | PlutusV1Script mintScript = PlutusV1Script.builder() 38 | .type("PlutusScriptV1") 39 | .cborHex("59083159082e010000323322332232323233322232333222323333333322222222323332223233332222323233223233322232333222323233223322323233333222223322332233223322332233222232325335302f332203330430043333573466e1cd55cea8012400046600e64646464646464646464646666ae68cdc39aab9d500a480008cccccccccc054cd408c8c8c8cccd5cd19b8735573aa004900011980d981b1aba150023028357426ae8940088d4158d4c15ccd5ce249035054310005849926135573ca00226ea8004d5d0a80519a8118121aba150093335502a75ca0526ae854020ccd540a9d728149aba1500733502303f35742a00c66a04666aa0a2090eb4d5d0a8029919191999ab9a3370e6aae7540092000233501d3232323333573466e1cd55cea80124000466a04a66a07ceb4d5d0a80118219aba135744a00446a0b46a60b666ae712401035054310005c49926135573ca00226ea8004d5d0a8011919191999ab9a3370e6aae7540092000233502333503e75a6ae854008c10cd5d09aba2500223505a35305b3357389201035054310005c49926135573ca00226ea8004d5d09aba250022350563530573357389201035054310005849926135573ca00226ea8004d5d0a80219a811bae35742a00666a04666aa0a2eb8140d5d0a801181a9aba135744a00446a0a46a60a666ae712401035054310005449926135744a00226ae8940044d5d1280089aba25001135744a00226ae8940044d5d1280089aba25001135573ca00226ea8004d5d0a8011919191999ab9a3370ea00290031180d181b9aba135573ca00646666ae68cdc3a801240084603260826ae84d55cf280211999ab9a3370ea00690011180c98161aba135573ca00a46666ae68cdc3a80224000460386eb8d5d09aab9e500623504d35304e3357389201035054310004f49926499264984d55cea80089baa001357426ae8940088d4118d4c11ccd5ce2490350543100048499261047135045353046335738920103505435000474984d55cf280089baa0012212330010030022001222222222212333333333300100b00a00900800700600500400300220012212330010030022001122123300100300212001122123300100300212001122123300100300212001212222300400521222230030052122223002005212222300100520011232230023758002640026aa06a446666aae7c004940388cd4034c010d5d080118019aba200203423232323333573466e1cd55cea801a4000466600e6464646666ae68cdc39aab9d5002480008cc034c0c4d5d0a80119a8098169aba135744a00446a06e6a607066ae712401035054310003949926135573ca00226ea8004d5d0a801999aa805bae500a35742a00466a01eeb8d5d09aba25002235033353034335738921035054310003549926135744a00226aae7940044dd50009110919980080200180110009109198008018011000899aa800bae75a224464460046eac004c8004d540bc88c8cccd55cf80112804919a80419aa81918031aab9d5002300535573ca00460086ae8800c0bc4d5d08008891001091091198008020018900089119191999ab9a3370ea002900011a80418029aba135573ca00646666ae68cdc3a801240044a01046a0546a605666ae712401035054310002c499264984d55cea80089baa001121223002003112200112001232323333573466e1cd55cea8012400046600c600e6ae854008dd69aba135744a00446a0486a604a66ae71241035054310002649926135573ca00226ea80048848cc00400c00880048c8cccd5cd19b8735573aa002900011bae357426aae7940088d4080d4c084cd5ce24810350543100022499261375400224464646666ae68cdc3a800a40084a00e46666ae68cdc3a8012400446a014600c6ae84d55cf280211999ab9a3370ea00690001280511a8119a981219ab9c490103505431000254992649926135573aa00226ea8004484888c00c0104488800844888004480048c8cccd5cd19b8750014800880188cccd5cd19b8750024800080188d406cd4c070cd5ce249035054310001d499264984d55ce9baa0011220021220012001232323232323333573466e1d4005200c200b23333573466e1d4009200a200d23333573466e1d400d200823300b375c6ae854014dd69aba135744a00a46666ae68cdc3a8022400c46601a6eb8d5d0a8039bae357426ae89401c8cccd5cd19b875005480108cc048c050d5d0a8049bae357426ae8940248cccd5cd19b875006480088c050c054d5d09aab9e500b23333573466e1d401d2000230133016357426aae7940308d4080d4c084cd5ce2481035054310002249926499264992649926135573aa00826aae79400c4d55cf280109aab9e500113754002424444444600e01044244444446600c012010424444444600a010244444440082444444400644244444446600401201044244444446600201201040024646464646666ae68cdc3a800a400446660106eb4d5d0a8021bad35742a0066eb4d5d09aba2500323333573466e1d400920002300a300b357426aae7940188d4044d4c048cd5ce2490350543100013499264984d55cea80189aba25001135573ca00226ea80048488c00800c888488ccc00401401000c80048c8c8cccd5cd19b875001480088c018dd71aba135573ca00646666ae68cdc3a80124000460106eb8d5d09aab9e500423500b35300c3357389201035054310000d499264984d55cea80089baa0012122300200321223001003200120011122232323333573466e1cd55cea80124000466aa016600c6ae854008c014d5d09aba25002235007353008335738921035054310000949926135573ca00226ea8004498480048004448848cc00400c008448004448c8c00400488cc00cc0080080041") 40 | .build(); 41 | 42 | String mintScriptAddress = AddressProvider.getEntAddress(mintScript, Networks.testnet()).getAddress(); 43 | System.out.println("Mint Script Address: " + mintScriptAddress); 44 | 45 | //-- Setup collateral 46 | String collateral = "ab44e0f5faf56154cc33e757c9d98a60666346179d5a7a0b9d77734c23c42082"; 47 | int collateralIndex = 0; 48 | 49 | Tuple collateralTuple = checkCollateral(sender, collateral, collateralIndex); 50 | if (collateralTuple == null) { 51 | System.out.println("Collateral cannot be found or created. " + collateral); 52 | return; 53 | } 54 | collateral = collateralTuple._1; 55 | collateralIndex = collateralTuple._2; 56 | 57 | PlutusData redeemerData = new BigIntPlutusData(BigInteger.valueOf(4444)); //any redeemer .. doesn't matter 58 | 59 | MultiAsset multiAsset = MultiAsset.builder() 60 | .policyId(mintScript.getPolicyId()) 61 | .assets(Arrays.asList( 62 | Asset.builder() 63 | .name("ScriptToken") 64 | .value(BigInteger.valueOf(2)) 65 | .build())) 66 | .build(); 67 | 68 | 69 | TransactionOutput mintOutput = TransactionOutput 70 | .builder() 71 | .address(receiverAddress) 72 | .value(new Value(BigInteger.ZERO, Arrays.asList(multiAsset))) 73 | .build(); 74 | 75 | MessageMetadata metadata = MessageMetadata.create() 76 | .add("NFT minted by Plutus script"); 77 | 78 | ExUnits exUnits = ExUnits.builder() 79 | .mem(BigInteger.valueOf(989624)) 80 | .steps(BigInteger.valueOf(514842019)).build(); 81 | 82 | TxBuilder txBuilder = OutputBuilders.createFromMintOutput(mintOutput) 83 | .buildInputs(InputBuilders.createFromSender(senderAddress, senderAddress)) 84 | .andThen(CollateralBuilders.collateralFrom(collateral, collateralIndex)) 85 | .andThen(MintCreators.mintCreator(mintScript, multiAsset)) 86 | .andThen(ScriptCallContextProviders.scriptCallContext(mintScript, null, null, redeemerData, RedeemerTag.Mint, exUnits)) 87 | .andThen(AuxDataProviders.metadataProvider(metadata)) 88 | .andThen(BalanceTxBuilders.balanceTx(senderAddress, 1)); 89 | 90 | TxSigner signer = SignerProviders.signerFrom(sender); 91 | 92 | Transaction signTxn = TxBuilderContext.init(utxoSupplier, protocolParamsSupplier) 93 | .buildAndSign(txBuilder, signer); 94 | 95 | System.out.println(signTxn); 96 | Result result = transactionService.submitTransaction(signTxn.serialize()); 97 | System.out.println(result); 98 | 99 | assertTrue(result.isSuccessful()); 100 | waitForTransactionHash(result); 101 | } 102 | } 103 | -------------------------------------------------------------------------------- /src/test/java/com/bloxbean/cardano/client/example/function/minting/MintAndBurnTokenTest.java: -------------------------------------------------------------------------------- 1 | package com.bloxbean.cardano.client.example.function.minting; 2 | 3 | import com.bloxbean.cardano.client.account.Account; 4 | import com.bloxbean.cardano.client.api.exception.ApiException; 5 | import com.bloxbean.cardano.client.api.model.Result; 6 | import com.bloxbean.cardano.client.common.model.Networks; 7 | import com.bloxbean.cardano.client.crypto.SecretKey; 8 | import com.bloxbean.cardano.client.crypto.VerificationKey; 9 | import com.bloxbean.cardano.client.example.BaseTest; 10 | import com.bloxbean.cardano.client.exception.AddressExcepion; 11 | import com.bloxbean.cardano.client.exception.CborSerializationException; 12 | import com.bloxbean.cardano.client.function.Output; 13 | import com.bloxbean.cardano.client.function.TxBuilder; 14 | import com.bloxbean.cardano.client.function.TxBuilderContext; 15 | import com.bloxbean.cardano.client.function.helper.BalanceTxBuilders; 16 | import com.bloxbean.cardano.client.function.helper.InputBuilders; 17 | import com.bloxbean.cardano.client.function.helper.MintCreators; 18 | import com.bloxbean.cardano.client.transaction.spec.Asset; 19 | import com.bloxbean.cardano.client.transaction.spec.MultiAsset; 20 | import com.bloxbean.cardano.client.transaction.spec.Transaction; 21 | import com.bloxbean.cardano.client.transaction.spec.TransactionOutput; 22 | import com.bloxbean.cardano.client.transaction.spec.script.ScriptPubkey; 23 | import org.junit.jupiter.api.Test; 24 | 25 | import java.math.BigInteger; 26 | 27 | import static com.bloxbean.cardano.client.function.helper.SignerProviders.signerFrom; 28 | import static org.junit.jupiter.api.Assertions.assertTrue; 29 | 30 | public class MintAndBurnTokenTest extends BaseTest { 31 | private String senderMnemonic = "kit color frog trick speak employ suit sort bomb goddess jewel primary spoil fade person useless measure manage warfare reduce few scrub beyond era"; 32 | private final Account sender; 33 | private final String senderAddress; 34 | 35 | //policy script specific fields 36 | private SecretKey secretKey; 37 | private ScriptPubkey scriptPubkey; 38 | private String tokenName = "BurnTokenTest"; 39 | 40 | public MintAndBurnTokenTest() { 41 | sender = new Account(Networks.testnet(), senderMnemonic); 42 | senderAddress = sender.baseAddress(); 43 | 44 | secretKey = new SecretKey("5820bb93a58be2457d3e2cd6faf07af24b4be10a58f08b9a478ccfcb790aaa64e363"); 45 | scriptPubkey = ScriptPubkey.create(new VerificationKey("58205fd196d870a6cd5422967092be93243c5bca7bfffc81c795f0cfa50be20dae9c")); 46 | } 47 | 48 | @Test 49 | public void run() throws AddressExcepion, CborSerializationException, ApiException { 50 | MintAndBurnTokenTest mintAndBurnTokenTest = new MintAndBurnTokenTest(); 51 | // mintAndBurnTokenTest.mintToken(); 52 | mintAndBurnTokenTest.burnToken(); 53 | } 54 | 55 | public void mintToken() throws CborSerializationException, ApiException { 56 | String policyId = scriptPubkey.getPolicyId(); 57 | 58 | BigInteger noOfTokensToMint = new BigInteger("100000"); 59 | MultiAsset multiAsset = new MultiAsset(); 60 | multiAsset.setPolicyId(policyId); 61 | Asset asset = new Asset(tokenName, noOfTokensToMint); 62 | multiAsset.getAssets().add(asset); 63 | 64 | Output output = Output.builder() 65 | .address(senderAddress) 66 | .policyId(policyId) 67 | .assetName(asset.getName()) 68 | .qty(noOfTokensToMint) 69 | .build(); 70 | 71 | TxBuilder txBuilder = output.mintOutputBuilder() 72 | .buildInputs(InputBuilders.createFromSender(senderAddress, senderAddress)) 73 | .andThen(MintCreators.mintCreator(scriptPubkey, multiAsset)) 74 | .andThen(BalanceTxBuilders.balanceTx(senderAddress, 2)); 75 | 76 | Transaction signedTransaction = TxBuilderContext.init(utxoSupplier, protocolParamsSupplier) 77 | .buildAndSign(txBuilder, signerFrom(sender).andThen(signerFrom(secretKey))); 78 | 79 | Result result = transactionService.submitTransaction(signedTransaction.serialize()); 80 | System.out.println(result); 81 | 82 | if (result.isSuccessful()) 83 | System.out.println("Mint Transaction Id: " + result.getValue()); 84 | else 85 | System.out.println("Mint Transaction failed: " + result); 86 | 87 | assertTrue(result.isSuccessful()); 88 | waitForTransactionHash(result); 89 | } 90 | 91 | public void burnToken() throws CborSerializationException, ApiException, AddressExcepion { 92 | String policyId = scriptPubkey.getPolicyId(); 93 | 94 | BigInteger noOfTokensToBurn = new BigInteger("3"); 95 | 96 | MultiAsset multiAsset = new MultiAsset(); 97 | multiAsset.setPolicyId(policyId); 98 | Asset asset = new Asset(tokenName, noOfTokensToBurn.negate()); //set negative number to burn 99 | multiAsset.getAssets().add(asset); 100 | 101 | //Create an output with receiver addr as sender with burn token amount 102 | //This is just a dummy output which helps in utxo selection. But the output will be discarded later 103 | Output output = Output.builder() 104 | .address(senderAddress) 105 | .policyId(policyId) 106 | .assetName(asset.getName()) 107 | .qty(noOfTokensToBurn) 108 | .build(); 109 | 110 | TxBuilder txBuilder = output.outputBuilder() 111 | .buildInputs(InputBuilders.createFromSender(senderAddress, senderAddress)) 112 | .andThen(MintCreators.mintCreator(scriptPubkey, multiAsset)) 113 | .andThen((context, transaction) -> { 114 | //Discard the first output which is our dummy output. But the min ada value from first output 115 | //needs to be added to the changeoutput to balance the transaction. 116 | TransactionOutput firstTxOuput = transaction.getBody().getOutputs().get(0); //output with burn token 117 | TransactionOutput changeTxOuput = transaction.getBody().getOutputs().get(1); 118 | 119 | //Discard first txOuputput 120 | transaction.getBody().getOutputs().remove(firstTxOuput); 121 | //Add ada value from first output to changeoutput 122 | changeTxOuput.getValue() 123 | .setCoin(changeTxOuput.getValue().getCoin().add(firstTxOuput.getValue().getCoin())); 124 | }) 125 | .andThen(BalanceTxBuilders.balanceTx(senderAddress, 2)); 126 | 127 | Transaction signedTransaction = TxBuilderContext.init(utxoSupplier, protocolParamsSupplier) 128 | .buildAndSign(txBuilder, signerFrom(sender).andThen(signerFrom(secretKey))); 129 | 130 | Result result = transactionService.submitTransaction(signedTransaction.serialize()); 131 | System.out.println(result); 132 | 133 | if (result.isSuccessful()) 134 | System.out.println("Burn Transaction Id: " + result.getValue()); 135 | else 136 | System.out.println("Burn Transaction failed: " + result); 137 | 138 | assertTrue(result.isSuccessful()); 139 | waitForTransactionHash(result); 140 | } 141 | } 142 | -------------------------------------------------------------------------------- /src/test/java/com/bloxbean/cardano/client/example/function/minting/MintTokenNFT.java: -------------------------------------------------------------------------------- 1 | package com.bloxbean.cardano.client.example.function.minting; 2 | 3 | import com.bloxbean.cardano.client.account.Account; 4 | import com.bloxbean.cardano.client.api.exception.ApiException; 5 | import com.bloxbean.cardano.client.api.model.Result; 6 | import com.bloxbean.cardano.client.cip.cip25.NFT; 7 | import com.bloxbean.cardano.client.cip.cip25.NFTFile; 8 | import com.bloxbean.cardano.client.cip.cip25.NFTMetadata; 9 | import com.bloxbean.cardano.client.common.model.Networks; 10 | import com.bloxbean.cardano.client.example.BaseTest; 11 | import com.bloxbean.cardano.client.exception.AddressExcepion; 12 | import com.bloxbean.cardano.client.exception.CborSerializationException; 13 | import com.bloxbean.cardano.client.function.TxBuilder; 14 | import com.bloxbean.cardano.client.function.TxBuilderContext; 15 | import com.bloxbean.cardano.client.transaction.spec.*; 16 | import com.bloxbean.cardano.client.util.PolicyUtil; 17 | import org.junit.jupiter.api.Test; 18 | 19 | import java.math.BigInteger; 20 | import java.util.List; 21 | 22 | import static com.bloxbean.cardano.client.function.helper.AuxDataProviders.metadataProvider; 23 | import static com.bloxbean.cardano.client.function.helper.BalanceTxBuilders.balanceTx; 24 | import static com.bloxbean.cardano.client.function.helper.InputBuilders.createFromSender; 25 | import static com.bloxbean.cardano.client.function.helper.MintCreators.mintCreator; 26 | import static com.bloxbean.cardano.client.function.helper.OutputBuilders.createFromMintOutput; 27 | import static com.bloxbean.cardano.client.function.helper.SignerProviders.signerFrom; 28 | import static org.junit.jupiter.api.Assertions.assertTrue; 29 | 30 | public class MintTokenNFT extends BaseTest { 31 | 32 | @Test 33 | public void run() throws AddressExcepion, CborSerializationException, ApiException { 34 | new MintTokenNFT().mintToken(); 35 | } 36 | 37 | public void mintToken() throws CborSerializationException, ApiException, AddressExcepion { 38 | String senderMnemonic = "kit color frog trick speak employ suit sort bomb goddess jewel primary spoil fade person useless measure manage warfare reduce few scrub beyond era"; 39 | Account sender = new Account(Networks.testnet(), senderMnemonic); 40 | String senderAddress = sender.baseAddress(); 41 | System.out.printf(senderAddress); 42 | 43 | String receiverAddress = "addr_test1qqwpl7h3g84mhr36wpetk904p7fchx2vst0z696lxk8ujsjyruqwmlsm344gfux3nsj6njyzj3ppvrqtt36cp9xyydzqzumz82"; 44 | 45 | Policy policy = PolicyUtil.createMultiSigScriptAllPolicy("policy-1", 1); 46 | 47 | //Multi asset and NFT metadata 48 | MultiAsset multiAsset = new MultiAsset(); 49 | multiAsset.setPolicyId(policy.getPolicyId()); 50 | Asset asset = new Asset("TestNFT", BigInteger.valueOf(1)); 51 | multiAsset.getAssets().add(asset); 52 | 53 | NFT nft = NFT.create() 54 | .assetName(asset.getName()) 55 | .name(asset.getName()) 56 | .image("ipfs://Qmcv6hwtmdVumrNeb42R1KmCEWdYWGcqNgs17Y3hj6CkP4") 57 | .mediaType("image/png") 58 | .addFile(NFTFile.create() 59 | .name("file-1") 60 | .mediaType("image/png") 61 | .src("ipfs/Qmcv6hwtmdVumrNeb42R1KmCEWdYWGcqNgs17Y3hj6CkP4")) 62 | .description("This is a test NFT"); 63 | 64 | NFTMetadata nftMetadata = NFTMetadata.create() 65 | .version("1.0") 66 | .addNFT(policy.getPolicyId(), nft); 67 | 68 | Value value = Value.builder() 69 | .coin(BigInteger.ZERO) 70 | .multiAssets(List.of(multiAsset)).build(); 71 | 72 | TransactionOutput mintOutput = TransactionOutput.builder() 73 | .address(receiverAddress) 74 | .value(value).build(); 75 | 76 | TxBuilder txBuilder = 77 | createFromMintOutput(mintOutput) 78 | .buildInputs(createFromSender(senderAddress, senderAddress)) 79 | .andThen(mintCreator(policy.getPolicyScript(), multiAsset)) 80 | .andThen(metadataProvider(nftMetadata)) 81 | .andThen(balanceTx(senderAddress, 2)); 82 | 83 | Transaction signedTransaction = TxBuilderContext.init(utxoSupplier, protocolParamsSupplier) 84 | .buildAndSign(txBuilder, signerFrom(sender).andThen(signerFrom(policy))); 85 | 86 | System.out.println(signedTransaction); 87 | Result result = transactionService.submitTransaction(signedTransaction.serialize()); 88 | System.out.println(result); 89 | 90 | if (result.isSuccessful()) 91 | System.out.println("Transaction Id: " + result.getValue()); 92 | else 93 | System.out.println("Transaction failed: " + result); 94 | 95 | assertTrue(result.isSuccessful()); 96 | waitForTransactionHash(result); 97 | 98 | } 99 | } 100 | -------------------------------------------------------------------------------- /src/test/java/com/bloxbean/cardano/client/example/function/minting/MintTokenTest.java: -------------------------------------------------------------------------------- 1 | package com.bloxbean.cardano.client.example.function.minting; 2 | 3 | import com.bloxbean.cardano.client.account.Account; 4 | import com.bloxbean.cardano.client.api.exception.ApiException; 5 | import com.bloxbean.cardano.client.api.model.Result; 6 | import com.bloxbean.cardano.client.common.model.Networks; 7 | import com.bloxbean.cardano.client.example.BaseTest; 8 | import com.bloxbean.cardano.client.exception.AddressExcepion; 9 | import com.bloxbean.cardano.client.exception.CborSerializationException; 10 | import com.bloxbean.cardano.client.function.Output; 11 | import com.bloxbean.cardano.client.function.TxBuilder; 12 | import com.bloxbean.cardano.client.function.TxBuilderContext; 13 | import com.bloxbean.cardano.client.function.helper.AuxDataProviders; 14 | import com.bloxbean.cardano.client.function.helper.BalanceTxBuilders; 15 | import com.bloxbean.cardano.client.function.helper.InputBuilders; 16 | import com.bloxbean.cardano.client.function.helper.MintCreators; 17 | import com.bloxbean.cardano.client.metadata.Metadata; 18 | import com.bloxbean.cardano.client.metadata.cbor.CBORMetadata; 19 | import com.bloxbean.cardano.client.metadata.cbor.CBORMetadataList; 20 | import com.bloxbean.cardano.client.metadata.cbor.CBORMetadataMap; 21 | import com.bloxbean.cardano.client.transaction.spec.Asset; 22 | import com.bloxbean.cardano.client.transaction.spec.MultiAsset; 23 | import com.bloxbean.cardano.client.transaction.spec.Policy; 24 | import com.bloxbean.cardano.client.transaction.spec.Transaction; 25 | import com.bloxbean.cardano.client.util.PolicyUtil; 26 | import org.junit.jupiter.api.Test; 27 | 28 | import java.math.BigInteger; 29 | 30 | import static com.bloxbean.cardano.client.function.helper.SignerProviders.signerFrom; 31 | import static org.junit.jupiter.api.Assertions.assertTrue; 32 | 33 | public class MintTokenTest extends BaseTest { 34 | 35 | @Test 36 | public void run() throws AddressExcepion, CborSerializationException, ApiException { 37 | new MintTokenTest().mintToken(); 38 | } 39 | 40 | public void mintToken() throws CborSerializationException, ApiException, AddressExcepion { 41 | String senderMnemonic = "kit color frog trick speak employ suit sort bomb goddess jewel primary spoil fade person useless measure manage warfare reduce few scrub beyond era"; 42 | Account sender = new Account(Networks.testnet(), senderMnemonic); 43 | String senderAddress = sender.baseAddress(); 44 | 45 | String receiverAddress = "addr_test1qqwpl7h3g84mhr36wpetk904p7fchx2vst0z696lxk8ujsjyruqwmlsm344gfux3nsj6njyzj3ppvrqtt36cp9xyydzqzumz82"; 46 | 47 | Policy policy = PolicyUtil.createMultiSigScriptAllPolicy("policy-1", 1); 48 | 49 | MultiAsset multiAsset = new MultiAsset(); 50 | multiAsset.setPolicyId(policy.getPolicyId()); 51 | Asset asset = new Asset("TestCoin", BigInteger.valueOf(50000)); 52 | multiAsset.getAssets().add(asset); 53 | 54 | //Metadata 55 | CBORMetadataMap tokenInfoMap 56 | = new CBORMetadataMap() 57 | .put("token", "Test Token") 58 | .put("symbol", "TTOK"); 59 | 60 | CBORMetadataList tagList 61 | = new CBORMetadataList() 62 | .add("tag1") 63 | .add("tag2"); 64 | 65 | Metadata metadata = new CBORMetadata() 66 | .put(new BigInteger("670001"), tokenInfoMap) 67 | .put(new BigInteger("670002"), tagList); 68 | 69 | Output output = Output.builder() 70 | .address(receiverAddress) 71 | .policyId(policy.getPolicyId()) 72 | .assetName(asset.getName()) 73 | .qty(BigInteger.valueOf(50000)) 74 | .build(); 75 | 76 | TxBuilder txBuilder = output.mintOutputBuilder() 77 | .buildInputs(InputBuilders.createFromSender(senderAddress, senderAddress)) 78 | .andThen(MintCreators.mintCreator(policy.getPolicyScript(), multiAsset)) 79 | .andThen(AuxDataProviders.metadataProvider(metadata)) 80 | .andThen(BalanceTxBuilders.balanceTx(senderAddress, 2)); 81 | 82 | Transaction signedTransaction = TxBuilderContext.init(utxoSupplier, protocolParamsSupplier) 83 | .buildAndSign(txBuilder, signerFrom(sender).andThen(signerFrom(policy))); 84 | 85 | Result result = transactionService.submitTransaction(signedTransaction.serialize()); 86 | System.out.println(result); 87 | 88 | if (result.isSuccessful()) 89 | System.out.println("Transaction Id: " + result.getValue()); 90 | else 91 | System.out.println("Transaction failed: " + result); 92 | 93 | assertTrue(result.isSuccessful()); 94 | waitForTransactionHash(result); 95 | 96 | } 97 | } 98 | -------------------------------------------------------------------------------- /src/test/java/com/bloxbean/cardano/client/example/function/minting/MulitpleMintNFTsWithRefund.java: -------------------------------------------------------------------------------- 1 | package com.bloxbean.cardano.client.example.function.minting; 2 | 3 | import com.bloxbean.cardano.client.account.Account; 4 | import com.bloxbean.cardano.client.api.exception.ApiException; 5 | import com.bloxbean.cardano.client.api.model.Result; 6 | import com.bloxbean.cardano.client.cip.cip25.NFT; 7 | import com.bloxbean.cardano.client.cip.cip25.NFTFile; 8 | import com.bloxbean.cardano.client.cip.cip25.NFTMetadata; 9 | import com.bloxbean.cardano.client.common.model.Networks; 10 | import com.bloxbean.cardano.client.example.BaseTest; 11 | import com.bloxbean.cardano.client.exception.AddressExcepion; 12 | import com.bloxbean.cardano.client.exception.CborSerializationException; 13 | import com.bloxbean.cardano.client.function.Output; 14 | import com.bloxbean.cardano.client.function.TxBuilder; 15 | import com.bloxbean.cardano.client.function.TxBuilderContext; 16 | import com.bloxbean.cardano.client.transaction.spec.*; 17 | import com.bloxbean.cardano.client.util.PolicyUtil; 18 | import org.junit.jupiter.api.Test; 19 | 20 | import java.math.BigInteger; 21 | import java.util.List; 22 | 23 | import static com.bloxbean.cardano.client.common.ADAConversionUtil.adaToLovelace; 24 | import static com.bloxbean.cardano.client.common.CardanoConstants.LOVELACE; 25 | import static com.bloxbean.cardano.client.function.helper.AuxDataProviders.metadataProvider; 26 | import static com.bloxbean.cardano.client.function.helper.BalanceTxBuilders.balanceTx; 27 | import static com.bloxbean.cardano.client.function.helper.InputBuilders.createFromSender; 28 | import static com.bloxbean.cardano.client.function.helper.MintCreators.mintCreator; 29 | import static com.bloxbean.cardano.client.function.helper.OutputBuilders.createFromMintOutput; 30 | import static com.bloxbean.cardano.client.function.helper.SignerProviders.signerFrom; 31 | import static org.junit.jupiter.api.Assertions.assertTrue; 32 | 33 | //One sender -- 3 Receivers (1 NFT receiver + 1 NFT receiver + 1 Ada receiver) 34 | public class MulitpleMintNFTsWithRefund extends BaseTest { 35 | 36 | @Test 37 | public void run() throws AddressExcepion, CborSerializationException, ApiException { 38 | new MulitpleMintNFTsWithRefund().mintToken(); 39 | } 40 | 41 | public void mintToken() throws CborSerializationException, ApiException, AddressExcepion { 42 | String senderMnemonic = "kit color frog trick speak employ suit sort bomb goddess jewel primary spoil fade person useless measure manage warfare reduce few scrub beyond era"; 43 | Account sender = new Account(Networks.testnet(), senderMnemonic); 44 | String senderAddress = sender.baseAddress(); 45 | 46 | String receiver1 = "addr_test1qqwpl7h3g84mhr36wpetk904p7fchx2vst0z696lxk8ujsjyruqwmlsm344gfux3nsj6njyzj3ppvrqtt36cp9xyydzqzumz82"; 47 | String receiver2 = "addr_test1qq9f6hzuwmqpe3p9h90z2rtgs0v0lsq9ln5f79fjyec7eclg7v88q9als70uzkdh5k6hw20uuwqfz477znfp5v4rga2s3ysgxu"; 48 | String receiver3 = "addr_test1qqqvjp4ffcdqg3fmx0k8rwamnn06wp8e575zcv8d0m3tjn2mmexsnkxp7az774522ce4h3qs4tjp9rxjjm46qf339d9sk33rqn"; 49 | 50 | Policy policy = PolicyUtil.createMultiSigScriptAllPolicy("policy-1", 1); 51 | 52 | //Multi asset and NFT metadata 53 | //NFT-1 54 | MultiAsset multiAsset1 = new MultiAsset(); 55 | multiAsset1.setPolicyId(policy.getPolicyId()); 56 | Asset asset = new Asset("TestNFT", BigInteger.valueOf(1)); 57 | multiAsset1.getAssets().add(asset); 58 | 59 | NFT nft1 = NFT.create() 60 | .assetName(asset.getName()) 61 | .name(asset.getName()) 62 | .image("ipfs://Qmcv6hwtmdVumrNeb42R1KmCEWdYWGcqNgs17Y3hj6CkP4") 63 | .mediaType("image/png") 64 | .addFile(NFTFile.create() 65 | .name("file-1") 66 | .mediaType("image/png") 67 | .src("ipfs/Qmcv6hwtmdVumrNeb42R1KmCEWdYWGcqNgs17Y3hj6CkP4")) 68 | .description("This is a test NFT"); 69 | 70 | //NFT-2 71 | MultiAsset multiAsset2 = new MultiAsset(); 72 | multiAsset2.setPolicyId(policy.getPolicyId()); 73 | Asset asset2 = new Asset("TestNFT2", BigInteger.valueOf(1)); 74 | multiAsset2.getAssets().add(asset2); 75 | 76 | NFT nft2 = NFT.create() 77 | .assetName(asset2.getName()) 78 | .name(asset2.getName()) 79 | .image("ipfs://Qmcv6hwtmdVumrNeb42R1KmCEWdYWGcqNgs17Y3hj6CkP4") 80 | .mediaType("image/png") 81 | .addFile(NFTFile.create() 82 | .name("file-1") 83 | .mediaType("image/png") 84 | .src("ipfs/Qmcv6hwtmdVumrNeb42R1KmCEWdYWGcqNgs17Y3hj6CkP4")) 85 | .description("This is a test NFT"); 86 | 87 | NFTMetadata nftMetadata = NFTMetadata.create() 88 | .version("1.0") 89 | .addNFT(policy.getPolicyId(), nft1) 90 | .addNFT(policy.getPolicyId(), nft2); 91 | 92 | //Define outputs 93 | //Output using TransactionOutput 94 | TransactionOutput mintOutput1 = TransactionOutput.builder() 95 | .address(receiver1) 96 | .value(Value.builder().coin(adaToLovelace(2)) 97 | .multiAssets(List.of(multiAsset1)).build()).build(); 98 | 99 | TransactionOutput mintOutput2 = TransactionOutput.builder() 100 | .address(receiver2) 101 | .value(Value.builder().coin(adaToLovelace(3)) 102 | .multiAssets(List.of(multiAsset2)).build()).build(); 103 | 104 | //Output using new Output class 105 | Output output3 = Output.builder() 106 | .address(receiver3) 107 | .assetName(LOVELACE) 108 | .qty(adaToLovelace(4.5)).build(); 109 | 110 | MultiAsset mergeMultiAsset = multiAsset1.plus(multiAsset2); 111 | 112 | //Create TxBuilder function 113 | TxBuilder txBuilder = 114 | createFromMintOutput(mintOutput1) 115 | .and(createFromMintOutput(mintOutput2)) 116 | .and(createFromMintOutput(output3)) 117 | .buildInputs(createFromSender(senderAddress, senderAddress)) 118 | .andThen(mintCreator(policy.getPolicyScript(), mergeMultiAsset)) 119 | .andThen(metadataProvider(nftMetadata)) 120 | .andThen(balanceTx(senderAddress, 2)); 121 | 122 | //Build and sign transaction 123 | Transaction signedTransaction = TxBuilderContext.init(utxoSupplier, protocolParamsSupplier) 124 | .buildAndSign(txBuilder, signerFrom(sender).andThen(signerFrom(policy))); 125 | 126 | Result result = transactionService.submitTransaction(signedTransaction.serialize()); 127 | System.out.println(result); 128 | 129 | if (result.isSuccessful()) 130 | System.out.println("Transaction Id: " + result.getValue()); 131 | else 132 | System.out.println("Transaction failed: " + result); 133 | 134 | assertTrue(result.isSuccessful()); 135 | waitForTransactionHash(result); 136 | } 137 | } 138 | -------------------------------------------------------------------------------- /src/test/java/com/bloxbean/cardano/client/example/quicktx/AlwaysTrueScriptTest.java: -------------------------------------------------------------------------------- 1 | package com.bloxbean.cardano.client.example.quicktx; 2 | 3 | import com.bloxbean.cardano.client.address.AddressProvider; 4 | import com.bloxbean.cardano.client.api.exception.ApiException; 5 | import com.bloxbean.cardano.client.api.model.Amount; 6 | import com.bloxbean.cardano.client.api.model.Result; 7 | import com.bloxbean.cardano.client.api.model.Utxo; 8 | import com.bloxbean.cardano.client.common.model.Networks; 9 | import com.bloxbean.cardano.client.function.helper.ScriptUtxoFinders; 10 | import com.bloxbean.cardano.client.function.helper.SignerProviders; 11 | import com.bloxbean.cardano.client.plutus.spec.BigIntPlutusData; 12 | import com.bloxbean.cardano.client.plutus.spec.PlutusV2Script; 13 | import com.bloxbean.cardano.client.quicktx.QuickTxBuilder; 14 | import com.bloxbean.cardano.client.quicktx.ScriptTx; 15 | import com.bloxbean.cardano.client.quicktx.Tx; 16 | import org.junit.jupiter.api.Test; 17 | 18 | import java.math.BigInteger; 19 | import java.util.Optional; 20 | import java.util.Random; 21 | 22 | import static org.junit.jupiter.api.Assertions.assertTrue; 23 | 24 | /** 25 | * Simple script tx example, which 26 | * 1. locks funds to a script address 27 | * 2. unlocks funds from the script address 28 | */ 29 | public class AlwaysTrueScriptTest extends QuickTxBaseTest { 30 | 31 | @Test 32 | void alwaysTrueScript() throws ApiException, InterruptedException { 33 | PlutusV2Script plutusScript = PlutusV2Script.builder() 34 | .type("PlutusScriptV2") 35 | .cborHex("49480100002221200101") 36 | .build(); 37 | 38 | String scriptAddress = AddressProvider.getEntAddress(plutusScript, Networks.testnet()).toBech32(); 39 | BigInteger scriptAmt = new BigInteger("2479280"); 40 | 41 | Random rand = new Random(); 42 | int randInt = rand.nextInt(); 43 | BigIntPlutusData plutusData = new BigIntPlutusData(BigInteger.valueOf(randInt)); //any random number 44 | 45 | System.out.println("Trying to lock fund --------"); 46 | lockFund(scriptAddress, scriptAmt, plutusData); 47 | 48 | System.out.println("Trying to unlock fund --------"); 49 | //Script tx 50 | Optional optionalUtxo = ScriptUtxoFinders.findFirstByInlineDatum(utxoSupplier, scriptAddress, plutusData); 51 | ScriptTx scriptTx = new ScriptTx() 52 | .collectFrom(optionalUtxo.get(), plutusData) 53 | .payToAddress(receiver1Addr, Amount.lovelace(scriptAmt)) 54 | .attachSpendingValidator(plutusScript); 55 | 56 | QuickTxBuilder quickTxBuilder = new QuickTxBuilder(backendService); 57 | Result result1 = quickTxBuilder.compose(scriptTx) 58 | .feePayer(sender1Addr) 59 | .withSigner(SignerProviders.signerFrom(sender1)) 60 | .completeAndWait(System.out::println); 61 | 62 | System.out.println(result1.getResponse()); 63 | assertTrue(result1.isSuccessful()); 64 | } 65 | 66 | private void lockFund(String scriptAddress, BigInteger scriptAmt, BigIntPlutusData plutusData) { 67 | Tx tx = new Tx(); 68 | tx.payToContract(scriptAddress, Amount.lovelace(scriptAmt), plutusData) 69 | .from(sender2Addr); 70 | 71 | QuickTxBuilder quickTxBuilder = new QuickTxBuilder(backendService); 72 | Result result = quickTxBuilder.compose(tx) 73 | .withSigner(SignerProviders.signerFrom(sender2)) 74 | .completeAndWait(System.out::println); 75 | 76 | System.out.println(result.getResponse()); 77 | checkIfUtxoAvailable(result.getValue(), scriptAddress); 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /src/test/java/com/bloxbean/cardano/client/example/quicktx/Minting.java: -------------------------------------------------------------------------------- 1 | package com.bloxbean.cardano.client.example.quicktx; 2 | 3 | import com.bloxbean.cardano.client.api.model.Amount; 4 | import com.bloxbean.cardano.client.api.model.Result; 5 | import com.bloxbean.cardano.client.api.util.PolicyUtil; 6 | import com.bloxbean.cardano.client.cip.cip20.MessageMetadata; 7 | import com.bloxbean.cardano.client.exception.CborSerializationException; 8 | import com.bloxbean.cardano.client.function.helper.SignerProviders; 9 | import com.bloxbean.cardano.client.quicktx.QuickTxBuilder; 10 | import com.bloxbean.cardano.client.quicktx.Tx; 11 | import com.bloxbean.cardano.client.transaction.spec.Asset; 12 | import com.bloxbean.cardano.client.transaction.spec.Policy; 13 | import org.junit.jupiter.api.Test; 14 | 15 | import java.math.BigInteger; 16 | 17 | import static com.bloxbean.cardano.client.common.ADAConversionUtil.adaToLovelace; 18 | import static com.bloxbean.cardano.client.common.CardanoConstants.LOVELACE; 19 | import static org.junit.jupiter.api.Assertions.assertTrue; 20 | 21 | public class Minting extends QuickTxBaseTest { 22 | 23 | //This is an example of simple minting by one account 24 | @Test 25 | void minting() throws CborSerializationException { 26 | Policy policy = PolicyUtil.createMultiSigScriptAtLeastPolicy("test_policy", 1, 1); 27 | String assetName = "MyAsset"; 28 | BigInteger qty = BigInteger.valueOf(1000); 29 | 30 | Tx tx = new Tx() 31 | .mintAssets(policy.getPolicyScript(), new Asset(assetName, qty), sender1.baseAddress()) 32 | .attachMetadata(MessageMetadata.create().add("Minting tx")) 33 | .from(sender1.baseAddress()); 34 | 35 | QuickTxBuilder quickTxBuilder = new QuickTxBuilder(backendService); 36 | Result result = quickTxBuilder.compose(tx) 37 | .withSigner(SignerProviders.signerFrom(sender1)) 38 | .withSigner(SignerProviders.signerFrom(policy)) 39 | .complete(); 40 | 41 | System.out.println(result); 42 | waitForTransactionHash(result); 43 | } 44 | 45 | //This is a composed transaction with minting and regular transfer 46 | @Test 47 | void minting_withTransfer() throws CborSerializationException { 48 | Policy policy = PolicyUtil.createMultiSigScriptAtLeastPolicy("test_policy", 1, 1); 49 | String assetName = "MyAsset"; 50 | BigInteger qty = BigInteger.valueOf(2000); 51 | 52 | Tx tx1 = new Tx() 53 | .payToAddress(receiver1Addr, Amount.ada(1.5)) 54 | .mintAssets(policy.getPolicyScript(), new Asset(assetName, qty), receiver2Addr) 55 | .attachMetadata(MessageMetadata.create().add("Minting tx")) 56 | .from(sender1Addr); 57 | 58 | Tx tx2 = new Tx() 59 | .payToAddress(receiver2Addr, new Amount(LOVELACE, adaToLovelace(2.13))) 60 | .from(sender2Addr); 61 | 62 | QuickTxBuilder quickTxBuilder = new QuickTxBuilder(backendService); 63 | Result result = quickTxBuilder.compose(tx1, tx2) 64 | .feePayer(sender1.baseAddress()) 65 | .withSigner(SignerProviders.signerFrom(sender1) 66 | .andThen(SignerProviders.signerFrom(sender2))) 67 | .withSigner(SignerProviders.signerFrom(policy)) 68 | .additionalSignersCount(1) //As we have composed TxSigners from 2 signers, we need to add 1 additional signer, 69 | // as it's hard to determine how many signers are in the composed TxSigner. Alternatively, just keep adding 70 | //different signers with withSigner() method call. 71 | .completeAndWait(System.out::println); 72 | 73 | System.out.println(result); 74 | assertTrue(result.isSuccessful()); 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /src/test/java/com/bloxbean/cardano/client/example/quicktx/MultiScriptMinting.java: -------------------------------------------------------------------------------- 1 | package com.bloxbean.cardano.client.example.quicktx; 2 | 3 | import com.bloxbean.cardano.client.api.model.Result; 4 | import com.bloxbean.cardano.client.exception.CborSerializationException; 5 | import com.bloxbean.cardano.client.function.helper.SignerProviders; 6 | import com.bloxbean.cardano.client.plutus.blueprint.PlutusBlueprintUtil; 7 | import com.bloxbean.cardano.client.plutus.blueprint.model.PlutusVersion; 8 | import com.bloxbean.cardano.client.plutus.spec.BigIntPlutusData; 9 | import com.bloxbean.cardano.client.plutus.spec.PlutusScript; 10 | import com.bloxbean.cardano.client.quicktx.QuickTxBuilder; 11 | import com.bloxbean.cardano.client.quicktx.ScriptTx; 12 | import com.bloxbean.cardano.client.transaction.spec.Asset; 13 | import com.bloxbean.cardano.client.util.JsonUtil; 14 | import org.junit.jupiter.api.Test; 15 | 16 | import java.math.BigInteger; 17 | 18 | import static org.junit.jupiter.api.Assertions.assertTrue; 19 | 20 | public class MultiScriptMinting extends QuickTxBaseTest { 21 | 22 | @Test 23 | void multi_minting() throws CborSerializationException { 24 | String aikenCompiledCode1 = "581801000032223253330043370e00290010a4c2c6eb40095cd1"; //redeemer = 1 25 | PlutusScript plutusScript1 = PlutusBlueprintUtil.getPlutusScriptFromCompiledCode(aikenCompiledCode1, PlutusVersion.v2); 26 | 27 | String aikenCompileCode2 = "581801000032223253330043370e00290020a4c2c6eb40095cd1"; //redeemer = 2 28 | PlutusScript plutusScript2 = PlutusBlueprintUtil.getPlutusScriptFromCompiledCode(aikenCompileCode2, PlutusVersion.v2); 29 | 30 | String aikenCompileCode3 = "581801000032223253330043370e00290030a4c2c6eb40095cd1"; 31 | PlutusScript plutusScript3 = PlutusBlueprintUtil.getPlutusScriptFromCompiledCode(aikenCompileCode3, PlutusVersion.v2); 32 | 33 | Asset asset1 = new Asset("PlutusMintToken-1", BigInteger.valueOf(8000)); 34 | Asset asset2 = new Asset("PlutusMintToken-2", BigInteger.valueOf(5000)); 35 | Asset asset3 = new Asset("PlutusMintToken-3", BigInteger.valueOf(2000)); 36 | 37 | System.out.println("policy 1: " + plutusScript1.getPolicyId()); 38 | System.out.println("policy 2: " + plutusScript2.getPolicyId()); 39 | 40 | ScriptTx scriptTx = new ScriptTx() 41 | .mintAsset(plutusScript1, asset1, BigIntPlutusData.of(1), receiver1Addr) 42 | .mintAsset(plutusScript2, asset2, BigIntPlutusData.of(2), sender1Addr) 43 | .mintAsset(plutusScript3, asset3, BigIntPlutusData.of(3), receiver1Addr) 44 | .withChangeAddress(sender2Addr); 45 | 46 | QuickTxBuilder quickTxBuilder = new QuickTxBuilder(backendService); 47 | Result result1 = quickTxBuilder.compose(scriptTx) 48 | .feePayer(sender2Addr) 49 | .withSigner(SignerProviders.signerFrom(sender2)) 50 | .mergeOutputs(false) 51 | .withTxInspector(tx -> System.out.println(JsonUtil.getPrettyJson(tx))) 52 | .completeAndWait(System.out::println); 53 | 54 | System.out.println(result1.getResponse()); 55 | assertTrue(result1.isSuccessful()); 56 | 57 | checkIfUtxoAvailable(result1.getValue(), sender2Addr); 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /src/test/java/com/bloxbean/cardano/client/example/quicktx/P2PNFTTransfer.java: -------------------------------------------------------------------------------- 1 | package com.bloxbean.cardano.client.example.quicktx; 2 | 3 | import com.bloxbean.cardano.client.account.Account; 4 | import com.bloxbean.cardano.client.api.MinAdaCalculator; 5 | import com.bloxbean.cardano.client.api.exception.ApiException; 6 | import com.bloxbean.cardano.client.api.model.Amount; 7 | import com.bloxbean.cardano.client.api.model.Result; 8 | import com.bloxbean.cardano.client.api.model.Utxo; 9 | import com.bloxbean.cardano.client.api.util.PolicyUtil; 10 | import com.bloxbean.cardano.client.backend.api.BackendService; 11 | import com.bloxbean.cardano.client.backend.api.DefaultUtxoSupplier; 12 | import com.bloxbean.cardano.client.backend.blockfrost.common.Constants; 13 | import com.bloxbean.cardano.client.backend.blockfrost.service.BFBackendService; 14 | import com.bloxbean.cardano.client.common.model.Networks; 15 | import com.bloxbean.cardano.client.example.Constant; 16 | import com.bloxbean.cardano.client.exception.CborSerializationException; 17 | import com.bloxbean.cardano.client.function.helper.OutputMergers; 18 | import com.bloxbean.cardano.client.function.helper.SignerProviders; 19 | import com.bloxbean.cardano.client.quicktx.QuickTxBuilder; 20 | import com.bloxbean.cardano.client.quicktx.Tx; 21 | import com.bloxbean.cardano.client.transaction.spec.*; 22 | import com.bloxbean.cardano.client.util.HexUtil; 23 | 24 | import java.math.BigInteger; 25 | import java.util.List; 26 | import java.util.Optional; 27 | import java.util.UUID; 28 | 29 | import static com.bloxbean.cardano.client.common.ADAConversionUtil.adaToLovelace; 30 | 31 | public class P2PNFTTransfer { 32 | String party1Mnemonic = "kit color frog trick speak employ suit sort bomb goddess jewel primary spoil fade person useless measure manage warfare reduce few scrub beyond era"; 33 | Account party1 = new Account(Networks.testnet(), party1Mnemonic); 34 | String party1Addr = party1.baseAddress(); 35 | 36 | String party2Mnemonic = "essence pilot click armor alpha noise mixture soldier able advice multiply inject ticket pride airport uncover honey desert curtain sun true toast valve half"; 37 | Account party2 = new Account(Networks.testnet(), party2Mnemonic); 38 | String party2Addr = party2.baseAddress(); 39 | 40 | BackendService backendService = new BFBackendService(Constants.BLOCKFROST_PREPROD_URL, Constant.BF_PROJECT_KEY); 41 | 42 | private Policy policy; 43 | Asset asset; 44 | BigInteger NFT_PRICE = adaToLovelace(10); 45 | 46 | public void testP2PTransaction() throws Exception { 47 | //create NFT in sender's wallet 48 | setupNTFs(); 49 | 50 | //calculate min ADA required when there's a single NFT in the UTXO 51 | //This is required to calculate the min ADA required to send the NFT to receiver 52 | //Party-2 needs to pay nft price + min ADA to party-1 53 | BigInteger minAda = calculateMinAdaInUtxo(); 54 | 55 | //Sender Part - Party1 56 | //create P2P transaction 57 | Tx party1Tx = new Tx() 58 | .payToAddress(party2Addr, Amount.asset(policy.getPolicyId(), asset.getName(), 1)) 59 | .from(party1Addr); 60 | 61 | Tx party2Tx = new Tx() 62 | .payToAddress(party1Addr, Amount.lovelace(NFT_PRICE.add(minAda))) 63 | .from(party2Addr); 64 | 65 | Transaction transaction = new QuickTxBuilder(backendService) 66 | .compose(party1Tx, party2Tx) 67 | .feePayer(party2Addr) 68 | .preBalanceTx((context, tx) -> { 69 | OutputMergers.mergeOutputsForAddress(party1Addr).apply(context, tx); 70 | OutputMergers.mergeOutputsForAddress(party2Addr).apply(context, tx); 71 | }) 72 | .withSigner(SignerProviders.signerFrom(party1)) //signer for party1 73 | .buildAndSign(); 74 | 75 | //Serialize this transaction and send it to receiver 76 | String serializedTx = transaction.serializeToHex(); 77 | 78 | //Reciver Part - Party2 79 | //Deserialize the transaction 80 | Transaction deserializedTx = Transaction.deserialize(HexUtil.decodeHexString(serializedTx)); 81 | Transaction finalTx = party2.sign(deserializedTx); 82 | 83 | //Submit the final signed transaction 84 | Result result = backendService.getTransactionService().submitTransaction(finalTx.serialize()); 85 | System.out.println(result); 86 | 87 | if (result.isSuccessful()) 88 | checkIfUtxoAvailable(result.getValue(), party2Addr); 89 | } 90 | 91 | private BigInteger calculateMinAdaInUtxo() throws ApiException, CborSerializationException { 92 | MinAdaCalculator minAdaCalculator = new MinAdaCalculator(backendService.getEpochService().getProtocolParameters().getValue()); 93 | BigInteger minAda = minAdaCalculator.calculateMinAda(TransactionOutput.builder() 94 | .address(party2Addr) 95 | .value(Value.builder() 96 | .multiAssets(List.of( 97 | MultiAsset.builder() 98 | .policyId(policy.getPolicyId()) 99 | .assets( 100 | List.of( 101 | new Asset(asset.getName(), new BigInteger("1")) 102 | ) 103 | ).build() 104 | )) 105 | .build()).build()); 106 | 107 | return minAda; 108 | } 109 | 110 | private void setupNTFs() throws Exception { 111 | policy = PolicyUtil.createMultiSigScriptAtLeastPolicy("policy", 1, 1); 112 | asset = new Asset(UUID.randomUUID().toString().substring(0, 5), new BigInteger("1")); 113 | 114 | Tx tx = new Tx() 115 | .mintAssets(policy.getPolicyScript(), asset, party1Addr) 116 | .from(party1Addr); 117 | Result result = new QuickTxBuilder(backendService) 118 | .compose(tx) 119 | .withSigner(SignerProviders.signerFrom(party1)) 120 | .withSigner(SignerProviders.signerFrom(policy)) 121 | .completeAndWait(System.out::println); 122 | 123 | System.out.println(result); 124 | if (result.isSuccessful()) 125 | checkIfUtxoAvailable(result.getValue(), party1Addr); 126 | } 127 | 128 | protected void checkIfUtxoAvailable(String txHash, String address) { 129 | Optional utxo = Optional.empty(); 130 | int count = 0; 131 | while (utxo.isEmpty()) { 132 | if (count++ >= 20) 133 | break; 134 | List utxos = new DefaultUtxoSupplier(backendService.getUtxoService()).getAll(address); 135 | utxo = utxos.stream().filter(u -> u.getTxHash().equals(txHash)) 136 | .findFirst(); 137 | System.out.println("Try to get new output... txhash: " + txHash); 138 | try { 139 | Thread.sleep(1000); 140 | } catch (Exception e) { 141 | } 142 | } 143 | } 144 | 145 | public static void main(String[] args) throws Exception { 146 | P2PNFTTransfer p2PTest = new P2PNFTTransfer(); 147 | p2PTest.testP2PTransaction(); 148 | } 149 | } 150 | -------------------------------------------------------------------------------- /src/test/java/com/bloxbean/cardano/client/example/quicktx/QuickTxBaseTest.java: -------------------------------------------------------------------------------- 1 | package com.bloxbean.cardano.client.example.quicktx; 2 | 3 | import co.nstant.in.cbor.CborException; 4 | import co.nstant.in.cbor.model.ByteString; 5 | import com.bloxbean.cardano.client.account.Account; 6 | import com.bloxbean.cardano.client.api.model.Utxo; 7 | import com.bloxbean.cardano.client.backend.api.DefaultUtxoSupplier; 8 | import com.bloxbean.cardano.client.common.cbor.CborSerializationUtil; 9 | import com.bloxbean.cardano.client.common.model.Networks; 10 | import com.bloxbean.cardano.client.example.BaseTest; 11 | import com.bloxbean.cardano.client.plutus.spec.PlutusV2Script; 12 | import com.bloxbean.cardano.client.util.HexUtil; 13 | 14 | import java.util.List; 15 | import java.util.Optional; 16 | 17 | public class QuickTxBaseTest extends BaseTest { 18 | String sender1Mnemonic = "kit color frog trick speak employ suit sort bomb goddess jewel primary spoil fade person useless measure manage warfare reduce few scrub beyond era"; 19 | Account sender1 = new Account(Networks.testnet(), sender1Mnemonic); 20 | String sender1Addr = sender1.baseAddress(); 21 | 22 | String sender2Mnemonic = "essence pilot click armor alpha noise mixture soldier able advice multiply inject ticket pride airport uncover honey desert curtain sun true toast valve half"; 23 | Account sender2 = new Account(Networks.testnet(), sender2Mnemonic); 24 | String sender2Addr = sender2.baseAddress(); 25 | 26 | String receiver1Addr = "addr_test1qqwpl7h3g84mhr36wpetk904p7fchx2vst0z696lxk8ujsjyruqwmlsm344gfux3nsj6njyzj3ppvrqtt36cp9xyydzqzumz82"; 27 | String receiver2Addr = "addr_test1qqqvjp4ffcdqg3fmx0k8rwamnn06wp8e575zcv8d0m3tjn2mmexsnkxp7az774522ce4h3qs4tjp9rxjjm46qf339d9sk33rqn"; 28 | 29 | protected void checkIfUtxoAvailable(String txHash, String address) { 30 | Optional utxo = Optional.empty(); 31 | int count = 0; 32 | while (utxo.isEmpty()) { 33 | if (count++ >= 20) 34 | break; 35 | List utxos = new DefaultUtxoSupplier(backendService.getUtxoService()).getAll(address); 36 | utxo = utxos.stream().filter(u -> u.getTxHash().equals(txHash)) 37 | .findFirst(); 38 | System.out.println("Try to get new output... txhash: " + txHash); 39 | try { 40 | Thread.sleep(1000); 41 | } catch (Exception e) {} 42 | } 43 | } 44 | 45 | } 46 | -------------------------------------------------------------------------------- /src/test/java/com/bloxbean/cardano/client/example/quicktx/ReferenceInputScriptTest.java: -------------------------------------------------------------------------------- 1 | package com.bloxbean.cardano.client.example.quicktx; 2 | 3 | import com.bloxbean.cardano.client.address.AddressProvider; 4 | import com.bloxbean.cardano.client.api.exception.ApiException; 5 | import com.bloxbean.cardano.client.api.model.Amount; 6 | import com.bloxbean.cardano.client.api.model.Result; 7 | import com.bloxbean.cardano.client.api.model.Utxo; 8 | import com.bloxbean.cardano.client.common.model.Networks; 9 | import com.bloxbean.cardano.client.function.helper.ScriptUtxoFinders; 10 | import com.bloxbean.cardano.client.function.helper.SignerProviders; 11 | import com.bloxbean.cardano.client.plutus.spec.BigIntPlutusData; 12 | import com.bloxbean.cardano.client.plutus.spec.PlutusData; 13 | import com.bloxbean.cardano.client.plutus.spec.PlutusV2Script; 14 | import com.bloxbean.cardano.client.quicktx.QuickTxBuilder; 15 | import com.bloxbean.cardano.client.quicktx.ScriptTx; 16 | import com.bloxbean.cardano.client.quicktx.Tx; 17 | import org.junit.jupiter.api.Test; 18 | 19 | import java.math.BigInteger; 20 | import java.util.List; 21 | import java.util.Optional; 22 | 23 | import static org.junit.jupiter.api.Assertions.assertTrue; 24 | 25 | /** 26 | * Example to show how to use reference input in a script tx 27 | */ 28 | public class ReferenceInputScriptTest extends QuickTxBaseTest { 29 | @Test 30 | void referenceInputUtxo_guessSumScript() throws ApiException, InterruptedException { 31 | //Sum Script 32 | PlutusV2Script sumScript = 33 | PlutusV2Script.builder() 34 | .cborHex("5907a65907a3010000323322323232323232323232323232323322323232323222232325335323232333573466e1ccc07000d200000201e01d3333573466e1cd55cea80224000466442466002006004646464646464646464646464646666ae68cdc39aab9d500c480008cccccccccccc88888888888848cccccccccccc00403403002c02802402001c01801401000c008cd405c060d5d0a80619a80b80c1aba1500b33501701935742a014666aa036eb94068d5d0a804999aa80dbae501a35742a01066a02e0446ae85401cccd5406c08dd69aba150063232323333573466e1cd55cea801240004664424660020060046464646666ae68cdc39aab9d5002480008cc8848cc00400c008cd40b5d69aba15002302e357426ae8940088c98c80c0cd5ce01881801709aab9e5001137540026ae854008c8c8c8cccd5cd19b8735573aa004900011991091980080180119a816bad35742a004605c6ae84d5d1280111931901819ab9c03103002e135573ca00226ea8004d5d09aba2500223263202c33573805a05805426aae7940044dd50009aba1500533501775c6ae854010ccd5406c07c8004d5d0a801999aa80dbae200135742a00460426ae84d5d1280111931901419ab9c029028026135744a00226ae8940044d5d1280089aba25001135744a00226ae8940044d5d1280089aba25001135744a00226ae8940044d55cf280089baa00135742a00860226ae84d5d1280211931900d19ab9c01b01a018375a00a6eb4014405c4c98c805ccd5ce24810350543500017135573ca00226ea800448c88c008dd6000990009aa80b911999aab9f0012500a233500930043574200460066ae880080508c8c8cccd5cd19b8735573aa004900011991091980080180118061aba150023005357426ae8940088c98c8050cd5ce00a80a00909aab9e5001137540024646464646666ae68cdc39aab9d5004480008cccc888848cccc00401401000c008c8c8c8cccd5cd19b8735573aa0049000119910919800801801180a9aba1500233500f014357426ae8940088c98c8064cd5ce00d00c80b89aab9e5001137540026ae854010ccd54021d728039aba150033232323333573466e1d4005200423212223002004357426aae79400c8cccd5cd19b875002480088c84888c004010dd71aba135573ca00846666ae68cdc3a801a400042444006464c6403666ae7007006c06406005c4d55cea80089baa00135742a00466a016eb8d5d09aba2500223263201533573802c02a02626ae8940044d5d1280089aab9e500113754002266aa002eb9d6889119118011bab00132001355014223233335573e0044a010466a00e66442466002006004600c6aae754008c014d55cf280118021aba200301213574200222440042442446600200800624464646666ae68cdc3a800a40004642446004006600a6ae84d55cf280191999ab9a3370ea0049001109100091931900819ab9c01101000e00d135573aa00226ea80048c8c8cccd5cd19b875001480188c848888c010014c01cd5d09aab9e500323333573466e1d400920042321222230020053009357426aae7940108cccd5cd19b875003480088c848888c004014c01cd5d09aab9e500523333573466e1d40112000232122223003005375c6ae84d55cf280311931900819ab9c01101000e00d00c00b135573aa00226ea80048c8c8cccd5cd19b8735573aa004900011991091980080180118029aba15002375a6ae84d5d1280111931900619ab9c00d00c00a135573ca00226ea80048c8cccd5cd19b8735573aa002900011bae357426aae7940088c98c8028cd5ce00580500409baa001232323232323333573466e1d4005200c21222222200323333573466e1d4009200a21222222200423333573466e1d400d2008233221222222233001009008375c6ae854014dd69aba135744a00a46666ae68cdc3a8022400c4664424444444660040120106eb8d5d0a8039bae357426ae89401c8cccd5cd19b875005480108cc8848888888cc018024020c030d5d0a8049bae357426ae8940248cccd5cd19b875006480088c848888888c01c020c034d5d09aab9e500b23333573466e1d401d2000232122222223005008300e357426aae7940308c98c804ccd5ce00a00980880800780700680600589aab9d5004135573ca00626aae7940084d55cf280089baa0012323232323333573466e1d400520022333222122333001005004003375a6ae854010dd69aba15003375a6ae84d5d1280191999ab9a3370ea0049000119091180100198041aba135573ca00c464c6401866ae700340300280244d55cea80189aba25001135573ca00226ea80048c8c8cccd5cd19b875001480088c8488c00400cdd71aba135573ca00646666ae68cdc3a8012400046424460040066eb8d5d09aab9e500423263200933573801401200e00c26aae7540044dd500089119191999ab9a3370ea00290021091100091999ab9a3370ea00490011190911180180218031aba135573ca00846666ae68cdc3a801a400042444004464c6401466ae7002c02802001c0184d55cea80089baa0012323333573466e1d40052002200923333573466e1d40092000200923263200633573800e00c00800626aae74dd5000a4c240029210350543100320013550032225335333573466e1c0092000005004100113300333702004900119b80002001122002122001112323001001223300330020020011") 35 | .build(); 36 | String sumScriptAddr = AddressProvider.getEntAddress(sumScript, Networks.testnet()).toBech32(); 37 | Amount sumScriptAmt = Amount.ada(4.0); 38 | PlutusData sumScriptDatum = new BigIntPlutusData(BigInteger.valueOf(8)); //redeemer should be 36 39 | PlutusData sumScriptRedeemer = new BigIntPlutusData(BigInteger.valueOf(36)); 40 | 41 | /**** Create reference input and Lock funds to script address ****/ 42 | //Create a reference input and send lock amount at script address 43 | Tx createRefInputTx = new Tx(); 44 | createRefInputTx.payToAddress(receiver1Addr, List.of(Amount.ada(1.0)), sumScript) 45 | .from(sender1Addr); 46 | 47 | Tx scriptPayTx = new Tx(); 48 | scriptPayTx.payToContract(sumScriptAddr, sumScriptAmt, sumScriptDatum) 49 | .from(sender1Addr); 50 | 51 | QuickTxBuilder quickTxBuilder = new QuickTxBuilder(backendService); 52 | Result result = quickTxBuilder.compose(createRefInputTx) 53 | .withSigner(SignerProviders.signerFrom(sender1)) 54 | .completeAndWait(System.out::println); 55 | System.out.println("Tx Response: " + result.getResponse()); 56 | assertTrue(result.isSuccessful()); 57 | 58 | //Required as backend service returns outdated utxo 59 | if (result.isSuccessful()) { 60 | checkIfUtxoAvailable(result.getValue(), sender1Addr); 61 | } 62 | /***** End of reference input creation and lock funds to script address ****/ 63 | 64 | Utxo refUtxo = Utxo.builder() 65 | .txHash(result.getValue()) 66 | .outputIndex(0) 67 | .build(); 68 | 69 | //Find the utxo for the script address 70 | Optional sumUtxo = ScriptUtxoFinders.findFirstByInlineDatum(utxoSupplier, sumScriptAddr, sumScriptDatum); 71 | 72 | //Script tx 73 | ScriptTx scriptTx = new ScriptTx() 74 | .collectFrom(sumUtxo.get(), sumScriptRedeemer) 75 | .readFrom(refUtxo) 76 | .payToAddress(receiver1Addr, List.of(sumScriptAmt)) 77 | .withChangeAddress(sumScriptAddr, sumScriptDatum); 78 | 79 | Result result1 = quickTxBuilder.compose(scriptTx) 80 | .feePayer(sender1Addr) 81 | .withSigner(SignerProviders.signerFrom(sender1)) 82 | .completeAndWait(System.out::println); 83 | 84 | System.out.println(result1.getResponse()); 85 | assertTrue(result1.isSuccessful()); 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /src/test/java/com/bloxbean/cardano/client/example/quicktx/ScriptStakingTest.java: -------------------------------------------------------------------------------- 1 | package com.bloxbean.cardano.client.example.quicktx; 2 | 3 | import com.bloxbean.cardano.client.address.AddressProvider; 4 | import com.bloxbean.cardano.client.api.model.Result; 5 | import com.bloxbean.cardano.client.cip.cip20.MessageMetadata; 6 | import com.bloxbean.cardano.client.common.model.Networks; 7 | import com.bloxbean.cardano.client.function.helper.SignerProviders; 8 | import com.bloxbean.cardano.client.plutus.blueprint.PlutusBlueprintUtil; 9 | import com.bloxbean.cardano.client.plutus.blueprint.model.PlutusVersion; 10 | import com.bloxbean.cardano.client.plutus.spec.BigIntPlutusData; 11 | import com.bloxbean.cardano.client.plutus.spec.PlutusScript; 12 | import com.bloxbean.cardano.client.quicktx.QuickTxBuilder; 13 | import com.bloxbean.cardano.client.quicktx.ScriptTx; 14 | import com.bloxbean.cardano.client.quicktx.Tx; 15 | import com.bloxbean.cardano.client.util.JsonUtil; 16 | import org.junit.jupiter.api.MethodOrderer; 17 | import org.junit.jupiter.api.Order; 18 | import org.junit.jupiter.api.Test; 19 | import org.junit.jupiter.api.TestMethodOrder; 20 | 21 | import static org.junit.jupiter.api.Assertions.assertTrue; 22 | 23 | @TestMethodOrder(MethodOrderer.OrderAnnotation.class) 24 | public class ScriptStakingTest extends QuickTxBaseTest { 25 | 26 | String aikenCompiledCode1 = "581801000032223253330043370e00290010a4c2c6eb40095cd1"; //redeemer = 1 27 | PlutusScript plutusScript1 = PlutusBlueprintUtil.getPlutusScriptFromCompiledCode(aikenCompiledCode1, PlutusVersion.v2); 28 | 29 | String aikenCompileCode2 = "581801000032223253330043370e00290020a4c2c6eb40095cd1"; //redeemer = 2 30 | PlutusScript plutusScript2 = PlutusBlueprintUtil.getPlutusScriptFromCompiledCode(aikenCompileCode2, PlutusVersion.v2); 31 | 32 | String scriptStakeAddress1 = AddressProvider.getRewardAddress(plutusScript1, Networks.testnet()).toBech32(); 33 | String scriptStakeAddress2 = AddressProvider.getRewardAddress(plutusScript2, Networks.testnet()).toBech32(); 34 | 35 | @Test 36 | @Order(1) 37 | void scriptStakeAddress_registration() { 38 | QuickTxBuilder quickTxBuilder = new QuickTxBuilder(backendService); 39 | Tx tx = new Tx() 40 | .registerStakeAddress(scriptStakeAddress1) 41 | .registerStakeAddress(scriptStakeAddress2) 42 | .attachMetadata(MessageMetadata.create().add("This is a script stake registration tx")) 43 | .from(sender1Addr); 44 | 45 | Result result = quickTxBuilder.compose(tx) 46 | .withSigner(SignerProviders.signerFrom(sender1)) 47 | .withTxInspector((txn) -> System.out.println(JsonUtil.getPrettyJson(txn))) 48 | .completeAndWait(msg -> System.out.println(msg)); 49 | 50 | System.out.println(result); 51 | assertTrue(result.isSuccessful()); 52 | 53 | checkIfUtxoAvailable(result.getValue(), sender1Addr); 54 | } 55 | 56 | @Test 57 | @Order(2) 58 | void scriptStakeAddress_deRegistration() { 59 | QuickTxBuilder quickTxBuilder = new QuickTxBuilder(backendService); 60 | ScriptTx tx = new ScriptTx() 61 | .deregisterStakeAddress(scriptStakeAddress1, BigIntPlutusData.of(1)) 62 | .deregisterStakeAddress(scriptStakeAddress2, BigIntPlutusData.of(2)) 63 | .attachMetadata(MessageMetadata.create().add("This is a script stake address deregistration tx")) 64 | .attachCertificateValidator(plutusScript1) 65 | .attachCertificateValidator(plutusScript2); 66 | 67 | Result result = quickTxBuilder.compose(tx) 68 | .feePayer(sender1Addr) 69 | .withSigner(SignerProviders.signerFrom(sender1)) 70 | .withTxInspector((txn) -> System.out.println(JsonUtil.getPrettyJson(txn))) 71 | .completeAndWait(msg -> System.out.println(msg)); 72 | 73 | System.out.println(result); 74 | assertTrue(result.isSuccessful()); 75 | 76 | checkIfUtxoAvailable(result.getValue(), sender1Addr); 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /src/test/java/com/bloxbean/cardano/client/example/quicktx/SimplePayment.java: -------------------------------------------------------------------------------- 1 | package com.bloxbean.cardano.client.example.quicktx; 2 | 3 | import com.bloxbean.cardano.client.account.Account; 4 | import com.bloxbean.cardano.client.api.model.Amount; 5 | import com.bloxbean.cardano.client.api.model.Result; 6 | import com.bloxbean.cardano.client.cip.cip20.MessageMetadata; 7 | import com.bloxbean.cardano.client.common.model.Networks; 8 | import com.bloxbean.cardano.client.example.BaseTest; 9 | import com.bloxbean.cardano.client.function.helper.SignerProviders; 10 | import com.bloxbean.cardano.client.quicktx.QuickTxBuilder; 11 | import com.bloxbean.cardano.client.quicktx.Tx; 12 | import org.junit.jupiter.api.Test; 13 | 14 | /** 15 | * Simple payments from two accounts 16 | */ 17 | public class SimplePayment extends QuickTxBaseTest { 18 | 19 | @Test 20 | public void transfer() { 21 | Tx tx1 = new Tx() 22 | .payToAddress(receiver1Addr, Amount.ada(1.5)) 23 | .payToAddress(receiver2Addr, Amount.ada(2.5)) 24 | .attachMetadata(MessageMetadata.create().add("This is a test message 2")) 25 | .from(sender1Addr); 26 | 27 | Tx tx2 = new Tx() 28 | .payToAddress(receiver2Addr, Amount.ada(4.5)) 29 | .from(sender2Addr); 30 | 31 | QuickTxBuilder quickTxBuilder = new QuickTxBuilder(backendService); 32 | Result result = quickTxBuilder 33 | .compose(tx1, tx2) 34 | .feePayer(sender1Addr) 35 | .withSigner(SignerProviders.signerFrom(sender1)) 36 | .withSigner(SignerProviders.signerFrom(sender2)) 37 | .completeAndWait(System.out::println); 38 | } 39 | 40 | } 41 | -------------------------------------------------------------------------------- /src/test/java/com/bloxbean/cardano/client/example/quicktx/SimplePaymentDifferentFeePayer.java: -------------------------------------------------------------------------------- 1 | package com.bloxbean.cardano.client.example.quicktx; 2 | 3 | import com.bloxbean.cardano.client.api.model.Amount; 4 | import com.bloxbean.cardano.client.api.model.Result; 5 | import com.bloxbean.cardano.client.cip.cip20.MessageMetadata; 6 | import com.bloxbean.cardano.client.function.helper.SignerProviders; 7 | import com.bloxbean.cardano.client.quicktx.QuickTxBuilder; 8 | import com.bloxbean.cardano.client.quicktx.Tx; 9 | import org.junit.jupiter.api.Test; 10 | 11 | /** 12 | * Simple payments from two accounts 13 | */ 14 | public class SimplePaymentDifferentFeePayer extends QuickTxBaseTest { 15 | 16 | @Test 17 | public void transfer() { 18 | Tx tx1 = new Tx() 19 | .payToAddress(receiver1Addr, Amount.ada(1.5)) 20 | .attachMetadata(MessageMetadata.create().add("This is a test message 2")) 21 | .from(sender1Addr); 22 | 23 | QuickTxBuilder quickTxBuilder = new QuickTxBuilder(backendService); 24 | Result result = quickTxBuilder 25 | .compose(tx1) 26 | .feePayer(sender2Addr) 27 | .withSigner(SignerProviders.signerFrom(sender1)) 28 | .withSigner(SignerProviders.signerFrom(sender2)) 29 | .completeAndWait(System.out::println); 30 | } 31 | 32 | } 33 | -------------------------------------------------------------------------------- /src/test/java/com/bloxbean/cardano/client/example/quicktx/StakingTest.java: -------------------------------------------------------------------------------- 1 | package com.bloxbean.cardano.client.example.quicktx; 2 | 3 | import com.bloxbean.cardano.client.address.Address; 4 | import com.bloxbean.cardano.client.address.AddressProvider; 5 | import com.bloxbean.cardano.client.api.model.Result; 6 | import com.bloxbean.cardano.client.cip.cip20.MessageMetadata; 7 | import com.bloxbean.cardano.client.function.helper.SignerProviders; 8 | import com.bloxbean.cardano.client.quicktx.QuickTxBuilder; 9 | import com.bloxbean.cardano.client.quicktx.Tx; 10 | import com.bloxbean.cardano.client.util.JsonUtil; 11 | import org.junit.jupiter.api.Order; 12 | import org.junit.jupiter.api.Test; 13 | 14 | import static org.junit.jupiter.api.Assertions.assertTrue; 15 | 16 | public class StakingTest extends QuickTxBaseTest { 17 | 18 | @Test 19 | void stakeAddressRegistration_onlyRegistration() { 20 | QuickTxBuilder quickTxBuilder = new QuickTxBuilder(backendService); 21 | Tx tx = new Tx() 22 | .registerStakeAddress(sender1Addr) 23 | .attachMetadata(MessageMetadata.create().add("This is a stake registration tx")) 24 | .from(sender1Addr); 25 | 26 | Result result = quickTxBuilder.compose(tx) 27 | .withSigner(SignerProviders.signerFrom(sender1)) 28 | .withTxInspector((txn) -> System.out.println(JsonUtil.getPrettyJson(txn))) 29 | .completeAndWait(msg -> System.out.println(msg)); 30 | 31 | System.out.println(result); 32 | assertTrue(result.isSuccessful()); 33 | } 34 | 35 | @Test 36 | @Order(4) 37 | void stakeAddressDeRegistration_onlyRegistration() { 38 | QuickTxBuilder quickTxBuilder = new QuickTxBuilder(backendService); 39 | Tx tx = new Tx() 40 | .deregisterStakeAddress(AddressProvider.getStakeAddress(new Address(sender1Addr))) 41 | .attachMetadata(MessageMetadata.create().add("This is a stake deregistration tx")) 42 | .from(sender1Addr); 43 | 44 | Result result = quickTxBuilder.compose(tx) 45 | .withSigner(SignerProviders.signerFrom(sender1)) 46 | .withSigner(SignerProviders.stakeKeySignerFrom(sender1)) 47 | .withTxInspector((txn) -> System.out.println(JsonUtil.getPrettyJson(txn))) 48 | .completeAndWait(msg -> System.out.println(msg)); 49 | 50 | System.out.println(result); 51 | assertTrue(result.isSuccessful()); 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /src/test/java/com/bloxbean/cardano/client/example/timelock/TimeLockScriptWithRegularAddress.java: -------------------------------------------------------------------------------- 1 | package com.bloxbean.cardano.client.example.timelock; 2 | 3 | import com.bloxbean.cardano.client.account.Account; 4 | import com.bloxbean.cardano.client.address.Address; 5 | import com.bloxbean.cardano.client.address.AddressProvider; 6 | import com.bloxbean.cardano.client.api.exception.ApiException; 7 | import com.bloxbean.cardano.client.api.model.Result; 8 | import com.bloxbean.cardano.client.backend.model.Block; 9 | import com.bloxbean.cardano.client.common.model.Networks; 10 | import com.bloxbean.cardano.client.crypto.VerificationKey; 11 | import com.bloxbean.cardano.client.example.BaseTest; 12 | import com.bloxbean.cardano.client.function.Output; 13 | import com.bloxbean.cardano.client.function.TxBuilder; 14 | import com.bloxbean.cardano.client.function.TxBuilderContext; 15 | import com.bloxbean.cardano.client.transaction.spec.Transaction; 16 | import com.bloxbean.cardano.client.transaction.spec.script.*; 17 | import com.bloxbean.cardano.client.util.JsonUtil; 18 | import com.bloxbean.cardano.client.util.Tuple; 19 | import org.junit.jupiter.api.Test; 20 | 21 | import java.util.List; 22 | 23 | import static com.bloxbean.cardano.client.common.ADAConversionUtil.adaToLovelace; 24 | import static com.bloxbean.cardano.client.common.CardanoConstants.LOVELACE; 25 | import static com.bloxbean.cardano.client.function.helper.ChangeOutputAdjustments.adjustChangeOutput; 26 | import static com.bloxbean.cardano.client.function.helper.FeeCalculators.feeCalculator; 27 | import static com.bloxbean.cardano.client.function.helper.InputBuilders.createFromSender; 28 | import static com.bloxbean.cardano.client.function.helper.SignerProviders.signerFrom; 29 | import static org.junit.jupiter.api.Assertions.assertTrue; 30 | 31 | /** 32 | * Example : Create a enterprise address(no staking part) from a Time-lock Native script which is created using a regular account's key as verification key 33 | * - Transfer fund to the newly generated script address 34 | * - After unlocked slot no, transfer fund from script address to another address with signer as original payment account. 35 | */ 36 | public class TimeLockScriptWithRegularAddress extends BaseTest { 37 | String paymentAccMnemonic = "couple pulse brother awake panther garden elder scheme erase bone close estate token receive blossom squirrel report field pioneer project behind abstract enable legend"; 38 | long targetUnlockSlot = 55111682; 39 | 40 | @Test 41 | public void run() throws Exception { 42 | TimeLockScriptWithRegularAddress timeLockScriptWithRegularAddress = new TimeLockScriptWithRegularAddress(); 43 | 44 | //Transfer fund to time-lock script address 45 | timeLockScriptWithRegularAddress.transferToScriptAddress(); 46 | 47 | //Transfer fund from time-lock script address to another address 48 | timeLockScriptWithRegularAddress.transferFromScriptAddress(); 49 | } 50 | 51 | public Tuple createScriptAddress() throws Exception { 52 | Account account = new Account(Networks.testnet(), paymentAccMnemonic); 53 | 54 | //Create Payment part 55 | ScriptPubkey scriptPubkey = ScriptPubkey.create(VerificationKey.create(account.publicKeyBytes())); 56 | RequireTimeAfter requireTimeAfter = new RequireTimeAfter(targetUnlockSlot); 57 | 58 | ScriptAll scriptAll = new ScriptAll() 59 | .addScript(requireTimeAfter) 60 | .addScript(new ScriptAtLeast(1).addScript(scriptPubkey)); 61 | 62 | //Address with only payment part 63 | Address entAddress = AddressProvider.getEntAddress(scriptAll, Networks.testnet()); 64 | System.out.println(entAddress.toBech32()); 65 | 66 | return new Tuple(entAddress.toBech32(), scriptAll); 67 | 68 | } 69 | 70 | public void transferToScriptAddress() throws Exception { 71 | Account sender = new Account(Networks.testnet(), paymentAccMnemonic); 72 | String senderAddress = sender.baseAddress(); 73 | 74 | Tuple scriptTuple = createScriptAddress(); 75 | String scriptAddress = scriptTuple._1; 76 | NativeScript script = scriptTuple._2; 77 | 78 | System.out.println(JsonUtil.getPrettyJson(script)); 79 | 80 | Output output = Output.builder() 81 | .address(scriptAddress) 82 | .assetName(LOVELACE) 83 | .qty(adaToLovelace(6)) 84 | .build(); 85 | 86 | TxBuilder txBuilder = output.outputBuilder() 87 | .buildInputs(createFromSender(senderAddress, senderAddress)) 88 | .andThen(feeCalculator(senderAddress, 1)) 89 | .andThen(adjustChangeOutput(senderAddress, 1)); 90 | 91 | Transaction signedTransaction = TxBuilderContext.init(utxoSupplier, protocolParamsSupplier) 92 | .buildAndSign(txBuilder, signerFrom(sender)); 93 | 94 | Result result = transactionService.submitTransaction(signedTransaction.serialize()); 95 | System.out.println(result); 96 | 97 | if (result.isSuccessful()) 98 | System.out.println("Transaction Id: " + result.getValue()); 99 | else 100 | System.out.println("Transaction failed: " + result); 101 | 102 | assertTrue(result.isSuccessful()); 103 | waitForTransactionHash(result); 104 | } 105 | 106 | public void transferFromScriptAddress() throws Exception { 107 | Account signingAcc = new Account(Networks.testnet(), paymentAccMnemonic); 108 | Tuple scriptTuple = createScriptAddress(); 109 | String scriptAddress = scriptTuple._1; 110 | NativeScript script = scriptTuple._2; 111 | 112 | System.out.println(JsonUtil.getPrettyJson(script)); 113 | 114 | String receiverAddress = "addr_test1qqwpl7h3g84mhr36wpetk904p7fchx2vst0z696lxk8ujsjyruqwmlsm344gfux3nsj6njyzj3ppvrqtt36cp9xyydzqzumz82"; 115 | 116 | Output output = Output.builder() 117 | .address(receiverAddress) 118 | .assetName(LOVELACE) 119 | .qty(adaToLovelace(1.1)) 120 | .build(); 121 | 122 | TxBuilder txBuilder = output.outputBuilder() 123 | .buildInputs(createFromSender(scriptAddress, scriptAddress)) 124 | .andThen((txBuilderContext, transaction) -> { //Add script witness and validation start interval 125 | //Set validity start interval. Should be after target slot. Without that it will not work 126 | transaction.getBody().setValidityStartInterval(targetUnlockSlot + 1); 127 | 128 | //Set script witness 129 | transaction.getWitnessSet().setNativeScripts(List.of(script)); 130 | }) 131 | .andThen(feeCalculator(scriptAddress, 1)) 132 | .andThen(adjustChangeOutput(scriptAddress, 1)); 133 | 134 | Transaction signedTransaction = TxBuilderContext.init(utxoSupplier, protocolParamsSupplier) 135 | .buildAndSign(txBuilder, signerFrom(signingAcc)); 136 | 137 | Result result = transactionService.submitTransaction(signedTransaction.serialize()); 138 | System.out.println(result); 139 | 140 | if (result.isSuccessful()) 141 | System.out.println("Transaction Id: " + result.getValue()); 142 | else 143 | System.out.println("Transaction failed: " + result); 144 | 145 | assertTrue(result.isSuccessful()); 146 | waitForTransactionHash(result); 147 | } 148 | 149 | protected long getCurrentSlot() throws ApiException { 150 | Block block = blockService.getLatestBlock().getValue(); 151 | long slot = block.getSlot(); 152 | return slot; 153 | } 154 | 155 | public void getSlot() throws ApiException { 156 | System.out.println("Expected slot : " + targetUnlockSlot); 157 | System.out.println("Current slot: " + getCurrentSlot()); 158 | } 159 | 160 | } 161 | -------------------------------------------------------------------------------- /src/test/resources/log4j.properties: -------------------------------------------------------------------------------- 1 | log4j.rootLogger=DEBUG, consoleAppender, fileAppender 2 | log4j.appender.consoleAppender=org.apache.log4j.ConsoleAppender 3 | log4j.appender.consoleAppender.layout=org.apache.log4j.PatternLayout 4 | log4j.appender.consoleAppender.layout.ConversionPattern=[%t] %-5p %c %x - %m%n 5 | log4j.appender.fileAppender=org.apache.log4j.RollingFileAppender 6 | log4j.appender.fileAppender.layout=org.apache.log4j.PatternLayout 7 | log4j.appender.fileAppender.layout.ConversionPattern=[%t] %-5p %c %x - %m%n 8 | log4j.appender.fileAppender.File=application.log 9 | -------------------------------------------------------------------------------- /src/test/resources/multisig.script: -------------------------------------------------------------------------------- 1 | { 2 | "type" : "atLeast", 3 | "required" : 2, 4 | "scripts" : [ { 5 | "keyHash" : "74cfebcf5e97474d7b89c862d7ee7cff22efbb032d4133a1b84cbdcd", 6 | "type" : "sig" 7 | }, { 8 | "keyHash" : "710ee487dbbcdb59b5841a00d1029a56a407c722b3081c02470b516d", 9 | "type" : "sig" 10 | }, { 11 | "keyHash" : "beed26382ec96254a6714928c3c5bb8227abecbbb095cfeab9fb2dd1", 12 | "type" : "sig" 13 | } ] 14 | } 15 | --------------------------------------------------------------------------------