From 4335e6cb784cb8b872c2b12496376f553622c4d0 Mon Sep 17 00:00:00 2001 From: Ben Guidarelli Date: Sat, 25 Feb 2023 13:19:57 -0500 Subject: [PATCH 01/22] starting example location --- examples/README.md | 15 +++ examples/pom.xml | 101 ++++++++++++++++++ .../java/com/algorand/examples/Example.java | 59 ++++++++++ .../java/com/algorand/examples/Utils.java | 78 ++++++++++++++ 4 files changed, 253 insertions(+) create mode 100644 examples/README.md create mode 100644 examples/pom.xml create mode 100644 examples/src/main/java/com/algorand/examples/Example.java create mode 100644 examples/src/main/java/com/algorand/examples/Utils.java diff --git a/examples/README.md b/examples/README.md new file mode 100644 index 000000000..16afe5dd3 --- /dev/null +++ b/examples/README.md @@ -0,0 +1,15 @@ +Algorand Java SDK Examples + + + +Running +-------- +Package with `mvn` +```sh +mvn package +``` + +Run an example with java +```sh +java -cp target/sdk-extras-1.0-SNAPSHOT.jar com.algorand.examples.Example +``` \ No newline at end of file diff --git a/examples/pom.xml b/examples/pom.xml new file mode 100644 index 000000000..d86485db7 --- /dev/null +++ b/examples/pom.xml @@ -0,0 +1,101 @@ + + 4.0.0 + com.algorand + sdk-extras + jar + 1.0-SNAPSHOT + sdk-extras + http://maven.apache.org + + + 1.8 + 1.8 + + + + + com.fasterxml.jackson.core + jackson-annotations + 2.10.0 + + + com.fasterxml.jackson.core + jackson-core + 2.10.0 + + + com.fasterxml.jackson.core + jackson-databind + 2.10.5.1 + + + com.squareup.okhttp + logging-interceptor + 2.7.5 + + + com.squareup.okhttp + okhttp + 2.7.5 + + + com.squareup.okio + okio + 1.6.0 + + + commons-codec + commons-codec + + 1.12 + + + io.gsonfire + gson-fire + 1.8.0 + + + io.swagger + swagger-annotations + 1.5.18 + + + org.apache.commons + commons-lang3 + + 3.8 + + + org.bouncycastle + bcprov-jdk15to18 + 1.66 + + + org.msgpack + jackson-dataformat-msgpack + 0.9.0 + + + org.threeten + threetenbp + 1.3.5 + + + com.google.guava + guava + 28.2-android + + + junit + junit + 3.8.1 + test + + + com.algorand + algosdk + 2.0.0 + + + diff --git a/examples/src/main/java/com/algorand/examples/Example.java b/examples/src/main/java/com/algorand/examples/Example.java new file mode 100644 index 000000000..06fa12a8a --- /dev/null +++ b/examples/src/main/java/com/algorand/examples/Example.java @@ -0,0 +1,59 @@ +package com.algorand.examples; + +public class Example { + + public static void main(String[] args) { + System.out.println("hi"); + } + + +// Missing ATOMIC_CREATE_TXNS in JAVASDK examples (in ../docs/get-details/atomic_transfers.md:71) +// Missing ATOMIC_GROUP_TXNS in JAVASDK examples (in ../docs/get-details/atomic_transfers.md:154) +// Missing ATOMIC_GROUP_SIGN in JAVASDK examples (in ../docs/get-details/atomic_transfers.md:222) +// Missing ATOMIC_GROUP_ASSEMBLE in JAVASDK examples (in ../docs/get-details/atomic_transfers.md:284) +// Missing ATOMIC_GROUP_SEND in JAVASDK examples (in ../docs/get-details/atomic_transfers.md:346) +// Missing MULTISIG_CREATE in JAVASDK examples (in ../docs/get-details/transactions/signatures.md:256) +// Missing MULTISIG_SIGN in JAVASDK examples (in ../docs/get-details/transactions/signatures.md:258) +// Missing TRANSACTION_FEE_OVERRIDE in JAVASDK examples (in ../docs/get-details/transactions/index.md:791) +// Missing CODEC_TRANSACTION_UNSIGNED in JAVASDK examples (in ../docs/get-details/transactions/offline_transactions.md:62) +// Missing CODEC_TRANSACTION_SIGNED in JAVASDK examples (in ../docs/get-details/transactions/offline_transactions.md:268) +// Missing KMD_CREATE_CLIENT in JAVASDK examples (in ../docs/get-details/accounts/create.md:115) +// Missing KMD_CREATE_WALLET in JAVASDK examples (in ../docs/get-details/accounts/create.md:132) +// Missing KMD_CREATE_ACCOUNT in JAVASDK examples (in ../docs/get-details/accounts/create.md:150) +// Missing KMD_RECOVER_WALLET in JAVASDK examples (in ../docs/get-details/accounts/create.md:294) +// Missing KMD_EXPORT_ACCOUNT in JAVASDK examples (in ../docs/get-details/accounts/create.md:488) +// Missing KMD_IMPORT_ACCOUNT in JAVASDK examples (in ../docs/get-details/accounts/create.md:690) +// Missing ACCOUNT_GENERATE in JAVASDK examples (in ../docs/get-details/accounts/create.md:894) +// Missing MULTISIG_CREATE in JAVASDK examples (in ../docs/get-details/accounts/create.md:1030) +// Missing ACCOUNT_REKEY in JAVASDK examples (in ../docs/get-details/accounts/rekey.md:364) +// Missing CODEC_ADDRESS in JAVASDK examples (in ../docs/get-details/encoding.md:86) +// Missing CODEC_BASE64 in JAVASDK examples (in ../docs/get-details/encoding.md:138) +// Missing CODEC_UINT64 in JAVASDK examples (in ../docs/get-details/encoding.md:196) +// Missing CODEC_TRANSACTION_UNSIGNED in JAVASDK examples (in ../docs/get-details/encoding.md:337) +// Missing CODEC_TRANSACTION_SIGNED in JAVASDK examples (in ../docs/get-details/encoding.md:339) +// Missing CODEC_BLOCK in JAVASDK examples (in ../docs/get-details/encoding.md:363) +// Missing CONST_MIN_FEE in JAVASDK examples (in ../docs/get-details/dapps/smart-contracts/guidelines.md:62) +// Missing SP_MIN_FEE in JAVASDK examples (in ../docs/get-details/dapps/smart-contracts/guidelines.md:96) +// Missing ASSET_CREATE in JAVASDK examples (in ../docs/get-details/asa.md:203) +// Missing ASSET_CONFIG in JAVASDK examples (in ../docs/get-details/asa.md:429) +// Missing ASSET_OPTIN in JAVASDK examples (in ../docs/get-details/asa.md:628) +// Missing ASSET_XFER in JAVASDK examples (in ../docs/get-details/asa.md:809) +// Missing ASSET_FREEZE in JAVASDK examples (in ../docs/get-details/asa.md:1007) +// Missing ASSET_CLAWBACK in JAVASDK examples (in ../docs/get-details/asa.md:1193) +// Missing ASSET_DELETE in JAVASDK examples (in ../docs/get-details/asa.md:1386) +// Missing ASSET_INFO in JAVASDK examples (in ../docs/get-details/asa.md:1549) +// Missing ATC_CREATE in JAVASDK examples (in ../docs/get-details/atc.md:48) +// Missing ATC_ADD_TRANSACTION in JAVASDK examples (in ../docs/get-details/atc.md:142) +// Missing ATC_CONTRACT_INIT in JAVASDK examples (in ../docs/get-details/atc.md:307) +// Missing ATC_ADD_METHOD_CALL in JAVASDK examples (in ../docs/get-details/atc.md:325) +// Missing ATC_RESULTS in JAVASDK examples (in ../docs/get-details/atc.md:406) +// Missing CREATE_INDEXER_CLIENT in JAVASDK examples (in ../docs/get-details/indexer.md:42) +// Missing INDEXER_LOOKUP_ASSET in JAVASDK examples (in ../docs/get-details/indexer.md:131) +// Missing INDEXER_SEARCH_MIN_AMOUNT in JAVASDK examples (in ../docs/get-details/indexer.md:205) +// Missing INDEXER_PAGINATE_RESULTS in JAVASDK examples (in ../docs/get-details/indexer.md:322) +// Missing INDEXER_PREFIX_SEARCH in JAVASDK examples (in ../docs/get-details/indexer.md:477) +// Missing TRANSACTION_KEYREG_OFFLINE_CREATE in JAVASDK examples (in ../docs/run-a-node/participate/offline.md:41) +// Missing TRANSACTION_KEYREG_ONLINE_CREATE in JAVASDK examples (in ../docs/run-a-node/participate/online.md:42) + + +} diff --git a/examples/src/main/java/com/algorand/examples/Utils.java b/examples/src/main/java/com/algorand/examples/Utils.java new file mode 100644 index 000000000..4bc7a79ff --- /dev/null +++ b/examples/src/main/java/com/algorand/examples/Utils.java @@ -0,0 +1,78 @@ +package com.algorand.examples; + +import java.security.NoSuchAlgorithmException; +import java.util.ArrayList; +import java.util.List; + +import com.algorand.algosdk.account.Account; +import com.algorand.algosdk.algod.client.AlgodClient; +import com.algorand.algosdk.crypto.Address; +import com.algorand.algosdk.kmd.client.KmdClient; +import com.algorand.algosdk.kmd.client.api.KmdApi; +import com.algorand.algosdk.kmd.client.model.APIV1Wallet; +import com.algorand.algosdk.kmd.client.model.ExportKeyRequest; +import com.algorand.algosdk.kmd.client.model.InitWalletHandleTokenRequest; +import com.algorand.algosdk.kmd.client.model.ListKeysRequest; +import com.algorand.algosdk.kmd.client.ApiException; + +public class Utils { + + private static String host = "http://localhost:4002"; + private static String token = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"; + private static KmdApi kmd = null; + + public static AlgodClient getAlgodClient() { + + } + + public static List getSandboxAccounts() throws Exception { + // Initialize KMD v1 client + KmdClient kmdClient = new KmdClient(); + kmdClient.setBasePath(host); + kmdClient.setApiKey(token); + kmd = new KmdApi(kmdClient); + + // Get accounts from sandbox. + String walletHandle = getDefaultWalletHandle(); + List
addresses = getWalletAccounts(walletHandle); + + List accts = new ArrayList<>(); + for(Address addr: addresses){ + byte[] pk = lookupPrivateKey(addr, walletHandle); + accts.add(new Account(pk)); + } + return accts; + } + + public static byte[] lookupPrivateKey(Address addr, String walletHandle) throws ApiException { + ExportKeyRequest req = new ExportKeyRequest(); + req.setAddress(addr.toString()); + req.setWalletHandleToken(walletHandle); + req.setWalletPassword(""); + return kmd.exportKey(req).getPrivateKey(); + } + + public static String getDefaultWalletHandle() throws ApiException { + for (APIV1Wallet w : kmd.listWallets().getWallets()) { + if (w.getName().equals("unencrypted-default-wallet")) { + InitWalletHandleTokenRequest tokenreq = new InitWalletHandleTokenRequest(); + tokenreq.setWalletId(w.getId()); + tokenreq.setWalletPassword(""); + return kmd.initWalletHandleToken(tokenreq).getWalletHandleToken(); + } + } + throw new RuntimeException("Default wallet not found."); + } + + public static List
getWalletAccounts(String walletHandle) throws ApiException, NoSuchAlgorithmException { + List
accounts = new ArrayList<>(); + + ListKeysRequest keysRequest = new ListKeysRequest(); + keysRequest.setWalletHandleToken(walletHandle); + for (String addr : kmd.listKeysInWallet(keysRequest).getAddresses()) { + accounts.add(new Address(addr)); + } + + return accounts; + } +} \ No newline at end of file From 5b1c7b55c17d37315168d99f0df69105c434fa96 Mon Sep 17 00:00:00 2001 From: Ben Guidarelli Date: Sat, 25 Feb 2023 13:49:38 -0500 Subject: [PATCH 02/22] first example working --- examples/pom.xml | 18 +++ examples/runit.sh | 2 + .../java/com/algorand/examples/Example.java | 134 ++++++++++++------ .../{Utils.java => ExampleUtils.java} | 26 +++- 4 files changed, 132 insertions(+), 48 deletions(-) create mode 100755 examples/runit.sh rename examples/src/main/java/com/algorand/examples/{Utils.java => ExampleUtils.java} (72%) diff --git a/examples/pom.xml b/examples/pom.xml index d86485db7..3b06f5d04 100644 --- a/examples/pom.xml +++ b/examples/pom.xml @@ -98,4 +98,22 @@ 2.0.0 + + + + + maven-assembly-plugin + + + + com.algorand.examples.Example + + + + jar-with-dependencies + + + + + diff --git a/examples/runit.sh b/examples/runit.sh new file mode 100755 index 000000000..2b3eab9f4 --- /dev/null +++ b/examples/runit.sh @@ -0,0 +1,2 @@ +mvn clean compile assembly:single +java -cp target/sdk-extras-1.0-SNAPSHOT-jar-with-dependencies.jar com.algorand.examples.Example diff --git a/examples/src/main/java/com/algorand/examples/Example.java b/examples/src/main/java/com/algorand/examples/Example.java index 06fa12a8a..aad8b8ebb 100644 --- a/examples/src/main/java/com/algorand/examples/Example.java +++ b/examples/src/main/java/com/algorand/examples/Example.java @@ -1,59 +1,109 @@ package com.algorand.examples; -public class Example { +import com.algorand.algosdk.v2.client.common.AlgodClient; +public class Example { public static void main(String[] args) { System.out.println("hi"); + AlgodClient c = ExampleUtils.getAlgodClient(); } + public static void createClient() { + // example: ALGOD_CREATE_CLIENT + String algodHost = "http://localhost"; + int algodPort = 4001; + String algodToken = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"; + AlgodClient algodClient = AlgodClient(algodHost, algodPort, algodToken); -// Missing ATOMIC_CREATE_TXNS in JAVASDK examples (in ../docs/get-details/atomic_transfers.md:71) -// Missing ATOMIC_GROUP_TXNS in JAVASDK examples (in ../docs/get-details/atomic_transfers.md:154) -// Missing ATOMIC_GROUP_SIGN in JAVASDK examples (in ../docs/get-details/atomic_transfers.md:222) -// Missing ATOMIC_GROUP_ASSEMBLE in JAVASDK examples (in ../docs/get-details/atomic_transfers.md:284) -// Missing ATOMIC_GROUP_SEND in JAVASDK examples (in ../docs/get-details/atomic_transfers.md:346) -// Missing MULTISIG_CREATE in JAVASDK examples (in ../docs/get-details/transactions/signatures.md:256) -// Missing MULTISIG_SIGN in JAVASDK examples (in ../docs/get-details/transactions/signatures.md:258) -// Missing TRANSACTION_FEE_OVERRIDE in JAVASDK examples (in ../docs/get-details/transactions/index.md:791) -// Missing CODEC_TRANSACTION_UNSIGNED in JAVASDK examples (in ../docs/get-details/transactions/offline_transactions.md:62) -// Missing CODEC_TRANSACTION_SIGNED in JAVASDK examples (in ../docs/get-details/transactions/offline_transactions.md:268) -// Missing KMD_CREATE_CLIENT in JAVASDK examples (in ../docs/get-details/accounts/create.md:115) -// Missing KMD_CREATE_WALLET in JAVASDK examples (in ../docs/get-details/accounts/create.md:132) -// Missing KMD_CREATE_ACCOUNT in JAVASDK examples (in ../docs/get-details/accounts/create.md:150) -// Missing KMD_RECOVER_WALLET in JAVASDK examples (in ../docs/get-details/accounts/create.md:294) -// Missing KMD_EXPORT_ACCOUNT in JAVASDK examples (in ../docs/get-details/accounts/create.md:488) -// Missing KMD_IMPORT_ACCOUNT in JAVASDK examples (in ../docs/get-details/accounts/create.md:690) -// Missing ACCOUNT_GENERATE in JAVASDK examples (in ../docs/get-details/accounts/create.md:894) -// Missing MULTISIG_CREATE in JAVASDK examples (in ../docs/get-details/accounts/create.md:1030) -// Missing ACCOUNT_REKEY in JAVASDK examples (in ../docs/get-details/accounts/rekey.md:364) -// Missing CODEC_ADDRESS in JAVASDK examples (in ../docs/get-details/encoding.md:86) -// Missing CODEC_BASE64 in JAVASDK examples (in ../docs/get-details/encoding.md:138) -// Missing CODEC_UINT64 in JAVASDK examples (in ../docs/get-details/encoding.md:196) -// Missing CODEC_TRANSACTION_UNSIGNED in JAVASDK examples (in ../docs/get-details/encoding.md:337) -// Missing CODEC_TRANSACTION_SIGNED in JAVASDK examples (in ../docs/get-details/encoding.md:339) -// Missing CODEC_BLOCK in JAVASDK examples (in ../docs/get-details/encoding.md:363) -// Missing CONST_MIN_FEE in JAVASDK examples (in ../docs/get-details/dapps/smart-contracts/guidelines.md:62) -// Missing SP_MIN_FEE in JAVASDK examples (in ../docs/get-details/dapps/smart-contracts/guidelines.md:96) + // OR if the API provider requires a specific header key for the token + String tokenHeader = "X-API-Key"; + AlgodClient otherAlgodClient = AlgodClient(algodHost, algodPort, algodToken, tokenHeader); + // example: ALGOD_CREATE_CLIENT + } +} + +// Missing ATOMIC_CREATE_TXNS in JAVASDK examples (in +// ../docs/get-details/atomic_transfers.md:71) +// Missing ATOMIC_GROUP_TXNS in JAVASDK examples (in +// ../docs/get-details/atomic_transfers.md:154) +// Missing ATOMIC_GROUP_SIGN in JAVASDK examples (in +// ../docs/get-details/atomic_transfers.md:222) +// Missing ATOMIC_GROUP_ASSEMBLE in JAVASDK examples (in +// ../docs/get-details/atomic_transfers.md:284) +// Missing ATOMIC_GROUP_SEND in JAVASDK examples (in +// ../docs/get-details/atomic_transfers.md:346) +// Missing MULTISIG_CREATE in JAVASDK examples (in +// ../docs/get-details/transactions/signatures.md:256) +// Missing MULTISIG_SIGN in JAVASDK examples (in +// ../docs/get-details/transactions/signatures.md:258) +// Missing TRANSACTION_FEE_OVERRIDE in JAVASDK examples (in +// ../docs/get-details/transactions/index.md:791) +// Missing CODEC_TRANSACTION_UNSIGNED in JAVASDK examples (in +// ../docs/get-details/transactions/offline_transactions.md:62) +// Missing CODEC_TRANSACTION_SIGNED in JAVASDK examples (in +// ../docs/get-details/transactions/offline_transactions.md:268) +// Missing KMD_CREATE_CLIENT in JAVASDK examples (in +// ../docs/get-details/accounts/create.md:115) +// Missing KMD_CREATE_WALLET in JAVASDK examples (in +// ../docs/get-details/accounts/create.md:132) +// Missing KMD_CREATE_ACCOUNT in JAVASDK examples (in +// ../docs/get-details/accounts/create.md:150) +// Missing KMD_RECOVER_WALLET in JAVASDK examples (in +// ../docs/get-details/accounts/create.md:294) +// Missing KMD_EXPORT_ACCOUNT in JAVASDK examples (in +// ../docs/get-details/accounts/create.md:488) +// Missing KMD_IMPORT_ACCOUNT in JAVASDK examples (in +// ../docs/get-details/accounts/create.md:690) +// Missing ACCOUNT_GENERATE in JAVASDK examples (in +// ../docs/get-details/accounts/create.md:894) +// Missing MULTISIG_CREATE in JAVASDK examples (in +// ../docs/get-details/accounts/create.md:1030) +// Missing ACCOUNT_REKEY in JAVASDK examples (in +// ../docs/get-details/accounts/rekey.md:364) +// Missing CODEC_ADDRESS in JAVASDK examples (in +// ../docs/get-details/encoding.md:86) +// Missing CODEC_BASE64 in JAVASDK examples (in +// ../docs/get-details/encoding.md:138) +// Missing CODEC_UINT64 in JAVASDK examples (in +// ../docs/get-details/encoding.md:196) +// Missing CODEC_TRANSACTION_UNSIGNED in JAVASDK examples (in +// ../docs/get-details/encoding.md:337) +// Missing CODEC_TRANSACTION_SIGNED in JAVASDK examples (in +// ../docs/get-details/encoding.md:339) +// Missing CODEC_BLOCK in JAVASDK examples (in +// ../docs/get-details/encoding.md:363) +// Missing CONST_MIN_FEE in JAVASDK examples (in +// ../docs/get-details/dapps/smart-contracts/guidelines.md:62) +// Missing SP_MIN_FEE in JAVASDK examples (in +// ../docs/get-details/dapps/smart-contracts/guidelines.md:96) // Missing ASSET_CREATE in JAVASDK examples (in ../docs/get-details/asa.md:203) // Missing ASSET_CONFIG in JAVASDK examples (in ../docs/get-details/asa.md:429) // Missing ASSET_OPTIN in JAVASDK examples (in ../docs/get-details/asa.md:628) // Missing ASSET_XFER in JAVASDK examples (in ../docs/get-details/asa.md:809) // Missing ASSET_FREEZE in JAVASDK examples (in ../docs/get-details/asa.md:1007) -// Missing ASSET_CLAWBACK in JAVASDK examples (in ../docs/get-details/asa.md:1193) +// Missing ASSET_CLAWBACK in JAVASDK examples (in +// ../docs/get-details/asa.md:1193) // Missing ASSET_DELETE in JAVASDK examples (in ../docs/get-details/asa.md:1386) // Missing ASSET_INFO in JAVASDK examples (in ../docs/get-details/asa.md:1549) // Missing ATC_CREATE in JAVASDK examples (in ../docs/get-details/atc.md:48) -// Missing ATC_ADD_TRANSACTION in JAVASDK examples (in ../docs/get-details/atc.md:142) -// Missing ATC_CONTRACT_INIT in JAVASDK examples (in ../docs/get-details/atc.md:307) -// Missing ATC_ADD_METHOD_CALL in JAVASDK examples (in ../docs/get-details/atc.md:325) +// Missing ATC_ADD_TRANSACTION in JAVASDK examples (in +// ../docs/get-details/atc.md:142) +// Missing ATC_CONTRACT_INIT in JAVASDK examples (in +// ../docs/get-details/atc.md:307) +// Missing ATC_ADD_METHOD_CALL in JAVASDK examples (in +// ../docs/get-details/atc.md:325) // Missing ATC_RESULTS in JAVASDK examples (in ../docs/get-details/atc.md:406) -// Missing CREATE_INDEXER_CLIENT in JAVASDK examples (in ../docs/get-details/indexer.md:42) -// Missing INDEXER_LOOKUP_ASSET in JAVASDK examples (in ../docs/get-details/indexer.md:131) -// Missing INDEXER_SEARCH_MIN_AMOUNT in JAVASDK examples (in ../docs/get-details/indexer.md:205) -// Missing INDEXER_PAGINATE_RESULTS in JAVASDK examples (in ../docs/get-details/indexer.md:322) -// Missing INDEXER_PREFIX_SEARCH in JAVASDK examples (in ../docs/get-details/indexer.md:477) -// Missing TRANSACTION_KEYREG_OFFLINE_CREATE in JAVASDK examples (in ../docs/run-a-node/participate/offline.md:41) -// Missing TRANSACTION_KEYREG_ONLINE_CREATE in JAVASDK examples (in ../docs/run-a-node/participate/online.md:42) - - -} +// Missing CREATE_INDEXER_CLIENT in JAVASDK examples (in +// ../docs/get-details/indexer.md:42) +// Missing INDEXER_LOOKUP_ASSET in JAVASDK examples (in +// ../docs/get-details/indexer.md:131) +// Missing INDEXER_SEARCH_MIN_AMOUNT in JAVASDK examples (in +// ../docs/get-details/indexer.md:205) +// Missing INDEXER_PAGINATE_RESULTS in JAVASDK examples (in +// ../docs/get-details/indexer.md:322) +// Missing INDEXER_PREFIX_SEARCH in JAVASDK examples (in +// ../docs/get-details/indexer.md:477) +// Missing TRANSACTION_KEYREG_OFFLINE_CREATE in JAVASDK examples (in +// ../docs/run-a-node/participate/offline.md:41) +// Missing TRANSACTION_KEYREG_ONLINE_CREATE in JAVASDK examples (in +// ../docs/run-a-node/participate/online.md:42) diff --git a/examples/src/main/java/com/algorand/examples/Utils.java b/examples/src/main/java/com/algorand/examples/ExampleUtils.java similarity index 72% rename from examples/src/main/java/com/algorand/examples/Utils.java rename to examples/src/main/java/com/algorand/examples/ExampleUtils.java index 4bc7a79ff..33e715fe5 100644 --- a/examples/src/main/java/com/algorand/examples/Utils.java +++ b/examples/src/main/java/com/algorand/examples/ExampleUtils.java @@ -4,8 +4,9 @@ import java.util.ArrayList; import java.util.List; +import com.algorand.algosdk.v2.client.common.AlgodClient; +import com.algorand.algosdk.v2.client.common.IndexerClient; import com.algorand.algosdk.account.Account; -import com.algorand.algosdk.algod.client.AlgodClient; import com.algorand.algosdk.crypto.Address; import com.algorand.algosdk.kmd.client.KmdClient; import com.algorand.algosdk.kmd.client.api.KmdApi; @@ -15,21 +16,34 @@ import com.algorand.algosdk.kmd.client.model.ListKeysRequest; import com.algorand.algosdk.kmd.client.ApiException; -public class Utils { +public class ExampleUtils { - private static String host = "http://localhost:4002"; - private static String token = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"; + private static String kmd_host = "http://localhost:4002"; + private static String kmd_token = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"; private static KmdApi kmd = null; + private static String algod_host = "http://localhost"; + private static int algod_port = 4001; + private static String algod_token = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"; + + private static String indexer_host = "http://localhost"; + private static int indexer_port = 8980; + private static String indexer_token = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"; + + public static AlgodClient getAlgodClient() { + return new AlgodClient(algod_host, algod_port, algod_token); + } + public static IndexerClient getIndexerClient() { + return new IndexerClient(indexer_host, indexer_port, indexer_token); } public static List getSandboxAccounts() throws Exception { // Initialize KMD v1 client KmdClient kmdClient = new KmdClient(); - kmdClient.setBasePath(host); - kmdClient.setApiKey(token); + kmdClient.setBasePath(kmd_host); + kmdClient.setApiKey(kmd_token); kmd = new KmdApi(kmdClient); // Get accounts from sandbox. From b593f3cb2588fa63bb211bf1fafb607a2963ea77 Mon Sep 17 00:00:00 2001 From: Ben Guidarelli Date: Mon, 27 Feb 2023 11:23:34 -0500 Subject: [PATCH 03/22] more examples --- .../java/com/algorand/examples/Example.java | 63 +++++++++++++++++-- 1 file changed, 57 insertions(+), 6 deletions(-) diff --git a/examples/src/main/java/com/algorand/examples/Example.java b/examples/src/main/java/com/algorand/examples/Example.java index aad8b8ebb..d75196700 100644 --- a/examples/src/main/java/com/algorand/examples/Example.java +++ b/examples/src/main/java/com/algorand/examples/Example.java @@ -1,25 +1,76 @@ package com.algorand.examples; +import java.security.NoSuchAlgorithmException; +import java.util.List; +import com.algorand.algosdk.v2.client.Utils; import com.algorand.algosdk.v2.client.common.AlgodClient; +import com.algorand.algosdk.v2.client.common.Response; +import com.algorand.algosdk.v2.client.model.PendingTransactionResponse; +import com.algorand.algosdk.v2.client.model.PostTransactionsResponse; +import com.algorand.algosdk.v2.client.model.TransactionParametersResponse; +import com.algorand.algosdk.account.Account; +import com.algorand.algosdk.transaction.SignedTransaction; +import com.algorand.algosdk.transaction.Transaction; +import com.algorand.algosdk.util.Encoder; public class Example { - public static void main(String[] args) { - System.out.println("hi"); - AlgodClient c = ExampleUtils.getAlgodClient(); + public static void main(String[] args) throws Exception { + AlgodClient algodClient = ExampleUtils.getAlgodClient(); + List accts = ExampleUtils.getSandboxAccounts(); + // grab the first one from the sandbox kmd + Account acct = accts.get(0); + Account acct2 = accts.get(1); + + // example: TRANSACTION_PAYMENT_CREATE + Response suggestedParams = algodClient.TransactionParams().execute(); + Integer amount = 1000000; // 1 Algo + Transaction ptxn = Transaction.PaymentTransactionBuilder() + .sender(acct.getAddress()) + .amount(amount) + .receiver(acct2.getAddress()) + .suggestedParams(suggestedParams.body()).build(); + // example: TRANSACTION_PAYMENT_CREATE + + + // example: TRANSACTION_PAYMENT_SIGN + SignedTransaction sptxn = acct.signTransaction(ptxn); + // example: TRANSACTION_PAYMENT_SIGN + + // example: TRANSACTION_PAYMENT_SUBMIT + // encode the transaction + byte[] encodedTxBytes = Encoder.encodeToMsgPack(sptxn); + // submit the transaction to the algod server + Response resp = algodClient.RawTransaction().rawtxn(encodedTxBytes).execute(); + // wait for the transaction to be confirmed + String txid = resp.body().txId; + PendingTransactionResponse result = Utils.waitForConfirmation(algodClient, txid, 4); + System.out.printf("Transaction %s confirmed in round %d\n", txid, result.confirmedRound); + // example: TRANSACTION_PAYMENT_SUBMIT } - public static void createClient() { + public static void createAccount() throws NoSuchAlgorithmException{ + // example: ACCOUNT_GENERATE + Account acct = new Account(); + System.out.println("Address: " + acct.getAddress()); + System.out.println("Passphrase: " + acct.toMnemonic()); + // example: ACCOUNT_GENERATE + } + + public static AlgodClient createClient() { // example: ALGOD_CREATE_CLIENT String algodHost = "http://localhost"; int algodPort = 4001; String algodToken = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"; - AlgodClient algodClient = AlgodClient(algodHost, algodPort, algodToken); + AlgodClient algodClient = new AlgodClient(algodHost, algodPort, algodToken); // OR if the API provider requires a specific header key for the token String tokenHeader = "X-API-Key"; - AlgodClient otherAlgodClient = AlgodClient(algodHost, algodPort, algodToken, tokenHeader); + AlgodClient otherAlgodClient = new AlgodClient(algodHost, algodPort, algodToken, tokenHeader); // example: ALGOD_CREATE_CLIENT + return algodClient; } + + } // Missing ATOMIC_CREATE_TXNS in JAVASDK examples (in From 5e2ae3546935f37412a146b9f46bd7fafbb475e1 Mon Sep 17 00:00:00 2001 From: Ben Guidarelli Date: Tue, 28 Feb 2023 13:38:01 -0500 Subject: [PATCH 04/22] adding more examples --- examples/calculator/approval.teal | 181 ++++++++++++++++++ examples/calculator/clear.teal | 3 + examples/calculator/contract.json | 74 +++++++ .../main/java/com/algorand/examples/ATC.java | 119 ++++++++++++ .../algorand/examples/AccountExamples.java | 103 ++++++++++ .../java/com/algorand/examples/Example.java | 160 ---------------- .../com/algorand/examples/ExampleUtils.java | 20 +- .../java/com/algorand/examples/Overview.java | 74 +++++++ .../java/com/algorand/examples/contract.json | 0 9 files changed, 572 insertions(+), 162 deletions(-) create mode 100644 examples/calculator/approval.teal create mode 100644 examples/calculator/clear.teal create mode 100644 examples/calculator/contract.json create mode 100644 examples/src/main/java/com/algorand/examples/ATC.java create mode 100644 examples/src/main/java/com/algorand/examples/AccountExamples.java delete mode 100644 examples/src/main/java/com/algorand/examples/Example.java create mode 100644 examples/src/main/java/com/algorand/examples/Overview.java create mode 100644 examples/src/main/java/com/algorand/examples/contract.json diff --git a/examples/calculator/approval.teal b/examples/calculator/approval.teal new file mode 100644 index 000000000..32acbb840 --- /dev/null +++ b/examples/calculator/approval.teal @@ -0,0 +1,181 @@ +#pragma version 8 +intcblock 0 1 +bytecblock 0x151f7c75 +txn NumAppArgs +intc_0 // 0 +== +bnz main_l10 +txna ApplicationArgs 0 +pushbytes 0xfe6bdf69 // "add(uint64,uint64)uint64" +== +bnz main_l9 +txna ApplicationArgs 0 +pushbytes 0xe2f188c5 // "mul(uint64,uint64)uint64" +== +bnz main_l8 +txna ApplicationArgs 0 +pushbytes 0x78b488b7 // "sub(uint64,uint64)uint64" +== +bnz main_l7 +txna ApplicationArgs 0 +pushbytes 0x16e80f08 // "div(uint64,uint64)uint64" +== +bnz main_l6 +err +main_l6: +txn OnCompletion +intc_0 // NoOp +== +txn ApplicationID +intc_0 // 0 +!= +&& +assert +txna ApplicationArgs 1 +btoi +store 9 +txna ApplicationArgs 2 +btoi +store 10 +load 9 +load 10 +callsub div_3 +store 11 +bytec_0 // 0x151f7c75 +load 11 +itob +concat +log +intc_1 // 1 +return +main_l7: +txn OnCompletion +intc_0 // NoOp +== +txn ApplicationID +intc_0 // 0 +!= +&& +assert +txna ApplicationArgs 1 +btoi +store 6 +txna ApplicationArgs 2 +btoi +store 7 +load 6 +load 7 +callsub sub_2 +store 8 +bytec_0 // 0x151f7c75 +load 8 +itob +concat +log +intc_1 // 1 +return +main_l8: +txn OnCompletion +intc_0 // NoOp +== +txn ApplicationID +intc_0 // 0 +!= +&& +assert +txna ApplicationArgs 1 +btoi +store 3 +txna ApplicationArgs 2 +btoi +store 4 +load 3 +load 4 +callsub mul_1 +store 5 +bytec_0 // 0x151f7c75 +load 5 +itob +concat +log +intc_1 // 1 +return +main_l9: +txn OnCompletion +intc_0 // NoOp +== +txn ApplicationID +intc_0 // 0 +!= +&& +assert +txna ApplicationArgs 1 +btoi +store 0 +txna ApplicationArgs 2 +btoi +store 1 +load 0 +load 1 +callsub add_0 +store 2 +bytec_0 // 0x151f7c75 +load 2 +itob +concat +log +intc_1 // 1 +return +main_l10: +txn OnCompletion +intc_0 // NoOp +== +bnz main_l12 +err +main_l12: +txn ApplicationID +intc_0 // 0 +== +assert +intc_1 // 1 +return + +// add +add_0: +proto 2 1 +intc_0 // 0 +frame_dig -2 +frame_dig -1 ++ +frame_bury 0 +retsub + +// mul +mul_1: +proto 2 1 +intc_0 // 0 +frame_dig -2 +frame_dig -1 +* +frame_bury 0 +retsub + +// sub +sub_2: +proto 2 1 +intc_0 // 0 +frame_dig -2 +frame_dig -1 +- +frame_bury 0 +retsub + +// div +div_3: +proto 2 1 +intc_0 // 0 +frame_dig -2 +frame_dig -1 +/ +frame_bury 0 +retsub \ No newline at end of file diff --git a/examples/calculator/clear.teal b/examples/calculator/clear.teal new file mode 100644 index 000000000..e741f0e57 --- /dev/null +++ b/examples/calculator/clear.teal @@ -0,0 +1,3 @@ +#pragma version 8 +pushint 0 // 0 +return \ No newline at end of file diff --git a/examples/calculator/contract.json b/examples/calculator/contract.json new file mode 100644 index 000000000..4b23fa17e --- /dev/null +++ b/examples/calculator/contract.json @@ -0,0 +1,74 @@ +{ + "name": "Calculator", + "methods": [ + { + "name": "add", + "args": [ + { + "type": "uint64", + "name": "a" + }, + { + "type": "uint64", + "name": "b" + } + ], + "returns": { + "type": "uint64" + }, + "desc": "Add a and b, return the result" + }, + { + "name": "mul", + "args": [ + { + "type": "uint64", + "name": "a" + }, + { + "type": "uint64", + "name": "b" + } + ], + "returns": { + "type": "uint64" + }, + "desc": "Multiply a and b, return the result" + }, + { + "name": "sub", + "args": [ + { + "type": "uint64", + "name": "a" + }, + { + "type": "uint64", + "name": "b" + } + ], + "returns": { + "type": "uint64" + }, + "desc": "Subtract b from a, return the result" + }, + { + "name": "div", + "args": [ + { + "type": "uint64", + "name": "a" + }, + { + "type": "uint64", + "name": "b" + } + ], + "returns": { + "type": "uint64" + }, + "desc": "Divide a by b, return the result" + } + ], + "networks": {} +} \ No newline at end of file diff --git a/examples/src/main/java/com/algorand/examples/ATC.java b/examples/src/main/java/com/algorand/examples/ATC.java new file mode 100644 index 000000000..5f5d93598 --- /dev/null +++ b/examples/src/main/java/com/algorand/examples/ATC.java @@ -0,0 +1,119 @@ +package com.algorand.examples; + +import java.nio.file.Files; +import java.nio.file.Paths; +import java.util.ArrayList; +import java.util.List; + +import com.algorand.algosdk.abi.Contract; +import com.algorand.algosdk.account.Account; +import com.algorand.algosdk.builder.transaction.ApplicationCreateTransactionBuilder; +import com.algorand.algosdk.builder.transaction.MethodCallTransactionBuilder; +import com.algorand.algosdk.builder.transaction.PaymentTransactionBuilder; +import com.algorand.algosdk.crypto.TEALProgram; +import com.algorand.algosdk.logic.StateSchema; +import com.algorand.algosdk.transaction.AtomicTransactionComposer; +import com.algorand.algosdk.transaction.MethodCallParams; +import com.algorand.algosdk.transaction.SignedTransaction; +import com.algorand.algosdk.transaction.Transaction; +import com.algorand.algosdk.transaction.TransactionWithSigner; +import com.algorand.algosdk.transaction.AtomicTransactionComposer.ExecuteResult; +import com.algorand.algosdk.transaction.AtomicTransactionComposer.ReturnValue; +import com.algorand.algosdk.util.Encoder; +import com.algorand.algosdk.v2.client.Utils; +import com.algorand.algosdk.v2.client.common.AlgodClient; +import com.algorand.algosdk.v2.client.common.Response; +import com.algorand.algosdk.v2.client.model.CompileResponse; +import com.algorand.algosdk.v2.client.model.PendingTransactionResponse; +import com.algorand.algosdk.v2.client.model.PostTransactionsResponse; +import com.algorand.algosdk.v2.client.model.TransactionParametersResponse; + +public class ATC { + + public static void main(String[] args) throws Exception { + AlgodClient algodClient = ExampleUtils.getAlgodClient(); + List accts = ExampleUtils.getSandboxAccounts(); + Account acct = accts.get(0); + + Long appId = deployApp(algodClient, acct); + + // Get suggested params from client + Response rsp = algodClient.TransactionParams().execute(); + TransactionParametersResponse sp = rsp.body(); + + // example: ATC_CREATE + AtomicTransactionComposer atc = new AtomicTransactionComposer(); + // example: ATC_CREATE + + // example: ATC_ADD_TRANSACTION + // Create a transaction + Transaction ptxn = PaymentTransactionBuilder.Builder().amount(10000).suggestedParams(sp) + .sender(acct.getAddress()).receiver(acct.getAddress()).build(); + + // Construct TransactionWithSigner + TransactionWithSigner tws = new TransactionWithSigner(ptxn, + acct.getTransactionSigner()); + + // Pass TransactionWithSigner to atc + atc.addTransaction(tws); + // example: ATC_ADD_TRANSACTION + + // example: ATC_CONTRACT_INIT + // Read the json from disk + String jsonContract = Files.readString(Paths.get("calculator/contract.json")); + // Create Contract from Json + Contract contract = Encoder.decodeFromJson(jsonContract, Contract.class); + // example: ATC_CONTRACT_INIT + + // example: ATC_ADD_METHOD_CALL + // create methodCallParams by builder (or create by constructor) for add method + List method_args = new ArrayList(); + method_args.add(1); + method_args.add(1); + + MethodCallTransactionBuilder mctb = MethodCallTransactionBuilder.Builder(); + + MethodCallParams mcp = mctb.applicationId(appId).signer(acct.getTransactionSigner()).sender(acct.getAddress()) + .method(contract.getMethodByName("add")).methodArguments(method_args) + .onComplete(Transaction.OnCompletion.NoOpOC).suggestedParams(sp).build(); + + atc.addMethodCall(mcp); + // example: ATC_ADD_METHOD_CALL + // example: ATC_RESULTS + ExecuteResult res = atc.execute(algodClient, 2); + System.out.printf("App call (%s) confirmed in round %d\n", res.txIDs, res.confirmedRound); + ReturnValue returnValue = res.methodResults.get(0); + System.out.printf("Result from calling '%s' method: %s\n", returnValue.method.name, returnValue.value); + // example: ATC_RESULTS + } + + public static Long deployApp(AlgodClient algodClient, Account acct1) throws Exception { + String approvalSource = Files.readString(Paths.get("calculator/approval.teal")); + String clearSource = Files.readString(Paths.get("calculator/clear.teal")); + + CompileResponse approvalResponse = algodClient.TealCompile().source(approvalSource.getBytes()).execute().body(); + CompileResponse clearResponse = algodClient.TealCompile().source(clearSource.getBytes()).execute().body(); + + TEALProgram approvalProg = new TEALProgram(approvalResponse.result); + TEALProgram clearProg = new TEALProgram(clearResponse.result); + + Response rsp = algodClient.TransactionParams().execute(); + TransactionParametersResponse sp = rsp.body(); + + StateSchema schema = new StateSchema(0, 0); + + Transaction appCreate = ApplicationCreateTransactionBuilder.Builder().sender(acct1.getAddress()) + .approvalProgram(approvalProg).clearStateProgram(clearProg).localStateSchema(schema) + .globalStateSchema(schema) + .suggestedParams(sp).build(); + SignedTransaction signedAppCreate = acct1.signTransaction(appCreate); + + Response createResult = algodClient.RawTransaction() + .rawtxn(Encoder.encodeToMsgPack(signedAppCreate)).execute(); + + PendingTransactionResponse result = Utils.waitForConfirmation(algodClient, createResult.body().txId, 4); + + return result.applicationIndex; + } + +} diff --git a/examples/src/main/java/com/algorand/examples/AccountExamples.java b/examples/src/main/java/com/algorand/examples/AccountExamples.java new file mode 100644 index 000000000..279b34cb1 --- /dev/null +++ b/examples/src/main/java/com/algorand/examples/AccountExamples.java @@ -0,0 +1,103 @@ +package com.algorand.examples; + +import java.security.NoSuchAlgorithmException; +import java.util.ArrayList; +import java.util.List; + +import com.algorand.algosdk.account.Account; +import com.algorand.algosdk.crypto.Ed25519PublicKey; +import com.algorand.algosdk.crypto.MultisigAddress; +import com.algorand.algosdk.transaction.SignedTransaction; +import com.algorand.algosdk.transaction.Transaction; +import com.algorand.algosdk.util.Encoder; +import com.algorand.algosdk.v2.client.common.AlgodClient; +import com.algorand.algosdk.v2.client.common.Response; +import com.algorand.algosdk.v2.client.model.PostTransactionsResponse; +import com.algorand.algosdk.v2.client.model.TransactionParametersResponse; + +public class AccountExamples { + + public static void main(String[] args) throws Exception { + AlgodClient algodClient = ExampleUtils.getAlgodClient(); + List accts = ExampleUtils.getSandboxAccounts(); + + // Grab some accounts from the sandbox kmd + Account acct1 = accts.get(0); + Account acct2 = accts.get(1); + Account acct3 = accts.get(2); + + MultisigAddress msig = createMsig(acct1, acct2, acct3); + + // Pay the multisig address so it can issue transactions for the demo + Response spResponse = algodClient.TransactionParams().execute(); + TransactionParametersResponse sp = spResponse.body(); + Transaction ptxn = Transaction.PaymentTransactionBuilder() + .sender(acct1.getAddress()).amount(1000000).receiver(msig.toAddress()).suggestedParams(sp).build(); + SignedTransaction stxn = acct1.signTransaction(ptxn); + ExampleUtils.sendPrint(algodClient, stxn, "seed msig"); + + // example: MULTISIG_SIGN + // Construct transaction with sender as address of msig + Transaction msigPayTxn = Transaction.PaymentTransactionBuilder() + .sender(msig.toAddress()) + .amount(1000) + .receiver(acct1.getAddress()) + .suggestedParams(sp) + .build(); + + // For each subsig, sign or append to the existing partially signed transaction + SignedTransaction signedMsigPayTxn = acct1.signMultisigTransaction(msig, msigPayTxn); + signedMsigPayTxn = acct2.appendMultisigTransaction(msig, signedMsigPayTxn); + Response msigSubResponse = algodClient.RawTransaction() + .rawtxn(Encoder.encodeToMsgPack(signedMsigPayTxn)).execute(); + // example: MULTISIG_SIGN + ExampleUtils.printTxnResults(algodClient, msigSubResponse.body(), "msig pay"); + + rekeyAcct(algodClient, acct1, acct2); + + } + + public static MultisigAddress createMsig(Account addr1, Account addr2, Account addr3) + throws NoSuchAlgorithmException { + // example: MULTISIG_CREATE + int version = 1; // no other versions at the time of writing + int threshold = 2; // we're making a 2/3 msig + + // Populate a list of Ed25519 pubkeys + List accts = new ArrayList<>(); + accts.add(addr1.getEd25519PublicKey()); + accts.add(addr2.getEd25519PublicKey()); + accts.add(addr3.getEd25519PublicKey()); + // create the MultisigAddress object + MultisigAddress msig = new MultisigAddress(version, threshold, accts); + System.out.printf("msig address: %s\n", msig.toAddress().toString()); + // example: MULTISIG_CREATE + return msig; + } + + public static void rekeyAcct(AlgodClient algodClient, Account acct1, Account acct2) throws Exception { + TransactionParametersResponse sp = algodClient.TransactionParams().execute().body(); + + // example: ACCOUNT_REKEY + + // Any kind of transaction can contain a rekey, here we use a Payment transaction + Transaction rekeyTxn = Transaction.PaymentTransactionBuilder().sender(acct1.getAddress()) + .receiver(acct1.getAddress()).suggestedParams(sp).rekey(acct2.getAddress()).build(); + SignedTransaction signedRekeyTxn = acct1.signTransaction(rekeyTxn); + Response resp = algodClient.RawTransaction() + .rawtxn(Encoder.encodeToMsgPack(signedRekeyTxn)).execute(); + ExampleUtils.printTxnResults(algodClient, resp.body(), "rekey"); + + // Create a transaction to rekey it back + Transaction rekeyBack = Transaction.PaymentTransactionBuilder().sender(acct1.getAddress()) + .receiver(acct1.getAddress()).suggestedParams(sp).rekey(acct1.getAddress()).build(); + + // note we sign with acct2's key + SignedTransaction signedRekeyBack = acct2.signTransaction(rekeyBack); + Response rekeyBackResponse = algodClient.RawTransaction() + .rawtxn(Encoder.encodeToMsgPack(signedRekeyBack)).execute(); + ExampleUtils.printTxnResults(algodClient, rekeyBackResponse.body(), "rekey back"); + // example: ACCOUNT_REKEY + } + +} \ No newline at end of file diff --git a/examples/src/main/java/com/algorand/examples/Example.java b/examples/src/main/java/com/algorand/examples/Example.java deleted file mode 100644 index d75196700..000000000 --- a/examples/src/main/java/com/algorand/examples/Example.java +++ /dev/null @@ -1,160 +0,0 @@ -package com.algorand.examples; - -import java.security.NoSuchAlgorithmException; -import java.util.List; -import com.algorand.algosdk.v2.client.Utils; -import com.algorand.algosdk.v2.client.common.AlgodClient; -import com.algorand.algosdk.v2.client.common.Response; -import com.algorand.algosdk.v2.client.model.PendingTransactionResponse; -import com.algorand.algosdk.v2.client.model.PostTransactionsResponse; -import com.algorand.algosdk.v2.client.model.TransactionParametersResponse; -import com.algorand.algosdk.account.Account; -import com.algorand.algosdk.transaction.SignedTransaction; -import com.algorand.algosdk.transaction.Transaction; -import com.algorand.algosdk.util.Encoder; - -public class Example { - public static void main(String[] args) throws Exception { - AlgodClient algodClient = ExampleUtils.getAlgodClient(); - List accts = ExampleUtils.getSandboxAccounts(); - // grab the first one from the sandbox kmd - Account acct = accts.get(0); - Account acct2 = accts.get(1); - - // example: TRANSACTION_PAYMENT_CREATE - Response suggestedParams = algodClient.TransactionParams().execute(); - Integer amount = 1000000; // 1 Algo - Transaction ptxn = Transaction.PaymentTransactionBuilder() - .sender(acct.getAddress()) - .amount(amount) - .receiver(acct2.getAddress()) - .suggestedParams(suggestedParams.body()).build(); - // example: TRANSACTION_PAYMENT_CREATE - - - // example: TRANSACTION_PAYMENT_SIGN - SignedTransaction sptxn = acct.signTransaction(ptxn); - // example: TRANSACTION_PAYMENT_SIGN - - // example: TRANSACTION_PAYMENT_SUBMIT - // encode the transaction - byte[] encodedTxBytes = Encoder.encodeToMsgPack(sptxn); - // submit the transaction to the algod server - Response resp = algodClient.RawTransaction().rawtxn(encodedTxBytes).execute(); - // wait for the transaction to be confirmed - String txid = resp.body().txId; - PendingTransactionResponse result = Utils.waitForConfirmation(algodClient, txid, 4); - System.out.printf("Transaction %s confirmed in round %d\n", txid, result.confirmedRound); - // example: TRANSACTION_PAYMENT_SUBMIT - } - - public static void createAccount() throws NoSuchAlgorithmException{ - // example: ACCOUNT_GENERATE - Account acct = new Account(); - System.out.println("Address: " + acct.getAddress()); - System.out.println("Passphrase: " + acct.toMnemonic()); - // example: ACCOUNT_GENERATE - } - - public static AlgodClient createClient() { - // example: ALGOD_CREATE_CLIENT - String algodHost = "http://localhost"; - int algodPort = 4001; - String algodToken = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"; - AlgodClient algodClient = new AlgodClient(algodHost, algodPort, algodToken); - - // OR if the API provider requires a specific header key for the token - String tokenHeader = "X-API-Key"; - AlgodClient otherAlgodClient = new AlgodClient(algodHost, algodPort, algodToken, tokenHeader); - // example: ALGOD_CREATE_CLIENT - return algodClient; - } - - -} - -// Missing ATOMIC_CREATE_TXNS in JAVASDK examples (in -// ../docs/get-details/atomic_transfers.md:71) -// Missing ATOMIC_GROUP_TXNS in JAVASDK examples (in -// ../docs/get-details/atomic_transfers.md:154) -// Missing ATOMIC_GROUP_SIGN in JAVASDK examples (in -// ../docs/get-details/atomic_transfers.md:222) -// Missing ATOMIC_GROUP_ASSEMBLE in JAVASDK examples (in -// ../docs/get-details/atomic_transfers.md:284) -// Missing ATOMIC_GROUP_SEND in JAVASDK examples (in -// ../docs/get-details/atomic_transfers.md:346) -// Missing MULTISIG_CREATE in JAVASDK examples (in -// ../docs/get-details/transactions/signatures.md:256) -// Missing MULTISIG_SIGN in JAVASDK examples (in -// ../docs/get-details/transactions/signatures.md:258) -// Missing TRANSACTION_FEE_OVERRIDE in JAVASDK examples (in -// ../docs/get-details/transactions/index.md:791) -// Missing CODEC_TRANSACTION_UNSIGNED in JAVASDK examples (in -// ../docs/get-details/transactions/offline_transactions.md:62) -// Missing CODEC_TRANSACTION_SIGNED in JAVASDK examples (in -// ../docs/get-details/transactions/offline_transactions.md:268) -// Missing KMD_CREATE_CLIENT in JAVASDK examples (in -// ../docs/get-details/accounts/create.md:115) -// Missing KMD_CREATE_WALLET in JAVASDK examples (in -// ../docs/get-details/accounts/create.md:132) -// Missing KMD_CREATE_ACCOUNT in JAVASDK examples (in -// ../docs/get-details/accounts/create.md:150) -// Missing KMD_RECOVER_WALLET in JAVASDK examples (in -// ../docs/get-details/accounts/create.md:294) -// Missing KMD_EXPORT_ACCOUNT in JAVASDK examples (in -// ../docs/get-details/accounts/create.md:488) -// Missing KMD_IMPORT_ACCOUNT in JAVASDK examples (in -// ../docs/get-details/accounts/create.md:690) -// Missing ACCOUNT_GENERATE in JAVASDK examples (in -// ../docs/get-details/accounts/create.md:894) -// Missing MULTISIG_CREATE in JAVASDK examples (in -// ../docs/get-details/accounts/create.md:1030) -// Missing ACCOUNT_REKEY in JAVASDK examples (in -// ../docs/get-details/accounts/rekey.md:364) -// Missing CODEC_ADDRESS in JAVASDK examples (in -// ../docs/get-details/encoding.md:86) -// Missing CODEC_BASE64 in JAVASDK examples (in -// ../docs/get-details/encoding.md:138) -// Missing CODEC_UINT64 in JAVASDK examples (in -// ../docs/get-details/encoding.md:196) -// Missing CODEC_TRANSACTION_UNSIGNED in JAVASDK examples (in -// ../docs/get-details/encoding.md:337) -// Missing CODEC_TRANSACTION_SIGNED in JAVASDK examples (in -// ../docs/get-details/encoding.md:339) -// Missing CODEC_BLOCK in JAVASDK examples (in -// ../docs/get-details/encoding.md:363) -// Missing CONST_MIN_FEE in JAVASDK examples (in -// ../docs/get-details/dapps/smart-contracts/guidelines.md:62) -// Missing SP_MIN_FEE in JAVASDK examples (in -// ../docs/get-details/dapps/smart-contracts/guidelines.md:96) -// Missing ASSET_CREATE in JAVASDK examples (in ../docs/get-details/asa.md:203) -// Missing ASSET_CONFIG in JAVASDK examples (in ../docs/get-details/asa.md:429) -// Missing ASSET_OPTIN in JAVASDK examples (in ../docs/get-details/asa.md:628) -// Missing ASSET_XFER in JAVASDK examples (in ../docs/get-details/asa.md:809) -// Missing ASSET_FREEZE in JAVASDK examples (in ../docs/get-details/asa.md:1007) -// Missing ASSET_CLAWBACK in JAVASDK examples (in -// ../docs/get-details/asa.md:1193) -// Missing ASSET_DELETE in JAVASDK examples (in ../docs/get-details/asa.md:1386) -// Missing ASSET_INFO in JAVASDK examples (in ../docs/get-details/asa.md:1549) -// Missing ATC_CREATE in JAVASDK examples (in ../docs/get-details/atc.md:48) -// Missing ATC_ADD_TRANSACTION in JAVASDK examples (in -// ../docs/get-details/atc.md:142) -// Missing ATC_CONTRACT_INIT in JAVASDK examples (in -// ../docs/get-details/atc.md:307) -// Missing ATC_ADD_METHOD_CALL in JAVASDK examples (in -// ../docs/get-details/atc.md:325) -// Missing ATC_RESULTS in JAVASDK examples (in ../docs/get-details/atc.md:406) -// Missing CREATE_INDEXER_CLIENT in JAVASDK examples (in -// ../docs/get-details/indexer.md:42) -// Missing INDEXER_LOOKUP_ASSET in JAVASDK examples (in -// ../docs/get-details/indexer.md:131) -// Missing INDEXER_SEARCH_MIN_AMOUNT in JAVASDK examples (in -// ../docs/get-details/indexer.md:205) -// Missing INDEXER_PAGINATE_RESULTS in JAVASDK examples (in -// ../docs/get-details/indexer.md:322) -// Missing INDEXER_PREFIX_SEARCH in JAVASDK examples (in -// ../docs/get-details/indexer.md:477) -// Missing TRANSACTION_KEYREG_OFFLINE_CREATE in JAVASDK examples (in -// ../docs/run-a-node/participate/offline.md:41) -// Missing TRANSACTION_KEYREG_ONLINE_CREATE in JAVASDK examples (in -// ../docs/run-a-node/participate/online.md:42) diff --git a/examples/src/main/java/com/algorand/examples/ExampleUtils.java b/examples/src/main/java/com/algorand/examples/ExampleUtils.java index 33e715fe5..a1fad3a30 100644 --- a/examples/src/main/java/com/algorand/examples/ExampleUtils.java +++ b/examples/src/main/java/com/algorand/examples/ExampleUtils.java @@ -4,8 +4,12 @@ import java.util.ArrayList; import java.util.List; +import com.algorand.algosdk.v2.client.Utils; import com.algorand.algosdk.v2.client.common.AlgodClient; import com.algorand.algosdk.v2.client.common.IndexerClient; +import com.algorand.algosdk.v2.client.common.Response; +import com.algorand.algosdk.v2.client.model.PendingTransactionResponse; +import com.algorand.algosdk.v2.client.model.PostTransactionsResponse; import com.algorand.algosdk.account.Account; import com.algorand.algosdk.crypto.Address; import com.algorand.algosdk.kmd.client.KmdClient; @@ -14,6 +18,8 @@ import com.algorand.algosdk.kmd.client.model.ExportKeyRequest; import com.algorand.algosdk.kmd.client.model.InitWalletHandleTokenRequest; import com.algorand.algosdk.kmd.client.model.ListKeysRequest; +import com.algorand.algosdk.transaction.SignedTransaction; +import com.algorand.algosdk.util.Encoder; import com.algorand.algosdk.kmd.client.ApiException; public class ExampleUtils { @@ -80,13 +86,23 @@ public static String getDefaultWalletHandle() throws ApiException { public static List
getWalletAccounts(String walletHandle) throws ApiException, NoSuchAlgorithmException { List
accounts = new ArrayList<>(); - ListKeysRequest keysRequest = new ListKeysRequest(); keysRequest.setWalletHandleToken(walletHandle); for (String addr : kmd.listKeysInWallet(keysRequest).getAddresses()) { accounts.add(new Address(addr)); } - return accounts; } + + public static void sendPrint(AlgodClient algodClient, SignedTransaction stxn, String name) throws Exception { + Response submitResult = algodClient.RawTransaction() + .rawtxn(Encoder.encodeToMsgPack(stxn)).execute(); + printTxnResults(algodClient, submitResult.body(), name); + } + + + public static void printTxnResults(AlgodClient client, PostTransactionsResponse ptr, String name) throws Exception { + PendingTransactionResponse result = Utils.waitForConfirmation(client, ptr.txId, 4); + System.out.printf("%s transaction (%s) Confirmed in round %d\n", name, ptr.txId, result.confirmedRound); + } } \ No newline at end of file diff --git a/examples/src/main/java/com/algorand/examples/Overview.java b/examples/src/main/java/com/algorand/examples/Overview.java new file mode 100644 index 000000000..de92ad398 --- /dev/null +++ b/examples/src/main/java/com/algorand/examples/Overview.java @@ -0,0 +1,74 @@ +package com.algorand.examples; + +import java.security.NoSuchAlgorithmException; +import java.util.List; +import com.algorand.algosdk.v2.client.Utils; +import com.algorand.algosdk.v2.client.common.AlgodClient; +import com.algorand.algosdk.v2.client.common.Response; +import com.algorand.algosdk.v2.client.model.PendingTransactionResponse; +import com.algorand.algosdk.v2.client.model.PostTransactionsResponse; +import com.algorand.algosdk.v2.client.model.TransactionParametersResponse; +import com.algorand.algosdk.account.Account; +import com.algorand.algosdk.transaction.SignedTransaction; +import com.algorand.algosdk.transaction.Transaction; +import com.algorand.algosdk.util.Encoder; + +public class Overview { + public static void main(String[] args) throws Exception { + AlgodClient algodClient = ExampleUtils.getAlgodClient(); + List accts = ExampleUtils.getSandboxAccounts(); + // grab the first one from the sandbox kmd + Account acct = accts.get(0); + Account acct2 = accts.get(1); + + // example: TRANSACTION_PAYMENT_CREATE + Response suggestedParams = algodClient.TransactionParams().execute(); + Integer amount = 1000000; // 1 Algo + Transaction ptxn = Transaction.PaymentTransactionBuilder() + .sender(acct.getAddress()) + .amount(amount) + .receiver(acct2.getAddress()) + .suggestedParams(suggestedParams.body()).build(); + // example: TRANSACTION_PAYMENT_CREATE + + + // example: TRANSACTION_PAYMENT_SIGN + SignedTransaction sptxn = acct.signTransaction(ptxn); + // example: TRANSACTION_PAYMENT_SIGN + + // example: TRANSACTION_PAYMENT_SUBMIT + // encode the transaction + byte[] encodedTxBytes = Encoder.encodeToMsgPack(sptxn); + // submit the transaction to the algod server + Response resp = algodClient.RawTransaction().rawtxn(encodedTxBytes).execute(); + // wait for the transaction to be confirmed + String txid = resp.body().txId; + PendingTransactionResponse result = Utils.waitForConfirmation(algodClient, txid, 4); + System.out.printf("Transaction %s confirmed in round %d\n", txid, result.confirmedRound); + // example: TRANSACTION_PAYMENT_SUBMIT + } + + public static void createAccount() throws NoSuchAlgorithmException{ + // example: ACCOUNT_GENERATE + Account acct = new Account(); + System.out.println("Address: " + acct.getAddress()); + System.out.println("Passphrase: " + acct.toMnemonic()); + // example: ACCOUNT_GENERATE + } + + public static AlgodClient createClient() { + // example: ALGOD_CREATE_CLIENT + String algodHost = "http://localhost"; + int algodPort = 4001; + String algodToken = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"; + AlgodClient algodClient = new AlgodClient(algodHost, algodPort, algodToken); + + // OR if the API provider requires a specific header key for the token + String tokenHeader = "X-API-Key"; + AlgodClient otherAlgodClient = new AlgodClient(algodHost, algodPort, algodToken, tokenHeader); + // example: ALGOD_CREATE_CLIENT + return algodClient; + } + + +} \ No newline at end of file diff --git a/examples/src/main/java/com/algorand/examples/contract.json b/examples/src/main/java/com/algorand/examples/contract.json new file mode 100644 index 000000000..e69de29bb From 832ebdb6254f4de928c1ca060ab18995d9a7d343 Mon Sep 17 00:00:00 2001 From: Ben Guidarelli Date: Tue, 28 Feb 2023 14:00:13 -0500 Subject: [PATCH 05/22] Adding atomic group examples --- .../main/java/com/algorand/examples/ATC.java | 5 +- .../algorand/examples/AtomicTransfers.java | 73 +++++++++++++++++++ 2 files changed, 76 insertions(+), 2 deletions(-) create mode 100644 examples/src/main/java/com/algorand/examples/AtomicTransfers.java diff --git a/examples/src/main/java/com/algorand/examples/ATC.java b/examples/src/main/java/com/algorand/examples/ATC.java index 5f5d93598..3af97934c 100644 --- a/examples/src/main/java/com/algorand/examples/ATC.java +++ b/examples/src/main/java/com/algorand/examples/ATC.java @@ -82,8 +82,9 @@ public static void main(String[] args) throws Exception { // example: ATC_RESULTS ExecuteResult res = atc.execute(algodClient, 2); System.out.printf("App call (%s) confirmed in round %d\n", res.txIDs, res.confirmedRound); - ReturnValue returnValue = res.methodResults.get(0); - System.out.printf("Result from calling '%s' method: %s\n", returnValue.method.name, returnValue.value); + res.methodResults.forEach(methodResult -> { + System.out.printf("Result from calling '%s' method: %s\n", methodResult.method.name, methodResult.value); + }); // example: ATC_RESULTS } diff --git a/examples/src/main/java/com/algorand/examples/AtomicTransfers.java b/examples/src/main/java/com/algorand/examples/AtomicTransfers.java new file mode 100644 index 000000000..206a91bc0 --- /dev/null +++ b/examples/src/main/java/com/algorand/examples/AtomicTransfers.java @@ -0,0 +1,73 @@ +package com.algorand.examples; + +import java.util.List; + +import com.algorand.algosdk.account.Account; +import com.algorand.algosdk.crypto.Digest; +import com.algorand.algosdk.transaction.SignedTransaction; +import com.algorand.algosdk.transaction.Transaction; +import com.algorand.algosdk.transaction.TxGroup; +import com.algorand.algosdk.util.Encoder; +import com.algorand.algosdk.v2.client.Utils; +import com.algorand.algosdk.v2.client.algod.RawTransaction; +import com.algorand.algosdk.v2.client.common.AlgodClient; +import com.algorand.algosdk.v2.client.common.Response; +import com.algorand.algosdk.v2.client.model.PendingTransactionResponse; +import com.algorand.algosdk.v2.client.model.PostTransactionsResponse; +import com.algorand.algosdk.v2.client.model.TransactionParametersResponse; + +public class AtomicTransfers { + public static void main(String[] args) throws Exception { + AlgodClient algodClient = ExampleUtils.getAlgodClient(); + List accts = ExampleUtils.getSandboxAccounts(); + + Account acct1 = accts.get(0); + Account acct2 = accts.get(1); + + // example: ATOMIC_CREATE_TXNS + Response rsp = algodClient.TransactionParams().execute(); + + // payment from account 1 to account 2 + Transaction ptxn1 = Transaction.PaymentTransactionBuilder().sender(acct1.getAddress()) + .amount(1000000).receiver(acct2.getAddress()).suggestedParams(rsp.body()).build(); + // txn_1 = transaction.PaymentTxn(addr1, suggested_params, addr2, 100000) + + // payment from account 2 to account 1 + Transaction ptxn2 = Transaction.PaymentTransactionBuilder().sender(acct2.getAddress()) + .amount(2000000).receiver(acct1.getAddress()).suggestedParams(rsp.body()).build(); + // example: ATOMIC_CREATE_TXNS + + // example: ATOMIC_GROUP_TXNS + // Assign group id to the transactions (order matters!) + Transaction[] txs = TxGroup.assignGroupID(ptxn1, ptxn2); + + // Or, equivalently + // compute group id and assign it to transactions + Digest gid = TxGroup.computeGroupID(txs); + ptxn1.group = gid; + ptxn2.group = gid; + // example: ATOMIC_GROUP_TXNS + + // example: ATOMIC_GROUP_SIGN + // sign transactions + SignedTransaction signedPtxn1 = acct1.signTransaction(ptxn1); + SignedTransaction signedPtxn2 = acct2.signTransaction(ptxn2); + // # example: ATOMIC_GROUP_SIGN + + // example: ATOMIC_GROUP_ASSEMBLE + // combine the signed transactions into a single list + SignedTransaction[] stxns = new SignedTransaction[] { signedPtxn1, signedPtxn2 }; + // example: ATOMIC_GROUP_ASSEMBLE + + // example: ATOMIC_GROUP_SEND + // Only the first transaction id is returned + Response txResponse = algodClient.RawTransaction().rawtxn(Encoder.encodeToMsgPack(stxns)).execute(); + String txid = txResponse.body().txId; + + // Wait for it to be confirmed + PendingTransactionResponse txResult = Utils.waitForConfirmation(algodClient, txid, 4); + System.out.printf("Transaction %s confirmed in round %d\n", txid, txResult.confirmedRound); + // example: ATOMIC_GROUP_SEND + } + +} \ No newline at end of file From 2feb59d73ee4fe0599cbc2fbc31bc12bd2ccc24e Mon Sep 17 00:00:00 2001 From: Ben Guidarelli Date: Tue, 28 Feb 2023 14:48:32 -0500 Subject: [PATCH 06/22] adding asset examples --- .../com/algorand/examples/ASAExamples.java | 173 ++++++++++++++++++ .../main/java/com/algorand/examples/ATC.java | 9 +- .../algorand/examples/AtomicTransfers.java | 5 +- 3 files changed, 180 insertions(+), 7 deletions(-) create mode 100644 examples/src/main/java/com/algorand/examples/ASAExamples.java diff --git a/examples/src/main/java/com/algorand/examples/ASAExamples.java b/examples/src/main/java/com/algorand/examples/ASAExamples.java new file mode 100644 index 000000000..d26d1a50a --- /dev/null +++ b/examples/src/main/java/com/algorand/examples/ASAExamples.java @@ -0,0 +1,173 @@ +package com.algorand.examples; + +import java.util.List; + +import com.algorand.algosdk.account.Account; +import com.algorand.algosdk.transaction.SignedTransaction; +import com.algorand.algosdk.transaction.Transaction; +import com.algorand.algosdk.util.Encoder; +import com.algorand.algosdk.v2.client.Utils; +import com.algorand.algosdk.v2.client.common.AlgodClient; +import com.algorand.algosdk.v2.client.common.Response; +import com.algorand.algosdk.v2.client.model.Asset; +import com.algorand.algosdk.v2.client.model.PendingTransactionResponse; +import com.algorand.algosdk.v2.client.model.PostTransactionsResponse; +import com.algorand.algosdk.v2.client.model.TransactionParametersResponse; + +public class ASAExamples { + + public static void main(String[] args) throws Exception { + AlgodClient algodClient = ExampleUtils.getAlgodClient(); + List accts = ExampleUtils.getSandboxAccounts(); + Account acct1 = accts.get(0); + Account acct2 = accts.get(1); + + Long asaId = createAsset(algodClient, acct1); + + // example: ASSET_INFO + // Retrieve the asset info of the newly created asset + Response assetResp = algodClient.GetAssetByID(asaId).execute(); + Asset assetInfo = assetResp.body(); + System.out.printf("Asset Name: %s", assetInfo.params.name); + // example: ASSET_INFO + + optInToAsset(algodClient, acct2, asaId); + xferAsset(algodClient, acct1, acct2, asaId); + freezeAsset(algodClient, acct1, acct2, asaId); + clawbackAsset(algodClient, acct1, acct2, asaId); + deleteAsset(algodClient, acct1, asaId); + + } + + public static Long createAsset(AlgodClient algodClient, Account acct) throws Exception { + // example: ASSET_CREATE + // Account 1 creates an asset called `rug` with a total supply + // of 1000 units and sets itself to the freeze/clawback/manager/reserve roles + Response rsp = algodClient.TransactionParams().execute(); + TransactionParametersResponse sp = rsp.body(); + + // Under the covers, this is an AssetConfig with asset id set to 0 + Transaction createTxn = Transaction.AssetCreateTransactionBuilder().suggestedParams(sp) + .sender(acct.getAddress()) + .assetTotal(1000) + .assetDecimals(0) + .defaultFrozen(false) + .assetUnitName("rug") + .assetName("Really Useful Gift") + .url("https://path/to/my/asset/details") + .manager(acct.getAddress()) + .reserve(acct.getAddress()) + .freeze(acct.getAddress()) + .clawback(acct.getAddress()) + .build(); + + SignedTransaction signedCreateTxn = acct.signTransaction(createTxn); + Response submitResult = algodClient.RawTransaction() + .rawtxn(Encoder.encodeToMsgPack(signedCreateTxn)).execute(); + String txId = submitResult.body().txId; + PendingTransactionResponse result = Utils.waitForConfirmation(algodClient, txId, 4); + + // Grab the asset id for the asset we just created + Long asaId = result.assetIndex; + System.out.printf("Created asset with id: %d\n", asaId); + + // example: ASSET_CREATE + return asaId; + } + + public static void optInToAsset(AlgodClient algodClient, Account acct, Long asaId) throws Exception { + // example: ASSET_OPTIN + Response rsp = algodClient.TransactionParams().execute(); + TransactionParametersResponse sp = rsp.body(); + // Under the covers, this is an AssetTransfer from me to me for amount 0 + // with asset id set to the asset we wish to start accepting + Transaction optInTxn = Transaction.AssetAcceptTransactionBuilder().suggestedParams(sp) + .sender(acct.getAddress()) + .assetIndex(asaId) + .build(); + + // example: ASSET_OPTIN + SignedTransaction signedOptIn = acct.signTransaction(optInTxn); + ExampleUtils.sendPrint(algodClient, signedOptIn, "opt in asset"); + } + + public static void xferAsset(AlgodClient algodClient, Account sender, Account receiver, Long asaId) + throws Exception { + // example: ASSET_XFER + Response rsp = algodClient.TransactionParams().execute(); + TransactionParametersResponse sp = rsp.body(); + // Under the covers, this is an AssetTransfer from me to me for amount 0 + // with asset id set to the asset we wish to start accepting + Transaction xferTxn = Transaction.AssetTransferTransactionBuilder().suggestedParams(sp) + .sender(sender.getAddress()) + .assetReceiver(receiver.getAddress()) + .assetIndex(asaId) + .assetAmount(1) + .build(); + + // example: ASSET_XFER + SignedTransaction signedXfer = sender.signTransaction(xferTxn); + ExampleUtils.sendPrint(algodClient, signedXfer, "xfer asset"); + } + + public static void freezeAsset(AlgodClient algodClient, Account sender, Account receiver, Long asaId) + throws Exception { + // example: ASSET_FREEZE + Response rsp = algodClient.TransactionParams().execute(); + TransactionParametersResponse sp = rsp.body(); + // Set the freeze state on the account, only the account that is set to the + // freeze role + // on the asset may issue this transaction + Transaction freezeTxn = Transaction.AssetFreezeTransactionBuilder().suggestedParams(sp) + .sender(sender.getAddress()) + .freezeTarget(receiver.getAddress()) + .freezeState(true) + .assetIndex(asaId) + .build(); + + // example: ASSET_FREEZE + SignedTransaction signedFreeze = sender.signTransaction(freezeTxn); + ExampleUtils.sendPrint(algodClient, signedFreeze, "freeze asset"); + } + + public static void clawbackAsset(AlgodClient algodClient, Account sender, Account receiver, Long asaId) + throws Exception { + // example: ASSET_CLAWBACK + Response rsp = algodClient.TransactionParams().execute(); + TransactionParametersResponse sp = rsp.body(); + // revoke an asset from an account, only the account that is set to the clawback + // role + // on the asset may issue this transaction + Transaction clawbackTxn = Transaction.AssetClawbackTransactionBuilder().suggestedParams(sp) + .sender(sender.getAddress()) + .assetClawbackFrom(receiver.getAddress()) + .assetReceiver(sender.getAddress()) + .assetIndex(asaId) + .assetAmount(1) + .build(); + + // example: ASSET_CLAWBACK + SignedTransaction signedClawback = sender.signTransaction(clawbackTxn); + ExampleUtils.sendPrint(algodClient, signedClawback, "clawback asset"); + } + + public static void deleteAsset(AlgodClient algodClient, Account acct, Long asaId) throws Exception { + // example: ASSET_DELETE + Response rsp = algodClient.TransactionParams().execute(); + TransactionParametersResponse sp = rsp.body(); + // Under the covers, an AssetDestroyTransaction is an AssetConfig with all of + // its + // configurable fields set to empty + // All units of the asset _must_ be owned by the creator account and this + // transaction _must_ + // be issued by the account set to the manager role on the asset + Transaction destroyTxn = Transaction.AssetDestroyTransactionBuilder().suggestedParams(sp) + .sender(acct.getAddress()) + .assetIndex(asaId) + .build(); + + // example: ASSET_DELETE + SignedTransaction signedDestroy = acct.signTransaction(destroyTxn); + ExampleUtils.sendPrint(algodClient, signedDestroy, "clawback asset"); + } +} diff --git a/examples/src/main/java/com/algorand/examples/ATC.java b/examples/src/main/java/com/algorand/examples/ATC.java index 3af97934c..c729093e2 100644 --- a/examples/src/main/java/com/algorand/examples/ATC.java +++ b/examples/src/main/java/com/algorand/examples/ATC.java @@ -18,7 +18,6 @@ import com.algorand.algosdk.transaction.Transaction; import com.algorand.algosdk.transaction.TransactionWithSigner; import com.algorand.algosdk.transaction.AtomicTransactionComposer.ExecuteResult; -import com.algorand.algosdk.transaction.AtomicTransactionComposer.ReturnValue; import com.algorand.algosdk.util.Encoder; import com.algorand.algosdk.v2.client.Utils; import com.algorand.algosdk.v2.client.common.AlgodClient; @@ -67,14 +66,14 @@ public static void main(String[] args) throws Exception { // example: ATC_ADD_METHOD_CALL // create methodCallParams by builder (or create by constructor) for add method - List method_args = new ArrayList(); - method_args.add(1); - method_args.add(1); + List methodArgs = new ArrayList(); + methodArgs.add(1); + methodArgs.add(1); MethodCallTransactionBuilder mctb = MethodCallTransactionBuilder.Builder(); MethodCallParams mcp = mctb.applicationId(appId).signer(acct.getTransactionSigner()).sender(acct.getAddress()) - .method(contract.getMethodByName("add")).methodArguments(method_args) + .method(contract.getMethodByName("add")).methodArguments(methodArgs) .onComplete(Transaction.OnCompletion.NoOpOC).suggestedParams(sp).build(); atc.addMethodCall(mcp); diff --git a/examples/src/main/java/com/algorand/examples/AtomicTransfers.java b/examples/src/main/java/com/algorand/examples/AtomicTransfers.java index 206a91bc0..8ec66d303 100644 --- a/examples/src/main/java/com/algorand/examples/AtomicTransfers.java +++ b/examples/src/main/java/com/algorand/examples/AtomicTransfers.java @@ -9,7 +9,6 @@ import com.algorand.algosdk.transaction.TxGroup; import com.algorand.algosdk.util.Encoder; import com.algorand.algosdk.v2.client.Utils; -import com.algorand.algosdk.v2.client.algod.RawTransaction; import com.algorand.algosdk.v2.client.common.AlgodClient; import com.algorand.algosdk.v2.client.common.Response; import com.algorand.algosdk.v2.client.model.PendingTransactionResponse; @@ -64,7 +63,9 @@ public static void main(String[] args) throws Exception { Response txResponse = algodClient.RawTransaction().rawtxn(Encoder.encodeToMsgPack(stxns)).execute(); String txid = txResponse.body().txId; - // Wait for it to be confirmed + // Wait for the transaction id to be confirmed + // If the results from other transactions are needed, grab the txid from those directly and + // call waitForConfirmation on each PendingTransactionResponse txResult = Utils.waitForConfirmation(algodClient, txid, 4); System.out.printf("Transaction %s confirmed in round %d\n", txid, txResult.confirmedRound); // example: ATOMIC_GROUP_SEND From af3e068c046fb563f75efcccbb78458c6e81603d Mon Sep 17 00:00:00 2001 From: Ben Guidarelli Date: Tue, 28 Feb 2023 15:16:05 -0500 Subject: [PATCH 07/22] adding codec examples --- .../com/algorand/examples/ASAExamples.java | 39 +++++++++-- .../com/algorand/examples/CodecExamples.java | 66 +++++++++++++++++++ .../com/algorand/examples/ExampleUtils.java | 2 +- 3 files changed, 99 insertions(+), 8 deletions(-) create mode 100644 examples/src/main/java/com/algorand/examples/CodecExamples.java diff --git a/examples/src/main/java/com/algorand/examples/ASAExamples.java b/examples/src/main/java/com/algorand/examples/ASAExamples.java index d26d1a50a..f431723e1 100644 --- a/examples/src/main/java/com/algorand/examples/ASAExamples.java +++ b/examples/src/main/java/com/algorand/examples/ASAExamples.java @@ -2,6 +2,8 @@ import java.util.List; +import org.bouncycastle.pqc.crypto.ExchangePair; + import com.algorand.algosdk.account.Account; import com.algorand.algosdk.transaction.SignedTransaction; import com.algorand.algosdk.transaction.Transaction; @@ -24,19 +26,22 @@ public static void main(String[] args) throws Exception { Long asaId = createAsset(algodClient, acct1); - // example: ASSET_INFO - // Retrieve the asset info of the newly created asset - Response assetResp = algodClient.GetAssetByID(asaId).execute(); - Asset assetInfo = assetResp.body(); - System.out.printf("Asset Name: %s", assetInfo.params.name); - // example: ASSET_INFO - + printAssetInfo(algodClient, asaId); + configureAsset(algodClient, acct1, asaId); optInToAsset(algodClient, acct2, asaId); xferAsset(algodClient, acct1, acct2, asaId); freezeAsset(algodClient, acct1, acct2, asaId); clawbackAsset(algodClient, acct1, acct2, asaId); deleteAsset(algodClient, acct1, asaId); + } + public static void printAssetInfo(AlgodClient algodClient, Long asaId) throws Exception { + // example: ASSET_INFO + // Retrieve the asset info of the newly created asset + Response assetResp = algodClient.GetAssetByID(asaId).execute(); + Asset assetInfo = assetResp.body(); + System.out.printf("Asset Name: %s\n", assetInfo.params.name); + // example: ASSET_INFO } public static Long createAsset(AlgodClient algodClient, Account acct) throws Exception { @@ -75,6 +80,26 @@ public static Long createAsset(AlgodClient algodClient, Account acct) throws Exc return asaId; } + public static void configureAsset(AlgodClient algodClient, Account acct, Long asaId) throws Exception { + // example: ASSET_CONFIG + Response rsp = algodClient.TransactionParams().execute(); + TransactionParametersResponse sp = rsp.body(); + // Wipe the `reserve` address through an AssetConfigTransaction + Transaction reconfigureTxn = Transaction.AssetConfigureTransactionBuilder().suggestedParams(sp) + .sender(acct.getAddress()) + .assetIndex(asaId) + .manager(acct.getAddress()) + .freeze(acct.getAddress()) + .clawback(acct.getAddress()) + .strictEmptyAddressChecking(false) + .reserve(new byte[32]) + .build(); + + // example: ASSET_CONFIG + SignedTransaction signedReconfigure = acct.signTransaction(reconfigureTxn); + ExampleUtils.sendPrint(algodClient, signedReconfigure, "config asset"); + } + public static void optInToAsset(AlgodClient algodClient, Account acct, Long asaId) throws Exception { // example: ASSET_OPTIN Response rsp = algodClient.TransactionParams().execute(); diff --git a/examples/src/main/java/com/algorand/examples/CodecExamples.java b/examples/src/main/java/com/algorand/examples/CodecExamples.java new file mode 100644 index 000000000..b36ec6a5c --- /dev/null +++ b/examples/src/main/java/com/algorand/examples/CodecExamples.java @@ -0,0 +1,66 @@ +package com.algorand.examples; + +import java.math.BigInteger; +import java.util.List; + +import com.algorand.algosdk.account.Account; +import com.algorand.algosdk.crypto.Address; +import com.algorand.algosdk.transaction.SignedTransaction; +import com.algorand.algosdk.transaction.Transaction; +import com.algorand.algosdk.util.Encoder; +import com.algorand.algosdk.v2.client.common.AlgodClient; +import com.algorand.algosdk.v2.client.common.Response; +import com.algorand.algosdk.v2.client.model.TransactionParametersResponse; + +public class CodecExamples { + + public static void main(String[] args) throws Exception { + AlgodClient algodClient = ExampleUtils.getAlgodClient(); + List accts = ExampleUtils.getSandboxAccounts(); + Account acct = accts.get(0); + + // example: CODEC_ADDRESS + String addrAsStr = "4H5UNRBJ2Q6JENAXQ6HNTGKLKINP4J4VTQBEPK5F3I6RDICMZBPGNH6KD4"; + // Instantiate a new Address object with string + Address addr = new Address(addrAsStr); + // Or with the bytes + Address addrAgain = new Address(addr.getBytes()); + assert addrAgain.equals(addr); + // example: CODEC_ADDRESS + + // example: CODEC_BASE64 + String encodedStr = "SGksIEknbSBkZWNvZGVkIGZyb20gYmFzZTY0"; + byte[] decodedBytes = Encoder.decodeFromBase64(encodedStr); + String reEncodedStr = Encoder.encodeToBase64(decodedBytes); + assert encodedStr.equals(reEncodedStr); + // example: CODEC_BASE64 + + // example: CODEC_UINT64 + BigInteger val = BigInteger.valueOf(1337); + byte[] encodedVal = Encoder.encodeUint64(val); + BigInteger decodedVal = Encoder.decodeUint64(encodedVal); + assert val.equals(decodedVal); + // example: CODEC_UINT64 + + // example: CODEC_TRANSACTION_UNSIGNED + Response rsp = algodClient.TransactionParams().execute(); + TransactionParametersResponse sp = rsp.body(); + // Wipe the `reserve` address through an AssetConfigTransaction + Transaction ptxn = Transaction.PaymentTransactionBuilder().suggestedParams(sp) + .sender(acct.getAddress()).receiver(acct.getAddress()).amount(100).build(); + + byte[] encodedTxn = Encoder.encodeToMsgPack(ptxn); + + Transaction decodedTxn = Encoder.decodeFromMsgPack(encodedTxn, Transaction.class); + assert decodedTxn.equals(ptxn); + // example: CODEC_TRANSACTION_UNSIGNED + + // example: CODEC_TRANSACTION_SIGNED + SignedTransaction signedTxn = acct.signTransaction(ptxn); + byte[] encodedSignedTxn = Encoder.encodeToMsgPack(signedTxn); + + SignedTransaction decodedSignedTransaction = Encoder.decodeFromMsgPack(encodedSignedTxn, SignedTransaction.class); + assert decodedSignedTransaction.equals(signedTxn); + // example: CODEC_TRANSACTION_SIGNED + } +} diff --git a/examples/src/main/java/com/algorand/examples/ExampleUtils.java b/examples/src/main/java/com/algorand/examples/ExampleUtils.java index a1fad3a30..ffa4d82ff 100644 --- a/examples/src/main/java/com/algorand/examples/ExampleUtils.java +++ b/examples/src/main/java/com/algorand/examples/ExampleUtils.java @@ -103,6 +103,6 @@ public static void sendPrint(AlgodClient algodClient, SignedTransaction stxn, St public static void printTxnResults(AlgodClient client, PostTransactionsResponse ptr, String name) throws Exception { PendingTransactionResponse result = Utils.waitForConfirmation(client, ptr.txId, 4); - System.out.printf("%s transaction (%s) Confirmed in round %d\n", name, ptr.txId, result.confirmedRound); + System.out.printf("%s\ttransaction (%s) was confirmed in round %d\n", name, ptr.txId, result.confirmedRound); } } \ No newline at end of file From 7f13b7fa618f0870b47c67c34079d403cf437562 Mon Sep 17 00:00:00 2001 From: Ben Guidarelli Date: Tue, 28 Feb 2023 15:35:47 -0500 Subject: [PATCH 08/22] adding indexer examples --- .../algorand/examples/IndexerExamples.java | 57 +++++++++++++++++++ 1 file changed, 57 insertions(+) create mode 100644 examples/src/main/java/com/algorand/examples/IndexerExamples.java diff --git a/examples/src/main/java/com/algorand/examples/IndexerExamples.java b/examples/src/main/java/com/algorand/examples/IndexerExamples.java new file mode 100644 index 000000000..832fa104a --- /dev/null +++ b/examples/src/main/java/com/algorand/examples/IndexerExamples.java @@ -0,0 +1,57 @@ +package com.algorand.examples; + +import com.algorand.algosdk.v2.client.common.IndexerClient; +import com.algorand.algosdk.v2.client.common.Response; +import com.algorand.algosdk.v2.client.model.Asset; +import com.algorand.algosdk.v2.client.model.AssetResponse; +import com.algorand.algosdk.v2.client.model.TransactionsResponse; + +public class IndexerExamples { + + public static void main(String[] args) throws Exception { + // example: CREATE_INDEXER_CLIENT + String indexerHost = "http://localhost"; + int indexerPort = 8980; + String indexerToken = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"; + IndexerClient indexerClient = new IndexerClient(indexerHost, indexerPort, indexerToken); + // example: CREATE_INDEXER_CLIENT + + // example: INDEXER_LOOKUP_ASSET + Long asaId = 25l; + Response assetResponse = indexerClient.lookupAssetByID(asaId).execute(); + Asset assetInfo = assetResponse.body().asset; + System.out.printf("Name for %d: %s\n", asaId, assetInfo.params.name); + // example: INDEXER_LOOKUP_ASSET + + // example: INDEXER_SEARCH_MIN_AMOUNT + Response transactionSearchResult = indexerClient.searchForTransactions() + .minRound(10l).maxRound(500l).currencyGreaterThan(10l).execute(); + TransactionsResponse txResp = transactionSearchResult.body(); + System.out.printf("Found %d transactions that match criteria\n", txResp.transactions.size()); + // example: INDEXER_SEARCH_MIN_AMOUNT + + // example: INDEXER_PAGINATE_RESULTS + String nextToken = ""; + boolean hasResults = true; + // Start with empty nextToken and while there are + // results in the transaction results, query again with the next page + while(hasResults){ + Response searchResults = indexerClient.searchForTransactions().minRound(1000l) + .maxRound(1500l).currencyGreaterThan(10l).next(nextToken).execute(); + TransactionsResponse txnRes = searchResults.body(); + // + // ... do something with transaction results + // + hasResults = txnRes.transactions.size()>0; + nextToken = txnRes.nextToken; + } + // example: INDEXER_PAGINATE_RESULTS + + // example: INDEXER_PREFIX_SEARCH + byte[] prefix = new String("showing prefix").getBytes(); + Response prefixResults = indexerClient.searchForTransactions().notePrefix(prefix).execute(); + // ... + // example: INDEXER_PREFIX_SEARCH + } + +} From e69977536d0703a6116ca82eb45ae4e97d25a995 Mon Sep 17 00:00:00 2001 From: Ben Guidarelli Date: Tue, 28 Feb 2023 16:06:09 -0500 Subject: [PATCH 09/22] starting to add kmd examples --- .../com/algorand/examples/KMDExamples.java | 75 +++++++++++++++++++ 1 file changed, 75 insertions(+) create mode 100644 examples/src/main/java/com/algorand/examples/KMDExamples.java diff --git a/examples/src/main/java/com/algorand/examples/KMDExamples.java b/examples/src/main/java/com/algorand/examples/KMDExamples.java new file mode 100644 index 000000000..80c770f7b --- /dev/null +++ b/examples/src/main/java/com/algorand/examples/KMDExamples.java @@ -0,0 +1,75 @@ +package com.algorand.examples; + +import com.algorand.algosdk.kmd.client.ApiException; +import com.algorand.algosdk.kmd.client.KmdClient; +import com.algorand.algosdk.kmd.client.api.KmdApi; +import com.algorand.algosdk.kmd.client.model.APIV1POSTKeyResponse; +import com.algorand.algosdk.kmd.client.model.APIV1POSTWalletInitResponse; +import com.algorand.algosdk.kmd.client.model.APIV1POSTWalletResponse; +import com.algorand.algosdk.kmd.client.model.APIV1Wallet; +import com.algorand.algosdk.kmd.client.model.CreateWalletRequest; +import com.algorand.algosdk.kmd.client.model.GenerateKeyRequest; +import com.algorand.algosdk.kmd.client.model.InitWalletHandleTokenRequest; + +public class KMDExamples { + + public static void main(String[] args) throws ApiException { + // example: KMD_CREATE_CLIENT + String kmdHost = "http://localhost:4002"; + String kmdToken = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"; + + KmdClient kmdClient = new KmdClient(); + kmdClient.setBasePath(kmdHost); + kmdClient.setApiKey(kmdToken); + + KmdApi kmd = new KmdApi(kmdClient); + // example: KMD_CREATE_CLIENT + + + // example: KMD_CREATE_WALLET + CreateWalletRequest cwr = new CreateWalletRequest(); + cwr.setWalletName("MyNewWallet"); + cwr.setWalletPassword("supersecretpassword"); + cwr.setWalletDriverName("sqlite"); // other option is `ledger` + APIV1POSTWalletResponse result = kmd.createWallet(cwr); + APIV1Wallet wallet = result.getWallet(); + System.out.printf("Wallet name: %s\n", wallet.getName()); + // example: KMD_CREATE_WALLET + + // example: KMD_CREATE_ACCOUNT + // First grab a handle that we can re-use + InitWalletHandleTokenRequest tokenReq = new InitWalletHandleTokenRequest(); + tokenReq.setWalletId(wallet.getId()); + tokenReq.setWalletPassword("supersecretpassword"); + APIV1POSTWalletInitResponse handleTokenResp = kmd.initWalletHandleToken(tokenReq); + + GenerateKeyRequest gkr = new GenerateKeyRequest(); + gkr.setWalletHandleToken(handleTokenResp.getWalletHandleToken()); + APIV1POSTKeyResponse generatedKey = kmd.generateKey(gkr); + System.out.printf("New account: %s\n", generatedKey.getAddress()); + // example: KMD_CREATE_ACCOUNT + + // /example: KMD_RECOVER_WALLET + // /... + // /example: KMD_RECOVER_WALLET + + // /example: KMD_EXPORT_ACCOUNT + // /example: KMD_EXPORT_ACCOUNT + + // /example: KMD_IMPORT_ACCOUNT + // /example: KMD_IMPORT_ACCOUNT + + // Get accounts from sandbox. + // String walletHandle = getDefaultWalletHandle(); + // List
addresses = getWalletAccounts(walletHandle); + + // List accts = new ArrayList<>(); + // for(Address addr: addresses){ + // byte[] pk = lookupPrivateKey(addr, walletHandle); + // accts.add(new Account(pk)); + // } + // return accts; + + } + +} From 076a859d0f6d0022484ce6cc46f7b703266f2fec Mon Sep 17 00:00:00 2001 From: Ben Guidarelli Date: Tue, 28 Feb 2023 16:12:31 -0500 Subject: [PATCH 10/22] found interface for key export --- .../com/algorand/examples/KMDExamples.java | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/examples/src/main/java/com/algorand/examples/KMDExamples.java b/examples/src/main/java/com/algorand/examples/KMDExamples.java index 80c770f7b..71b7d18f3 100644 --- a/examples/src/main/java/com/algorand/examples/KMDExamples.java +++ b/examples/src/main/java/com/algorand/examples/KMDExamples.java @@ -4,10 +4,12 @@ import com.algorand.algosdk.kmd.client.KmdClient; import com.algorand.algosdk.kmd.client.api.KmdApi; import com.algorand.algosdk.kmd.client.model.APIV1POSTKeyResponse; +import com.algorand.algosdk.kmd.client.model.APIV1POSTMasterKeyExportResponse; import com.algorand.algosdk.kmd.client.model.APIV1POSTWalletInitResponse; import com.algorand.algosdk.kmd.client.model.APIV1POSTWalletResponse; import com.algorand.algosdk.kmd.client.model.APIV1Wallet; import com.algorand.algosdk.kmd.client.model.CreateWalletRequest; +import com.algorand.algosdk.kmd.client.model.ExportMasterKeyRequest; import com.algorand.algosdk.kmd.client.model.GenerateKeyRequest; import com.algorand.algosdk.kmd.client.model.InitWalletHandleTokenRequest; @@ -26,10 +28,13 @@ public static void main(String[] args) throws ApiException { // example: KMD_CREATE_CLIENT + String walletName = "MyNewWallet"; + String password = "supersecretpassword"; // example: KMD_CREATE_WALLET + //create a new request CreateWalletRequest cwr = new CreateWalletRequest(); - cwr.setWalletName("MyNewWallet"); - cwr.setWalletPassword("supersecretpassword"); + cwr.setWalletName(walletName); + cwr.setWalletPassword(password); cwr.setWalletDriverName("sqlite"); // other option is `ledger` APIV1POSTWalletResponse result = kmd.createWallet(cwr); APIV1Wallet wallet = result.getWallet(); @@ -40,15 +45,21 @@ public static void main(String[] args) throws ApiException { // First grab a handle that we can re-use InitWalletHandleTokenRequest tokenReq = new InitWalletHandleTokenRequest(); tokenReq.setWalletId(wallet.getId()); - tokenReq.setWalletPassword("supersecretpassword"); + tokenReq.setWalletPassword(password); APIV1POSTWalletInitResponse handleTokenResp = kmd.initWalletHandleToken(tokenReq); + String handleToken = handleTokenResp.getWalletHandleToken() GenerateKeyRequest gkr = new GenerateKeyRequest(); - gkr.setWalletHandleToken(handleTokenResp.getWalletHandleToken()); + gkr.setWalletHandleToken(handleToken); APIV1POSTKeyResponse generatedKey = kmd.generateKey(gkr); System.out.printf("New account: %s\n", generatedKey.getAddress()); // example: KMD_CREATE_ACCOUNT + ExportMasterKeyRequest mker = new ExportMasterKeyRequest(); + mker.setWalletHandleToken(handleToken); + APIV1POSTMasterKeyExportResponse masterKeyResp = kmd.exportMasterKey(mker); + byte[] backupKey = masterKeyResp.getMasterDerivationKey(); + // /example: KMD_RECOVER_WALLET // /... // /example: KMD_RECOVER_WALLET From 5ce36cb59e87b5f20c7df9684b82e14b3bda968c Mon Sep 17 00:00:00 2001 From: Ben Guidarelli Date: Wed, 1 Mar 2023 07:51:46 -0500 Subject: [PATCH 11/22] adding kmd examples --- .../com/algorand/examples/KMDExamples.java | 100 ++++++++++++------ .../java/com/algorand/examples/contract.json | 0 2 files changed, 67 insertions(+), 33 deletions(-) delete mode 100644 examples/src/main/java/com/algorand/examples/contract.json diff --git a/examples/src/main/java/com/algorand/examples/KMDExamples.java b/examples/src/main/java/com/algorand/examples/KMDExamples.java index 71b7d18f3..86cdba618 100644 --- a/examples/src/main/java/com/algorand/examples/KMDExamples.java +++ b/examples/src/main/java/com/algorand/examples/KMDExamples.java @@ -1,17 +1,24 @@ package com.algorand.examples; +import org.bouncycastle.util.Arrays; + import com.algorand.algosdk.kmd.client.ApiException; import com.algorand.algosdk.kmd.client.KmdClient; import com.algorand.algosdk.kmd.client.api.KmdApi; +import com.algorand.algosdk.kmd.client.model.APIV1POSTKeyExportResponse; +import com.algorand.algosdk.kmd.client.model.APIV1POSTKeyImportResponse; import com.algorand.algosdk.kmd.client.model.APIV1POSTKeyResponse; import com.algorand.algosdk.kmd.client.model.APIV1POSTMasterKeyExportResponse; import com.algorand.algosdk.kmd.client.model.APIV1POSTWalletInitResponse; import com.algorand.algosdk.kmd.client.model.APIV1POSTWalletResponse; import com.algorand.algosdk.kmd.client.model.APIV1Wallet; import com.algorand.algosdk.kmd.client.model.CreateWalletRequest; +import com.algorand.algosdk.kmd.client.model.ExportKeyRequest; import com.algorand.algosdk.kmd.client.model.ExportMasterKeyRequest; import com.algorand.algosdk.kmd.client.model.GenerateKeyRequest; +import com.algorand.algosdk.kmd.client.model.ImportKeyRequest; import com.algorand.algosdk.kmd.client.model.InitWalletHandleTokenRequest; +import com.algorand.algosdk.mnemonic.Mnemonic; public class KMDExamples { @@ -30,57 +37,84 @@ public static void main(String[] args) throws ApiException { String walletName = "MyNewWallet"; String password = "supersecretpassword"; + // example: KMD_CREATE_WALLET - //create a new request + // create a new CreateWalletRequest and set parameters CreateWalletRequest cwr = new CreateWalletRequest(); cwr.setWalletName(walletName); cwr.setWalletPassword(password); cwr.setWalletDriverName("sqlite"); // other option is `ledger` + // using our client, pass the request APIV1POSTWalletResponse result = kmd.createWallet(cwr); APIV1Wallet wallet = result.getWallet(); System.out.printf("Wallet name: %s\n", wallet.getName()); // example: KMD_CREATE_WALLET - // example: KMD_CREATE_ACCOUNT - // First grab a handle that we can re-use - InitWalletHandleTokenRequest tokenReq = new InitWalletHandleTokenRequest(); - tokenReq.setWalletId(wallet.getId()); - tokenReq.setWalletPassword(password); - APIV1POSTWalletInitResponse handleTokenResp = kmd.initWalletHandleToken(tokenReq); - - String handleToken = handleTokenResp.getWalletHandleToken() - GenerateKeyRequest gkr = new GenerateKeyRequest(); - gkr.setWalletHandleToken(handleToken); - APIV1POSTKeyResponse generatedKey = kmd.generateKey(gkr); - System.out.printf("New account: %s\n", generatedKey.getAddress()); - // example: KMD_CREATE_ACCOUNT + String handleToken = getHandle(kmd, wallet, password); + // example: KMD_BACKUP_WALLET ExportMasterKeyRequest mker = new ExportMasterKeyRequest(); mker.setWalletHandleToken(handleToken); + mker.setWalletPassword(password); APIV1POSTMasterKeyExportResponse masterKeyResp = kmd.exportMasterKey(mker); byte[] backupKey = masterKeyResp.getMasterDerivationKey(); + // example: KMD_BACKUP_WALLET + + // example: KMD_RECOVER_WALLET + // create a new CreateWalletRequest and set parameters + CreateWalletRequest recoverRequest = new CreateWalletRequest(); + recoverRequest.setWalletName("Recovered:"+walletName); + recoverRequest.setWalletPassword(password); + recoverRequest.setWalletDriverName("sqlite"); + // Pass the specific derivation key we want to use + // to recover the wallet + recoverRequest.setMasterDerivationKey(backupKey); + APIV1POSTWalletResponse recoverResponse = kmd.createWallet(recoverRequest); + APIV1Wallet recoveredWallet = recoverResponse.getWallet(); + System.out.printf("Wallet name: %s\n", recoveredWallet.getName()); + // example: KMD_RECOVER_WALLET - // /example: KMD_RECOVER_WALLET - // /... - // /example: KMD_RECOVER_WALLET - - // /example: KMD_EXPORT_ACCOUNT - // /example: KMD_EXPORT_ACCOUNT + // example: KMD_CREATE_ACCOUNT + // create a request to generate a new key, using the handle token + GenerateKeyRequest gkr = new GenerateKeyRequest(); + gkr.setWalletHandleToken(handleToken); + APIV1POSTKeyResponse generatedKey = kmd.generateKey(gkr); + String addr = generatedKey.getAddress(); + System.out.printf("New account: %s\n", addr); + // example: KMD_CREATE_ACCOUNT + // example: KMD_EXPORT_ACCOUNT + ExportKeyRequest ekr = new ExportKeyRequest(); + ekr.setAddress(addr); + ekr.setWalletHandleToken(handleToken); + ekr.setWalletPassword(password); + APIV1POSTKeyExportResponse exportedKeyResp = kmd.exportKey(ekr); + byte[] exportedKey = exportedKeyResp.getPrivateKey(); + String mn = Mnemonic.fromKey(Arrays.copyOfRange(exportedKey, 0, 32)); + System.out.printf("Exported mnemonic: %s\n", mn); + // example: KMD_EXPORT_ACCOUNT + + String recoveredWalletHandleToken = getHandle(kmd, recoveredWallet, password); + + // example: KMD_IMPORT_ACCOUNT + ImportKeyRequest ikr = new ImportKeyRequest(); + ikr.setPrivateKey(Arrays.copyOfRange(exportedKey, 0, 32)); + ikr.setWalletHandleToken(recoveredWalletHandleToken); + APIV1POSTKeyImportResponse importResp = kmd.importKey(ikr); + System.out.printf("Imported account: %s\n", importResp.getAddress()); // /example: KMD_IMPORT_ACCOUNT - // /example: KMD_IMPORT_ACCOUNT - - // Get accounts from sandbox. - // String walletHandle = getDefaultWalletHandle(); - // List
addresses = getWalletAccounts(walletHandle); - - // List accts = new ArrayList<>(); - // for(Address addr: addresses){ - // byte[] pk = lookupPrivateKey(addr, walletHandle); - // accts.add(new Account(pk)); - // } - // return accts; + } + public static String getHandle(KmdApi kmd, APIV1Wallet wallet, String password) throws ApiException { + // example: KMD_CREATE_HANDLE_TOKEN + // grab a handle that we can re-use + InitWalletHandleTokenRequest tokenReq = new InitWalletHandleTokenRequest(); + tokenReq.setWalletId(wallet.getId()); + tokenReq.setWalletPassword(password); + APIV1POSTWalletInitResponse handleTokenResp = kmd.initWalletHandleToken(tokenReq); + String handleToken = handleTokenResp.getWalletHandleToken(); + // example: KMD_CREATE_HANDLE_TOKEN + return handleToken; } - + } diff --git a/examples/src/main/java/com/algorand/examples/contract.json b/examples/src/main/java/com/algorand/examples/contract.json deleted file mode 100644 index e69de29bb..000000000 From 249f8f7e219cf86f7077ef66229c3316cbe34177 Mon Sep 17 00:00:00 2001 From: Ben Guidarelli Date: Wed, 1 Mar 2023 08:15:02 -0500 Subject: [PATCH 12/22] adding randoms --- .../java/com/algorand/examples/Overview.java | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/examples/src/main/java/com/algorand/examples/Overview.java b/examples/src/main/java/com/algorand/examples/Overview.java index de92ad398..ee8ea3ce1 100644 --- a/examples/src/main/java/com/algorand/examples/Overview.java +++ b/examples/src/main/java/com/algorand/examples/Overview.java @@ -3,6 +3,7 @@ import java.security.NoSuchAlgorithmException; import java.util.List; import com.algorand.algosdk.v2.client.Utils; +import com.algorand.algosdk.v2.client.algod.AccountInformation; import com.algorand.algosdk.v2.client.common.AlgodClient; import com.algorand.algosdk.v2.client.common.Response; import com.algorand.algosdk.v2.client.model.PendingTransactionResponse; @@ -46,6 +47,16 @@ public static void main(String[] args) throws Exception { PendingTransactionResponse result = Utils.waitForConfirmation(algodClient, txid, 4); System.out.printf("Transaction %s confirmed in round %d\n", txid, result.confirmedRound); // example: TRANSACTION_PAYMENT_SUBMIT + + + // example: SP_MIN_FEE + Response sp = algodClient.TransactionParams().execute(); + System.out.printf("Min fee from suggested params: %d\n", sp.body().minFee); + // example: SP_MIN_FEE + + // example: CONST_MIN_FEE + System.out.printf("Min fee from const: %d\n", Account.MIN_TX_FEE_UALGOS); + // example: CONST_MIN_FEE } public static void createAccount() throws NoSuchAlgorithmException{ @@ -56,6 +67,15 @@ public static void createAccount() throws NoSuchAlgorithmException{ // example: ACCOUNT_GENERATE } + public static void getAccountInfo(AlgodClient algodClient, Account acct) throws Exception { + // example: ALGOD_FETCH_ACCOUNT_INFO + Response acctInfoResp = algodClient.AccountInformation(acct.getAddress()).execute(); + com.algorand.algosdk.v2.client.model.Account acctInfo = acctInfoResp.body(); + // print one of the fields in the account info response + System.out.printf("Current balance: %d", acctInfo.amount); + // example: ALGOD_FETCH_ACCOUNT_INFO + } + public static AlgodClient createClient() { // example: ALGOD_CREATE_CLIENT String algodHost = "http://localhost"; From eede000561e13f902266a833a8d1259a4a33432c Mon Sep 17 00:00:00 2001 From: Ben Guidarelli Date: Wed, 1 Mar 2023 08:41:45 -0500 Subject: [PATCH 13/22] adding participation examples --- .../com/algorand/examples/Participation.java | 47 +++++++++++++++++++ 1 file changed, 47 insertions(+) create mode 100644 examples/src/main/java/com/algorand/examples/Participation.java diff --git a/examples/src/main/java/com/algorand/examples/Participation.java b/examples/src/main/java/com/algorand/examples/Participation.java new file mode 100644 index 000000000..1fa46c7bf --- /dev/null +++ b/examples/src/main/java/com/algorand/examples/Participation.java @@ -0,0 +1,47 @@ +package com.algorand.examples; + +import com.algorand.algosdk.transaction.Transaction; +import com.algorand.algosdk.v2.client.common.AlgodClient; +import com.algorand.algosdk.v2.client.common.Response; +import com.algorand.algosdk.v2.client.model.TransactionParametersResponse; + +public class Participation { + + public static void main(String[] args) throws Exception { + AlgodClient algodClient = ExampleUtils.getAlgodClient(); + + // example: TRANSACTION_KEYREG_ONLINE_CREATE + // get suggested parameters + Response rsp = algodClient.TransactionParams().execute(); + TransactionParametersResponse sp = rsp.body(); + + String address = "EW64GC6F24M7NDSC5R3ES4YUVE3ZXXNMARJHDCCCLIHZU6TBEOC7XRSBG4"; + + String votekey = "eXq34wzh2UIxCZaI1leALKyAvSz/+XOe0wqdHagM+bw="; + String skey = "X84ReKTmp+yfgmMCbbokVqeFFFrKQeFZKEXG89SXwm4="; + + Long numRounds = 100000l; // sets up keys for 100000 rounds + Long keyDilution = (long) Math.sqrt(numRounds); // dilution default is sqrt num rounds + + Transaction keyRegTxn = Transaction.KeyRegistrationTransactionBuilder().suggestedParams(sp) + .sender(address) + .selectionPublicKeyBase64(skey) + .participationPublicKeyBase64(votekey) + .voteFirst(sp.lastRound) + .voteLast(sp.lastRound + numRounds) + .voteKeyDilution(keyDilution) + .build(); + // ... sign and send to network + // example: TRANSACTION_KEYREG_ONLINE_CREATE + + // example: TRANSACTION_KEYREG_OFFLINE_CREATE + // create keyreg transaction to take this account offline + Transaction keyRegOfflineTxn = Transaction.KeyRegistrationTransactionBuilder().suggestedParams(sp) + .sender(address) + .build(); + // example: TRANSACTION_KEYREG_OFFLINE_CREATE + System.out.println(keyRegOfflineTxn); + } + +} + From baf217c45d9b37a0df8d722e58fd50564dd38972 Mon Sep 17 00:00:00 2001 From: Ben Guidarelli Date: Wed, 1 Mar 2023 08:50:24 -0500 Subject: [PATCH 14/22] add fee override example --- .../com/algorand/examples/CodecExamples.java | 1 + .../java/com/algorand/examples/Overview.java | 16 ++++++++++++++-- 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/examples/src/main/java/com/algorand/examples/CodecExamples.java b/examples/src/main/java/com/algorand/examples/CodecExamples.java index b36ec6a5c..19452f80e 100644 --- a/examples/src/main/java/com/algorand/examples/CodecExamples.java +++ b/examples/src/main/java/com/algorand/examples/CodecExamples.java @@ -62,5 +62,6 @@ public static void main(String[] args) throws Exception { SignedTransaction decodedSignedTransaction = Encoder.decodeFromMsgPack(encodedSignedTxn, SignedTransaction.class); assert decodedSignedTransaction.equals(signedTxn); // example: CODEC_TRANSACTION_SIGNED + } } diff --git a/examples/src/main/java/com/algorand/examples/Overview.java b/examples/src/main/java/com/algorand/examples/Overview.java index ee8ea3ce1..fcf8af81c 100644 --- a/examples/src/main/java/com/algorand/examples/Overview.java +++ b/examples/src/main/java/com/algorand/examples/Overview.java @@ -50,10 +50,22 @@ public static void main(String[] args) throws Exception { // example: SP_MIN_FEE - Response sp = algodClient.TransactionParams().execute(); - System.out.printf("Min fee from suggested params: %d\n", sp.body().minFee); + Response tpr = algodClient.TransactionParams().execute(); + TransactionParametersResponse sp = tpr.body(); + System.out.printf("Min fee from suggested params: %d\n", sp.minFee); // example: SP_MIN_FEE + // example: TRANSACTION_FEE_OVERRIDE + Transaction feeOverrideTxn = Transaction.PaymentTransactionBuilder() + .sender(acct.getAddress()) + .receiver(acct2.getAddress()) + .suggestedParams(suggestedParams.body()) + // override the fee given by suggested params + // to set a flat fee of 2x minfee to cover another transaction + // in the same group + .flatFee(2*suggestedParams.body().minFee).build(); + // example: TRANSACTION_FEE_OVERRIDE + // example: CONST_MIN_FEE System.out.printf("Min fee from const: %d\n", Account.MIN_TX_FEE_UALGOS); // example: CONST_MIN_FEE From 4d0a66c63fc3154e1cb1bcc4b415e219ffa7de8f Mon Sep 17 00:00:00 2001 From: Ben Guidarelli Date: Wed, 1 Mar 2023 08:51:13 -0500 Subject: [PATCH 15/22] fmt --- .../com/algorand/examples/ASAExamples.java | 4 +- .../main/java/com/algorand/examples/ATC.java | 176 +++++++++--------- .../algorand/examples/AccountExamples.java | 166 +++++++++-------- .../algorand/examples/AtomicTransfers.java | 6 +- .../com/algorand/examples/CodecExamples.java | 3 +- .../com/algorand/examples/ExampleUtils.java | 6 +- .../java/com/algorand/examples/Overview.java | 30 ++- .../com/algorand/examples/Participation.java | 7 +- 8 files changed, 201 insertions(+), 197 deletions(-) diff --git a/examples/src/main/java/com/algorand/examples/ASAExamples.java b/examples/src/main/java/com/algorand/examples/ASAExamples.java index f431723e1..e68389743 100644 --- a/examples/src/main/java/com/algorand/examples/ASAExamples.java +++ b/examples/src/main/java/com/algorand/examples/ASAExamples.java @@ -35,7 +35,7 @@ public static void main(String[] args) throws Exception { deleteAsset(algodClient, acct1, asaId); } - public static void printAssetInfo(AlgodClient algodClient, Long asaId) throws Exception { + public static void printAssetInfo(AlgodClient algodClient, Long asaId) throws Exception { // example: ASSET_INFO // Retrieve the asset info of the newly created asset Response assetResp = algodClient.GetAssetByID(asaId).execute(); @@ -84,7 +84,7 @@ public static void configureAsset(AlgodClient algodClient, Account acct, Long as // example: ASSET_CONFIG Response rsp = algodClient.TransactionParams().execute(); TransactionParametersResponse sp = rsp.body(); - // Wipe the `reserve` address through an AssetConfigTransaction + // Wipe the `reserve` address through an AssetConfigTransaction Transaction reconfigureTxn = Transaction.AssetConfigureTransactionBuilder().suggestedParams(sp) .sender(acct.getAddress()) .assetIndex(asaId) diff --git a/examples/src/main/java/com/algorand/examples/ATC.java b/examples/src/main/java/com/algorand/examples/ATC.java index c729093e2..324366b4d 100644 --- a/examples/src/main/java/com/algorand/examples/ATC.java +++ b/examples/src/main/java/com/algorand/examples/ATC.java @@ -29,91 +29,95 @@ public class ATC { - public static void main(String[] args) throws Exception { - AlgodClient algodClient = ExampleUtils.getAlgodClient(); - List accts = ExampleUtils.getSandboxAccounts(); - Account acct = accts.get(0); - - Long appId = deployApp(algodClient, acct); - - // Get suggested params from client - Response rsp = algodClient.TransactionParams().execute(); - TransactionParametersResponse sp = rsp.body(); - - // example: ATC_CREATE - AtomicTransactionComposer atc = new AtomicTransactionComposer(); - // example: ATC_CREATE - - // example: ATC_ADD_TRANSACTION - // Create a transaction - Transaction ptxn = PaymentTransactionBuilder.Builder().amount(10000).suggestedParams(sp) - .sender(acct.getAddress()).receiver(acct.getAddress()).build(); - - // Construct TransactionWithSigner - TransactionWithSigner tws = new TransactionWithSigner(ptxn, - acct.getTransactionSigner()); - - // Pass TransactionWithSigner to atc - atc.addTransaction(tws); - // example: ATC_ADD_TRANSACTION - - // example: ATC_CONTRACT_INIT - // Read the json from disk - String jsonContract = Files.readString(Paths.get("calculator/contract.json")); - // Create Contract from Json - Contract contract = Encoder.decodeFromJson(jsonContract, Contract.class); - // example: ATC_CONTRACT_INIT - - // example: ATC_ADD_METHOD_CALL - // create methodCallParams by builder (or create by constructor) for add method - List methodArgs = new ArrayList(); - methodArgs.add(1); - methodArgs.add(1); - - MethodCallTransactionBuilder mctb = MethodCallTransactionBuilder.Builder(); - - MethodCallParams mcp = mctb.applicationId(appId).signer(acct.getTransactionSigner()).sender(acct.getAddress()) - .method(contract.getMethodByName("add")).methodArguments(methodArgs) - .onComplete(Transaction.OnCompletion.NoOpOC).suggestedParams(sp).build(); - - atc.addMethodCall(mcp); - // example: ATC_ADD_METHOD_CALL - // example: ATC_RESULTS - ExecuteResult res = atc.execute(algodClient, 2); - System.out.printf("App call (%s) confirmed in round %d\n", res.txIDs, res.confirmedRound); - res.methodResults.forEach(methodResult -> { - System.out.printf("Result from calling '%s' method: %s\n", methodResult.method.name, methodResult.value); - }); - // example: ATC_RESULTS - } - - public static Long deployApp(AlgodClient algodClient, Account acct1) throws Exception { - String approvalSource = Files.readString(Paths.get("calculator/approval.teal")); - String clearSource = Files.readString(Paths.get("calculator/clear.teal")); - - CompileResponse approvalResponse = algodClient.TealCompile().source(approvalSource.getBytes()).execute().body(); - CompileResponse clearResponse = algodClient.TealCompile().source(clearSource.getBytes()).execute().body(); - - TEALProgram approvalProg = new TEALProgram(approvalResponse.result); - TEALProgram clearProg = new TEALProgram(clearResponse.result); - - Response rsp = algodClient.TransactionParams().execute(); - TransactionParametersResponse sp = rsp.body(); - - StateSchema schema = new StateSchema(0, 0); - - Transaction appCreate = ApplicationCreateTransactionBuilder.Builder().sender(acct1.getAddress()) - .approvalProgram(approvalProg).clearStateProgram(clearProg).localStateSchema(schema) - .globalStateSchema(schema) - .suggestedParams(sp).build(); - SignedTransaction signedAppCreate = acct1.signTransaction(appCreate); - - Response createResult = algodClient.RawTransaction() - .rawtxn(Encoder.encodeToMsgPack(signedAppCreate)).execute(); - - PendingTransactionResponse result = Utils.waitForConfirmation(algodClient, createResult.body().txId, 4); - - return result.applicationIndex; - } + public static void main(String[] args) throws Exception { + AlgodClient algodClient = ExampleUtils.getAlgodClient(); + List accts = ExampleUtils.getSandboxAccounts(); + Account acct = accts.get(0); + + Long appId = deployApp(algodClient, acct); + + // Get suggested params from client + Response rsp = algodClient.TransactionParams().execute(); + TransactionParametersResponse sp = rsp.body(); + + // example: ATC_CREATE + AtomicTransactionComposer atc = new AtomicTransactionComposer(); + // example: ATC_CREATE + + // example: ATC_ADD_TRANSACTION + // Create a transaction + Transaction ptxn = PaymentTransactionBuilder.Builder().amount(10000).suggestedParams(sp) + .sender(acct.getAddress()).receiver(acct.getAddress()).build(); + + // Construct TransactionWithSigner + TransactionWithSigner tws = new TransactionWithSigner(ptxn, + acct.getTransactionSigner()); + + // Pass TransactionWithSigner to atc + atc.addTransaction(tws); + // example: ATC_ADD_TRANSACTION + + // example: ATC_CONTRACT_INIT + // Read the json from disk + String jsonContract = Files.readString(Paths.get("calculator/contract.json")); + // Create Contract from Json + Contract contract = Encoder.decodeFromJson(jsonContract, Contract.class); + // example: ATC_CONTRACT_INIT + + // example: ATC_ADD_METHOD_CALL + // create methodCallParams by builder (or create by constructor) for add method + List methodArgs = new ArrayList(); + methodArgs.add(1); + methodArgs.add(1); + + MethodCallTransactionBuilder mctb = MethodCallTransactionBuilder.Builder(); + + MethodCallParams mcp = mctb.applicationId(appId).signer(acct.getTransactionSigner()) + .sender(acct.getAddress()) + .method(contract.getMethodByName("add")).methodArguments(methodArgs) + .onComplete(Transaction.OnCompletion.NoOpOC).suggestedParams(sp).build(); + + atc.addMethodCall(mcp); + // example: ATC_ADD_METHOD_CALL + // example: ATC_RESULTS + ExecuteResult res = atc.execute(algodClient, 2); + System.out.printf("App call (%s) confirmed in round %d\n", res.txIDs, res.confirmedRound); + res.methodResults.forEach(methodResult -> { + System.out.printf("Result from calling '%s' method: %s\n", methodResult.method.name, + methodResult.value); + }); + // example: ATC_RESULTS + } + + public static Long deployApp(AlgodClient algodClient, Account acct1) throws Exception { + String approvalSource = Files.readString(Paths.get("calculator/approval.teal")); + String clearSource = Files.readString(Paths.get("calculator/clear.teal")); + + CompileResponse approvalResponse = algodClient.TealCompile().source(approvalSource.getBytes()).execute() + .body(); + CompileResponse clearResponse = algodClient.TealCompile().source(clearSource.getBytes()).execute() + .body(); + + TEALProgram approvalProg = new TEALProgram(approvalResponse.result); + TEALProgram clearProg = new TEALProgram(clearResponse.result); + + Response rsp = algodClient.TransactionParams().execute(); + TransactionParametersResponse sp = rsp.body(); + + StateSchema schema = new StateSchema(0, 0); + + Transaction appCreate = ApplicationCreateTransactionBuilder.Builder().sender(acct1.getAddress()) + .approvalProgram(approvalProg).clearStateProgram(clearProg).localStateSchema(schema) + .globalStateSchema(schema) + .suggestedParams(sp).build(); + SignedTransaction signedAppCreate = acct1.signTransaction(appCreate); + + Response createResult = algodClient.RawTransaction() + .rawtxn(Encoder.encodeToMsgPack(signedAppCreate)).execute(); + + PendingTransactionResponse result = Utils.waitForConfirmation(algodClient, createResult.body().txId, 4); + + return result.applicationIndex; + } } diff --git a/examples/src/main/java/com/algorand/examples/AccountExamples.java b/examples/src/main/java/com/algorand/examples/AccountExamples.java index 279b34cb1..60f5b69f2 100644 --- a/examples/src/main/java/com/algorand/examples/AccountExamples.java +++ b/examples/src/main/java/com/algorand/examples/AccountExamples.java @@ -17,87 +17,89 @@ public class AccountExamples { - public static void main(String[] args) throws Exception { - AlgodClient algodClient = ExampleUtils.getAlgodClient(); - List accts = ExampleUtils.getSandboxAccounts(); - - // Grab some accounts from the sandbox kmd - Account acct1 = accts.get(0); - Account acct2 = accts.get(1); - Account acct3 = accts.get(2); - - MultisigAddress msig = createMsig(acct1, acct2, acct3); - - // Pay the multisig address so it can issue transactions for the demo - Response spResponse = algodClient.TransactionParams().execute(); - TransactionParametersResponse sp = spResponse.body(); - Transaction ptxn = Transaction.PaymentTransactionBuilder() - .sender(acct1.getAddress()).amount(1000000).receiver(msig.toAddress()).suggestedParams(sp).build(); - SignedTransaction stxn = acct1.signTransaction(ptxn); - ExampleUtils.sendPrint(algodClient, stxn, "seed msig"); - - // example: MULTISIG_SIGN - // Construct transaction with sender as address of msig - Transaction msigPayTxn = Transaction.PaymentTransactionBuilder() - .sender(msig.toAddress()) - .amount(1000) - .receiver(acct1.getAddress()) - .suggestedParams(sp) - .build(); - - // For each subsig, sign or append to the existing partially signed transaction - SignedTransaction signedMsigPayTxn = acct1.signMultisigTransaction(msig, msigPayTxn); - signedMsigPayTxn = acct2.appendMultisigTransaction(msig, signedMsigPayTxn); - Response msigSubResponse = algodClient.RawTransaction() - .rawtxn(Encoder.encodeToMsgPack(signedMsigPayTxn)).execute(); - // example: MULTISIG_SIGN - ExampleUtils.printTxnResults(algodClient, msigSubResponse.body(), "msig pay"); - - rekeyAcct(algodClient, acct1, acct2); - - } - - public static MultisigAddress createMsig(Account addr1, Account addr2, Account addr3) - throws NoSuchAlgorithmException { - // example: MULTISIG_CREATE - int version = 1; // no other versions at the time of writing - int threshold = 2; // we're making a 2/3 msig - - // Populate a list of Ed25519 pubkeys - List accts = new ArrayList<>(); - accts.add(addr1.getEd25519PublicKey()); - accts.add(addr2.getEd25519PublicKey()); - accts.add(addr3.getEd25519PublicKey()); - // create the MultisigAddress object - MultisigAddress msig = new MultisigAddress(version, threshold, accts); - System.out.printf("msig address: %s\n", msig.toAddress().toString()); - // example: MULTISIG_CREATE - return msig; - } - - public static void rekeyAcct(AlgodClient algodClient, Account acct1, Account acct2) throws Exception { - TransactionParametersResponse sp = algodClient.TransactionParams().execute().body(); - - // example: ACCOUNT_REKEY - - // Any kind of transaction can contain a rekey, here we use a Payment transaction - Transaction rekeyTxn = Transaction.PaymentTransactionBuilder().sender(acct1.getAddress()) - .receiver(acct1.getAddress()).suggestedParams(sp).rekey(acct2.getAddress()).build(); - SignedTransaction signedRekeyTxn = acct1.signTransaction(rekeyTxn); - Response resp = algodClient.RawTransaction() - .rawtxn(Encoder.encodeToMsgPack(signedRekeyTxn)).execute(); - ExampleUtils.printTxnResults(algodClient, resp.body(), "rekey"); - - // Create a transaction to rekey it back - Transaction rekeyBack = Transaction.PaymentTransactionBuilder().sender(acct1.getAddress()) - .receiver(acct1.getAddress()).suggestedParams(sp).rekey(acct1.getAddress()).build(); - - // note we sign with acct2's key - SignedTransaction signedRekeyBack = acct2.signTransaction(rekeyBack); - Response rekeyBackResponse = algodClient.RawTransaction() - .rawtxn(Encoder.encodeToMsgPack(signedRekeyBack)).execute(); - ExampleUtils.printTxnResults(algodClient, rekeyBackResponse.body(), "rekey back"); - // example: ACCOUNT_REKEY - } + public static void main(String[] args) throws Exception { + AlgodClient algodClient = ExampleUtils.getAlgodClient(); + List accts = ExampleUtils.getSandboxAccounts(); + + // Grab some accounts from the sandbox kmd + Account acct1 = accts.get(0); + Account acct2 = accts.get(1); + Account acct3 = accts.get(2); + + MultisigAddress msig = createMsig(acct1, acct2, acct3); + + // Pay the multisig address so it can issue transactions for the demo + Response spResponse = algodClient.TransactionParams().execute(); + TransactionParametersResponse sp = spResponse.body(); + Transaction ptxn = Transaction.PaymentTransactionBuilder() + .sender(acct1.getAddress()).amount(1000000).receiver(msig.toAddress()) + .suggestedParams(sp).build(); + SignedTransaction stxn = acct1.signTransaction(ptxn); + ExampleUtils.sendPrint(algodClient, stxn, "seed msig"); + + // example: MULTISIG_SIGN + // Construct transaction with sender as address of msig + Transaction msigPayTxn = Transaction.PaymentTransactionBuilder() + .sender(msig.toAddress()) + .amount(1000) + .receiver(acct1.getAddress()) + .suggestedParams(sp) + .build(); + + // For each subsig, sign or append to the existing partially signed transaction + SignedTransaction signedMsigPayTxn = acct1.signMultisigTransaction(msig, msigPayTxn); + signedMsigPayTxn = acct2.appendMultisigTransaction(msig, signedMsigPayTxn); + Response msigSubResponse = algodClient.RawTransaction() + .rawtxn(Encoder.encodeToMsgPack(signedMsigPayTxn)).execute(); + // example: MULTISIG_SIGN + ExampleUtils.printTxnResults(algodClient, msigSubResponse.body(), "msig pay"); + + rekeyAcct(algodClient, acct1, acct2); + + } + + public static MultisigAddress createMsig(Account addr1, Account addr2, Account addr3) + throws NoSuchAlgorithmException { + // example: MULTISIG_CREATE + int version = 1; // no other versions at the time of writing + int threshold = 2; // we're making a 2/3 msig + + // Populate a list of Ed25519 pubkeys + List accts = new ArrayList<>(); + accts.add(addr1.getEd25519PublicKey()); + accts.add(addr2.getEd25519PublicKey()); + accts.add(addr3.getEd25519PublicKey()); + // create the MultisigAddress object + MultisigAddress msig = new MultisigAddress(version, threshold, accts); + System.out.printf("msig address: %s\n", msig.toAddress().toString()); + // example: MULTISIG_CREATE + return msig; + } + + public static void rekeyAcct(AlgodClient algodClient, Account acct1, Account acct2) throws Exception { + TransactionParametersResponse sp = algodClient.TransactionParams().execute().body(); + + // example: ACCOUNT_REKEY + + // Any kind of transaction can contain a rekey, here we use a Payment + // transaction + Transaction rekeyTxn = Transaction.PaymentTransactionBuilder().sender(acct1.getAddress()) + .receiver(acct1.getAddress()).suggestedParams(sp).rekey(acct2.getAddress()).build(); + SignedTransaction signedRekeyTxn = acct1.signTransaction(rekeyTxn); + Response resp = algodClient.RawTransaction() + .rawtxn(Encoder.encodeToMsgPack(signedRekeyTxn)).execute(); + ExampleUtils.printTxnResults(algodClient, resp.body(), "rekey"); + + // Create a transaction to rekey it back + Transaction rekeyBack = Transaction.PaymentTransactionBuilder().sender(acct1.getAddress()) + .receiver(acct1.getAddress()).suggestedParams(sp).rekey(acct1.getAddress()).build(); + + // note we sign with acct2's key + SignedTransaction signedRekeyBack = acct2.signTransaction(rekeyBack); + Response rekeyBackResponse = algodClient.RawTransaction() + .rawtxn(Encoder.encodeToMsgPack(signedRekeyBack)).execute(); + ExampleUtils.printTxnResults(algodClient, rekeyBackResponse.body(), "rekey back"); + // example: ACCOUNT_REKEY + } } \ No newline at end of file diff --git a/examples/src/main/java/com/algorand/examples/AtomicTransfers.java b/examples/src/main/java/com/algorand/examples/AtomicTransfers.java index 8ec66d303..95fc9c86b 100644 --- a/examples/src/main/java/com/algorand/examples/AtomicTransfers.java +++ b/examples/src/main/java/com/algorand/examples/AtomicTransfers.java @@ -60,11 +60,13 @@ public static void main(String[] args) throws Exception { // example: ATOMIC_GROUP_SEND // Only the first transaction id is returned - Response txResponse = algodClient.RawTransaction().rawtxn(Encoder.encodeToMsgPack(stxns)).execute(); + Response txResponse = algodClient.RawTransaction() + .rawtxn(Encoder.encodeToMsgPack(stxns)).execute(); String txid = txResponse.body().txId; // Wait for the transaction id to be confirmed - // If the results from other transactions are needed, grab the txid from those directly and + // If the results from other transactions are needed, grab the txid from those + // directly and // call waitForConfirmation on each PendingTransactionResponse txResult = Utils.waitForConfirmation(algodClient, txid, 4); System.out.printf("Transaction %s confirmed in round %d\n", txid, txResult.confirmedRound); diff --git a/examples/src/main/java/com/algorand/examples/CodecExamples.java b/examples/src/main/java/com/algorand/examples/CodecExamples.java index 19452f80e..0a9271fe5 100644 --- a/examples/src/main/java/com/algorand/examples/CodecExamples.java +++ b/examples/src/main/java/com/algorand/examples/CodecExamples.java @@ -59,7 +59,8 @@ public static void main(String[] args) throws Exception { SignedTransaction signedTxn = acct.signTransaction(ptxn); byte[] encodedSignedTxn = Encoder.encodeToMsgPack(signedTxn); - SignedTransaction decodedSignedTransaction = Encoder.decodeFromMsgPack(encodedSignedTxn, SignedTransaction.class); + SignedTransaction decodedSignedTransaction = Encoder.decodeFromMsgPack(encodedSignedTxn, + SignedTransaction.class); assert decodedSignedTransaction.equals(signedTxn); // example: CODEC_TRANSACTION_SIGNED diff --git a/examples/src/main/java/com/algorand/examples/ExampleUtils.java b/examples/src/main/java/com/algorand/examples/ExampleUtils.java index ffa4d82ff..b8783ec72 100644 --- a/examples/src/main/java/com/algorand/examples/ExampleUtils.java +++ b/examples/src/main/java/com/algorand/examples/ExampleUtils.java @@ -36,7 +36,6 @@ public class ExampleUtils { private static int indexer_port = 8980; private static String indexer_token = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"; - public static AlgodClient getAlgodClient() { return new AlgodClient(algod_host, algod_port, algod_token); } @@ -54,10 +53,10 @@ public static List getSandboxAccounts() throws Exception { // Get accounts from sandbox. String walletHandle = getDefaultWalletHandle(); - List
addresses = getWalletAccounts(walletHandle); + List
addresses = getWalletAccounts(walletHandle); List accts = new ArrayList<>(); - for(Address addr: addresses){ + for (Address addr : addresses) { byte[] pk = lookupPrivateKey(addr, walletHandle); accts.add(new Account(pk)); } @@ -100,7 +99,6 @@ public static void sendPrint(AlgodClient algodClient, SignedTransaction stxn, St printTxnResults(algodClient, submitResult.body(), name); } - public static void printTxnResults(AlgodClient client, PostTransactionsResponse ptr, String name) throws Exception { PendingTransactionResponse result = Utils.waitForConfirmation(client, ptr.txId, 4); System.out.printf("%s\ttransaction (%s) was confirmed in round %d\n", name, ptr.txId, result.confirmedRound); diff --git a/examples/src/main/java/com/algorand/examples/Overview.java b/examples/src/main/java/com/algorand/examples/Overview.java index fcf8af81c..52290ed45 100644 --- a/examples/src/main/java/com/algorand/examples/Overview.java +++ b/examples/src/main/java/com/algorand/examples/Overview.java @@ -26,13 +26,12 @@ public static void main(String[] args) throws Exception { Response suggestedParams = algodClient.TransactionParams().execute(); Integer amount = 1000000; // 1 Algo Transaction ptxn = Transaction.PaymentTransactionBuilder() - .sender(acct.getAddress()) - .amount(amount) - .receiver(acct2.getAddress()) - .suggestedParams(suggestedParams.body()).build(); + .sender(acct.getAddress()) + .amount(amount) + .receiver(acct2.getAddress()) + .suggestedParams(suggestedParams.body()).build(); // example: TRANSACTION_PAYMENT_CREATE - // example: TRANSACTION_PAYMENT_SIGN SignedTransaction sptxn = acct.signTransaction(ptxn); // example: TRANSACTION_PAYMENT_SIGN @@ -48,7 +47,6 @@ public static void main(String[] args) throws Exception { System.out.printf("Transaction %s confirmed in round %d\n", txid, result.confirmedRound); // example: TRANSACTION_PAYMENT_SUBMIT - // example: SP_MIN_FEE Response tpr = algodClient.TransactionParams().execute(); TransactionParametersResponse sp = tpr.body(); @@ -57,13 +55,13 @@ public static void main(String[] args) throws Exception { // example: TRANSACTION_FEE_OVERRIDE Transaction feeOverrideTxn = Transaction.PaymentTransactionBuilder() - .sender(acct.getAddress()) - .receiver(acct2.getAddress()) - .suggestedParams(suggestedParams.body()) - // override the fee given by suggested params - // to set a flat fee of 2x minfee to cover another transaction - // in the same group - .flatFee(2*suggestedParams.body().minFee).build(); + .sender(acct.getAddress()) + .receiver(acct2.getAddress()) + .suggestedParams(suggestedParams.body()) + // override the fee given by suggested params + // to set a flat fee of 2x minfee to cover another transaction + // in the same group + .flatFee(2 * suggestedParams.body().minFee).build(); // example: TRANSACTION_FEE_OVERRIDE // example: CONST_MIN_FEE @@ -71,7 +69,7 @@ public static void main(String[] args) throws Exception { // example: CONST_MIN_FEE } - public static void createAccount() throws NoSuchAlgorithmException{ + public static void createAccount() throws NoSuchAlgorithmException { // example: ACCOUNT_GENERATE Account acct = new Account(); System.out.println("Address: " + acct.getAddress()); @@ -81,7 +79,8 @@ public static void createAccount() throws NoSuchAlgorithmException{ public static void getAccountInfo(AlgodClient algodClient, Account acct) throws Exception { // example: ALGOD_FETCH_ACCOUNT_INFO - Response acctInfoResp = algodClient.AccountInformation(acct.getAddress()).execute(); + Response acctInfoResp = algodClient + .AccountInformation(acct.getAddress()).execute(); com.algorand.algosdk.v2.client.model.Account acctInfo = acctInfoResp.body(); // print one of the fields in the account info response System.out.printf("Current balance: %d", acctInfo.amount); @@ -102,5 +101,4 @@ public static AlgodClient createClient() { return algodClient; } - } \ No newline at end of file diff --git a/examples/src/main/java/com/algorand/examples/Participation.java b/examples/src/main/java/com/algorand/examples/Participation.java index 1fa46c7bf..27f0d4ebe 100644 --- a/examples/src/main/java/com/algorand/examples/Participation.java +++ b/examples/src/main/java/com/algorand/examples/Participation.java @@ -20,8 +20,8 @@ public static void main(String[] args) throws Exception { String votekey = "eXq34wzh2UIxCZaI1leALKyAvSz/+XOe0wqdHagM+bw="; String skey = "X84ReKTmp+yfgmMCbbokVqeFFFrKQeFZKEXG89SXwm4="; - Long numRounds = 100000l; // sets up keys for 100000 rounds - Long keyDilution = (long) Math.sqrt(numRounds); // dilution default is sqrt num rounds + Long numRounds = 100000l; // sets up keys for 100000 rounds + Long keyDilution = (long) Math.sqrt(numRounds); // dilution default is sqrt num rounds Transaction keyRegTxn = Transaction.KeyRegistrationTransactionBuilder().suggestedParams(sp) .sender(address) @@ -42,6 +42,5 @@ public static void main(String[] args) throws Exception { // example: TRANSACTION_KEYREG_OFFLINE_CREATE System.out.println(keyRegOfflineTxn); } - -} +} From 1d2b52578a36ef45236243e63f31205544a253bb Mon Sep 17 00:00:00 2001 From: Ben Guidarelli Date: Wed, 1 Mar 2023 10:50:50 -0500 Subject: [PATCH 16/22] add abi type examples --- .../java/com/algorand/examples/CodecExamples.java | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/examples/src/main/java/com/algorand/examples/CodecExamples.java b/examples/src/main/java/com/algorand/examples/CodecExamples.java index 0a9271fe5..0507bd63b 100644 --- a/examples/src/main/java/com/algorand/examples/CodecExamples.java +++ b/examples/src/main/java/com/algorand/examples/CodecExamples.java @@ -3,6 +3,9 @@ import java.math.BigInteger; import java.util.List; +import org.apache.commons.codec.binary.Hex; + +import com.algorand.algosdk.abi.ABIType; import com.algorand.algosdk.account.Account; import com.algorand.algosdk.crypto.Address; import com.algorand.algosdk.transaction.SignedTransaction; @@ -64,5 +67,16 @@ public static void main(String[] args) throws Exception { assert decodedSignedTransaction.equals(signedTxn); // example: CODEC_TRANSACTION_SIGNED + // example: CODEC_ABI_TYPES + ABIType tupleCodec = ABIType.valueOf("(uint64,bool,string)"); + Object[] data = new Object[]{123, false, "hi"}; + byte[] encoded = tupleCodec.encode(data); + System.out.printf("Encoded: '%s'\n", Hex.encodeHexString(encoded)); + + ABIType boolCodec = ABIType.valueOf("bool"); + byte[] singleEncoded = boolCodec.encode(true); + System.out.printf("Single Encoded: '%s'\n", Hex.encodeHexString(singleEncoded)); + // example: CODEC_ABI_TYPES + } } From d1843c373b12f52164e41ecb3bc3c26926689291 Mon Sep 17 00:00:00 2001 From: Ben Guidarelli Date: Wed, 1 Mar 2023 12:52:34 -0500 Subject: [PATCH 17/22] adding example of tws in atc --- .../main/java/com/algorand/examples/ATC.java | 40 +++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/examples/src/main/java/com/algorand/examples/ATC.java b/examples/src/main/java/com/algorand/examples/ATC.java index 324366b4d..150e42550 100644 --- a/examples/src/main/java/com/algorand/examples/ATC.java +++ b/examples/src/main/java/com/algorand/examples/ATC.java @@ -5,7 +5,10 @@ import java.util.ArrayList; import java.util.List; +import org.apache.commons.codec.binary.Hex; + import com.algorand.algosdk.abi.Contract; +import com.algorand.algosdk.abi.Method; import com.algorand.algosdk.account.Account; import com.algorand.algosdk.builder.transaction.ApplicationCreateTransactionBuilder; import com.algorand.algosdk.builder.transaction.MethodCallTransactionBuilder; @@ -89,6 +92,43 @@ public static void main(String[] args) throws Exception { // example: ATC_RESULTS } + public static void atcWithTws(AlgodClient algodClient, Account account) throws Exception { + Response rsp = algodClient.TransactionParams().execute(); + TransactionParametersResponse sp = rsp.body(); + + Transaction ptxn = PaymentTransactionBuilder.Builder().amount(10000).suggestedParams(sp) + .sender(account.getAddress()).receiver(account.getAddress()).build(); + + // Construct TransactionWithSigner + TransactionWithSigner tws = new TransactionWithSigner(ptxn, + account.getTransactionSigner()); + + MethodCallTransactionBuilder mctb = MethodCallTransactionBuilder.Builder(); + + Method m = new Method("doit(pay,bool)void"); + + List methodArgs = new ArrayList<>(); + Boolean isHeads = true; + methodArgs.add(tws); + methodArgs.add(isHeads); + MethodCallParams mcp = mctb.applicationId(123l).signer(account.getTransactionSigner()) + .sender(account.getAddress()) + .method(m).methodArguments(methodArgs) + .onComplete(Transaction.OnCompletion.NoOpOC).suggestedParams(sp).build(); + + AtomicTransactionComposer atc = new AtomicTransactionComposer(); + atc.addMethodCall(mcp); + + List stxns = atc.gatherSignatures(); + System.out.printf("Created %d transactions\n", stxns.size()); + // should be the app call + SignedTransaction stxn = stxns.get(1); + List args = stxn.tx.applicationArgs; + for (int i = 0; i < args.size(); i++) { + System.out.printf("Arg %d is %s\n", i, Hex.encodeHexString(args.get(i))); + } + } + public static Long deployApp(AlgodClient algodClient, Account acct1) throws Exception { String approvalSource = Files.readString(Paths.get("calculator/approval.teal")); String clearSource = Files.readString(Paths.get("calculator/clear.teal")); From 780477cce6e93d6291d541d81230a9de482f95dc Mon Sep 17 00:00:00 2001 From: Ben Guidarelli Date: Thu, 2 Mar 2023 06:53:06 -0500 Subject: [PATCH 18/22] start to add app examples --- .../algorand/examples/AccountExamples.java | 13 ++++++++++++ .../com/algorand/examples/AppExamples.java | 21 +++++++++++++++++++ 2 files changed, 34 insertions(+) create mode 100644 examples/src/main/java/com/algorand/examples/AppExamples.java diff --git a/examples/src/main/java/com/algorand/examples/AccountExamples.java b/examples/src/main/java/com/algorand/examples/AccountExamples.java index 60f5b69f2..84d21d1c2 100644 --- a/examples/src/main/java/com/algorand/examples/AccountExamples.java +++ b/examples/src/main/java/com/algorand/examples/AccountExamples.java @@ -1,5 +1,6 @@ package com.algorand.examples; +import java.security.GeneralSecurityException; import java.security.NoSuchAlgorithmException; import java.util.ArrayList; import java.util.List; @@ -7,6 +8,7 @@ import com.algorand.algosdk.account.Account; import com.algorand.algosdk.crypto.Ed25519PublicKey; import com.algorand.algosdk.crypto.MultisigAddress; +import com.algorand.algosdk.mnemonic.Mnemonic; import com.algorand.algosdk.transaction.SignedTransaction; import com.algorand.algosdk.transaction.Transaction; import com.algorand.algosdk.util.Encoder; @@ -57,6 +59,17 @@ public static void main(String[] args) throws Exception { rekeyAcct(algodClient, acct1, acct2); } + public static Account recoverFromMnemonic() throws GeneralSecurityException { + // example: ACCOUNT_RECOVER_MNEMONIC + // Space delimited 25 word mnemonic + String mn = "cost piano sample enough south bar diet garden nasty mystery mesh sadness convince bacon best patch surround protect drum actress entire vacuum begin abandon hair"; + // We can get the private key + byte[] key = Mnemonic.toKey(mn); + // Or just init the account directly from the mnemonic + Account acct = new Account(mn); + // example: ACCOUNT_RECOVER_MNEMONIC + return acct; + } public static MultisigAddress createMsig(Account addr1, Account addr2, Account addr3) throws NoSuchAlgorithmException { diff --git a/examples/src/main/java/com/algorand/examples/AppExamples.java b/examples/src/main/java/com/algorand/examples/AppExamples.java new file mode 100644 index 000000000..ee027e729 --- /dev/null +++ b/examples/src/main/java/com/algorand/examples/AppExamples.java @@ -0,0 +1,21 @@ +package com.algorand.examples; + +public class AppExamples { + +} + + +// ACCOUNT_RECOVER_MNEMONIC + +// Missing APP_SCHEMA +// Missing APP_SOURCE +// Missing APP_COMPILE +// Missing APP_CREATE +// Missing APP_OPTIN +// Missing APP_NOOP +// Missing APP_READ_STATE +// Missing APP_UPDATE +// Missing APP_CALL +// Missing APP_CLOSEOUT +// Missing APP_DELETE +// Missing APP_CLEAR \ No newline at end of file From cf8659da5ddbc17dd0c81109a41d227ed34d4a70 Mon Sep 17 00:00:00 2001 From: Ben Guidarelli Date: Fri, 3 Mar 2023 09:04:43 -0500 Subject: [PATCH 19/22] adding app examples --- examples/application/approval.teal | 100 ++++++++ examples/application/approval_refactored.teal | 107 ++++++++ examples/application/clear.teal | 3 + .../com/algorand/examples/AppExamples.java | 230 ++++++++++++++++-- 4 files changed, 422 insertions(+), 18 deletions(-) create mode 100644 examples/application/approval.teal create mode 100644 examples/application/approval_refactored.teal create mode 100644 examples/application/clear.teal diff --git a/examples/application/approval.teal b/examples/application/approval.teal new file mode 100644 index 000000000..07fca803f --- /dev/null +++ b/examples/application/approval.teal @@ -0,0 +1,100 @@ +#pragma version 4 +// Handle each possible OnCompletion type. We don't have to worry about +// handling ClearState, because the ClearStateProgram will execute in that +// case, not the ApprovalProgram. +txn ApplicationID +int 0 +== +bnz handle_approve + +txn OnCompletion +int NoOp +== +bnz handle_noop + +txn OnCompletion +int OptIn +== +bnz handle_approve + +txn OnCompletion +int CloseOut +== +bnz handle_closeout + +txn OnCompletion +int UpdateApplication +== +bnz handle_updateapp + +txn OnCompletion +int DeleteApplication +== +bnz handle_deleteapp + +// Unexpected OnCompletion value. Should be unreachable. +err + +handle_noop: +// Handle NoOp + +// read global state +byte "counter" +dup +app_global_get + +// increment the value +int 1 ++ + +// store to scratch space +dup +store 0 + +// update global state +app_global_put + +// read local state for sender +int 0 +byte "counter" +app_local_get + +// increment the value +int 1 ++ +store 1 + +// update local state for sender +int 0 +byte "counter" +load 1 +app_local_put + +// load return value as approval +load 0 +return + + +handle_closeout: +// Handle CloseOut +//approval +int 1 +return + +handle_deleteapp: +// Check for creator +global CreatorAddress +txn Sender +== +return + +handle_updateapp: +// Check for creator +global CreatorAddress +txn Sender +== +return + +handle_approve: +int 1 +return \ No newline at end of file diff --git a/examples/application/approval_refactored.teal b/examples/application/approval_refactored.teal new file mode 100644 index 000000000..1af5a7ebe --- /dev/null +++ b/examples/application/approval_refactored.teal @@ -0,0 +1,107 @@ +#pragma version 4 +// Handle each possible OnCompletion type. We don't have to worry about +// handling ClearState, because the ClearStateProgram will execute in that +// case, not the ApprovalProgram. + +txn ApplicationID +int 0 +== +bnz handle_approve + +txn OnCompletion +int NoOp +== +bnz handle_noop + +txn OnCompletion +int OptIn +== +bnz handle_approve + +txn OnCompletion +int CloseOut +== +bnz handle_closeout + +txn OnCompletion +int UpdateApplication +== +bnz handle_updateapp + +txn OnCompletion +int DeleteApplication +== +bnz handle_deleteapp + +// Unexpected OnCompletion value. Should be unreachable. +err + +handle_noop: +// Handle NoOp + +// read global state +byte "counter" +dup +app_global_get + +// increment the value +int 1 ++ + +// store to scratch space +dup +store 0 + +// update global state +app_global_put + +// read local state for sender +int 0 +byte "counter" +app_local_get + +// increment the value +int 1 ++ +store 1 + +// update local state for sender +// update "counter" +int 0 +byte "counter" +load 1 +app_local_put + +// update "timestamp" +int 0 +byte "timestamp" +txn ApplicationArgs 0 +app_local_put + +// load return value as approval +load 0 +return + +handle_closeout: +// Handle CloseOut +//approval +int 1 +return + +handle_deleteapp: +// Check for creator +global CreatorAddress +txn Sender +== +return + +handle_updateapp: +// Check for creator +global CreatorAddress +txn Sender +== +return + +handle_approve: +int 1 +return \ No newline at end of file diff --git a/examples/application/clear.teal b/examples/application/clear.teal new file mode 100644 index 000000000..d793651c8 --- /dev/null +++ b/examples/application/clear.teal @@ -0,0 +1,3 @@ +#pragma version 4 +int 1 +return \ No newline at end of file diff --git a/examples/src/main/java/com/algorand/examples/AppExamples.java b/examples/src/main/java/com/algorand/examples/AppExamples.java index ee027e729..811b3676e 100644 --- a/examples/src/main/java/com/algorand/examples/AppExamples.java +++ b/examples/src/main/java/com/algorand/examples/AppExamples.java @@ -1,21 +1,215 @@ package com.algorand.examples; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Date; +import java.util.List; + +import com.algorand.algosdk.account.Account; +import com.algorand.algosdk.builder.transaction.ApplicationCallTransactionBuilder; +import com.algorand.algosdk.builder.transaction.ApplicationClearTransactionBuilder; +import com.algorand.algosdk.builder.transaction.ApplicationCloseTransactionBuilder; +import com.algorand.algosdk.builder.transaction.ApplicationCreateTransactionBuilder; +import com.algorand.algosdk.builder.transaction.ApplicationDeleteTransactionBuilder; +import com.algorand.algosdk.builder.transaction.ApplicationOptInTransactionBuilder; +import com.algorand.algosdk.builder.transaction.ApplicationUpdateTransactionBuilder; +import com.algorand.algosdk.crypto.TEALProgram; +import com.algorand.algosdk.logic.StateSchema; +import com.algorand.algosdk.transaction.SignedTransaction; +import com.algorand.algosdk.transaction.Transaction; +import com.algorand.algosdk.util.Encoder; +import com.algorand.algosdk.v2.client.Utils; +import com.algorand.algosdk.v2.client.common.AlgodClient; +import com.algorand.algosdk.v2.client.common.Response; +import com.algorand.algosdk.v2.client.model.CompileResponse; +import com.algorand.algosdk.v2.client.model.PendingTransactionResponse; +import com.algorand.algosdk.v2.client.model.PostTransactionsResponse; +import com.algorand.algosdk.v2.client.model.TransactionParametersResponse; + public class AppExamples { - -} - - -// ACCOUNT_RECOVER_MNEMONIC - -// Missing APP_SCHEMA -// Missing APP_SOURCE -// Missing APP_COMPILE -// Missing APP_CREATE -// Missing APP_OPTIN -// Missing APP_NOOP -// Missing APP_READ_STATE -// Missing APP_UPDATE -// Missing APP_CALL -// Missing APP_CLOSEOUT -// Missing APP_DELETE -// Missing APP_CLEAR \ No newline at end of file + + public static void main(String[] args) throws Exception { + AlgodClient algodClient = ExampleUtils.getAlgodClient(); + List accts = ExampleUtils.getSandboxAccounts(); + + Account creator = accts.get(0); + Account user = accts.get(1); + + // example: APP_SCHEMA + int localInts = 1; + int localBytes = 1; + int globalInts = 1; + int globalBytes = 0; + StateSchema localSchema = new StateSchema(localInts, localBytes); + StateSchema globalSchema = new StateSchema(globalInts, globalBytes); + // example: APP_SCHEMA + + // example: APP_SOURCE + // Read in the `teal` source files as a string + String approvalSource = Files.readString(Paths.get("application/approval.teal")); + String clearSource = Files.readString(Paths.get("application/clear.teal")); + // example: APP_SOURCE + + // example: APP_COMPILE + CompileResponse approvalResponse = algodClient.TealCompile().source(approvalSource.getBytes()).execute() + .body(); + CompileResponse clearResponse = algodClient.TealCompile().source(clearSource.getBytes()).execute() + .body(); + + TEALProgram approvalProg = new TEALProgram(approvalResponse.result); + TEALProgram clearProg = new TEALProgram(clearResponse.result); + // example: APP_COMPILE + + // example: APP_CREATE + Response rsp = algodClient.TransactionParams().execute(); + TransactionParametersResponse sp = rsp.body(); + + Transaction appCreate = ApplicationCreateTransactionBuilder.Builder() + .sender(creator.getAddress()) + .suggestedParams(sp) + .approvalProgram(approvalProg) + .clearStateProgram(clearProg) + .localStateSchema(localSchema) + .globalStateSchema(globalSchema) + .build(); + + SignedTransaction signedAppCreate = creator.signTransaction(appCreate); + Response createResponse = algodClient.RawTransaction() + .rawtxn(Encoder.encodeToMsgPack(signedAppCreate)).execute(); + + PendingTransactionResponse result = Utils.waitForConfirmation(algodClient, createResponse.body().txId, 4); + Long appId = result.applicationIndex; + System.out.printf("Created application with id: %d\n", appId); + // example: APP_CREATE + + // example: APP_OPTIN + Transaction optInTxn = ApplicationOptInTransactionBuilder.Builder() + .sender(user.getAddress()) + .suggestedParams(sp) + .applicationId(appId) + .build(); + + SignedTransaction signedOptIn = user.signTransaction(optInTxn); + Response optInResponse = algodClient.RawTransaction() + .rawtxn(Encoder.encodeToMsgPack(signedOptIn)).execute(); + + PendingTransactionResponse optInResult = Utils.waitForConfirmation(algodClient, optInResponse.body().txId, 4); + assert optInResult.confirmedRound > 0; + // example: APP_OPTIN + + // example: APP_NOOP + Transaction noopTxn = ApplicationCallTransactionBuilder.Builder() + .sender(user.getAddress()) + .suggestedParams(sp) + .applicationId(appId) + .build(); + + SignedTransaction signedNoop = user.signTransaction(noopTxn); + Response noopResponse = algodClient.RawTransaction() + .rawtxn(Encoder.encodeToMsgPack(signedNoop)).execute(); + + PendingTransactionResponse noopResult = Utils.waitForConfirmation(algodClient, noopResponse.body().txId, 4); + assert noopResult.confirmedRound > 0; + // example: APP_NOOP + + // example: APP_READ_STATE + // example: APP_READ_STATE + + // example: APP_UPDATE + String approvalSourceUpdated = Files.readString(Paths.get("application/approval_refactored.teal")); + CompileResponse approvalUpdatedResponse = algodClient.TealCompile().source(approvalSourceUpdated.getBytes()) + .execute() + .body(); + TEALProgram approvalProgUpdated = new TEALProgram(approvalUpdatedResponse.result); + + Transaction appUpdate = ApplicationUpdateTransactionBuilder.Builder() + .sender(creator.getAddress()) + .suggestedParams(sp) + .applicationId(appId) + .approvalProgram(approvalProgUpdated) + .clearStateProgram(clearProg) + .build(); + + SignedTransaction signedAppUpdate = creator.signTransaction(appUpdate); + Response updateResponse = algodClient.RawTransaction() + .rawtxn(Encoder.encodeToMsgPack(signedAppUpdate)).execute(); + PendingTransactionResponse updateResult = Utils.waitForConfirmation(algodClient, updateResponse.body().txId, 4); + assert updateResult.confirmedRound > 0; + // example: APP_UPDATE + + // example: APP_CALL + SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd 'at' HH:mm:ss"); + Date date = new Date(System.currentTimeMillis()); + + List appArgs = new ArrayList(); + appArgs.add(formatter.format(date).toString().getBytes()); + + // create unsigned transaction + Transaction callTransaction = ApplicationCallTransactionBuilder.Builder() + .sender(user.getAddress()) + .suggestedParams(sp) + .applicationId(appId) + .args(appArgs) + .build(); + + SignedTransaction signedCallTransaction = user.signTransaction(callTransaction); + Response callResponse = algodClient.RawTransaction() + .rawtxn(Encoder.encodeToMsgPack(signedCallTransaction)).execute(); + + PendingTransactionResponse callResult = Utils.waitForConfirmation(algodClient, callResponse.body().txId, 4); + assert callResult.confirmedRound > 0; + // display results + if (callResult.globalStateDelta != null) { + System.out.printf("\tGlobal state: %s\n", callResult.globalStateDelta); + } + + if (callResult.localStateDelta != null) { + System.out.printf("\tLocal state: %s\n", callResult.localStateDelta); + } + // example: APP_CALL + + // example: APP_CLOSEOUT + Transaction closeOutTxn = ApplicationCloseTransactionBuilder.Builder() + .sender(user.getAddress()) + .suggestedParams(sp) + .applicationId(appId) + .build(); + + SignedTransaction signedCloseOut = user.signTransaction(closeOutTxn); + Response closeOutResponse = algodClient.RawTransaction() + .rawtxn(Encoder.encodeToMsgPack(signedCloseOut)).execute(); + + PendingTransactionResponse closeOutResult = Utils.waitForConfirmation(algodClient, closeOutResponse.body().txId, + 4); + assert closeOutResult.confirmedRound > 0; + // example: APP_CLOSEOUT + + // example: APP_DELETE + Transaction appDelete = ApplicationDeleteTransactionBuilder.Builder() + .sender(creator.getAddress()) + .suggestedParams(sp) + .applicationId(appId) + .build(); + + SignedTransaction signedAppDelete = creator.signTransaction(appDelete); + Response deleteResponse = algodClient.RawTransaction() + .rawtxn(Encoder.encodeToMsgPack(signedAppDelete)).execute(); + PendingTransactionResponse deleteResult = Utils.waitForConfirmation(algodClient, deleteResponse.body().txId, 4); + assert deleteResult.confirmedRound > 0; + // example: APP_DELETE + + // example: APP_CLEAR + Transaction clearTxn = ApplicationClearTransactionBuilder.Builder() + .sender(user.getAddress()) + .suggestedParams(sp) + .applicationId(appId) + .build(); + + SignedTransaction signedClear = user.signTransaction(clearTxn); + // ... sign, send, wait + // example: APP_CLEAR + } + +} \ No newline at end of file From 2db1ebedc41779d1ce81e46514ef6c7c15cc3be6 Mon Sep 17 00:00:00 2001 From: Ben Guidarelli Date: Mon, 6 Mar 2023 15:42:01 -0500 Subject: [PATCH 20/22] Adding lsig examples --- examples/lsig/sample_arg.teal | 5 + examples/lsig/simple.teal | 3 + .../main/java/com/algorand/examples/LSig.java | 108 ++++++++++++++++++ 3 files changed, 116 insertions(+) create mode 100644 examples/lsig/sample_arg.teal create mode 100644 examples/lsig/simple.teal create mode 100644 examples/src/main/java/com/algorand/examples/LSig.java diff --git a/examples/lsig/sample_arg.teal b/examples/lsig/sample_arg.teal new file mode 100644 index 000000000..8f21008e4 --- /dev/null +++ b/examples/lsig/sample_arg.teal @@ -0,0 +1,5 @@ +#pragma version 5 +arg_0 +btoi +int 123 +== \ No newline at end of file diff --git a/examples/lsig/simple.teal b/examples/lsig/simple.teal new file mode 100644 index 000000000..d62986563 --- /dev/null +++ b/examples/lsig/simple.teal @@ -0,0 +1,3 @@ +#pragma version 5 +int 1 +return \ No newline at end of file diff --git a/examples/src/main/java/com/algorand/examples/LSig.java b/examples/src/main/java/com/algorand/examples/LSig.java new file mode 100644 index 000000000..799e4aaff --- /dev/null +++ b/examples/src/main/java/com/algorand/examples/LSig.java @@ -0,0 +1,108 @@ +package com.algorand.examples; + +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.util.ArrayList; +import java.util.List; + +import com.algorand.algosdk.account.Account; +import com.algorand.algosdk.account.LogicSigAccount; +import com.algorand.algosdk.crypto.LogicsigSignature; +import com.algorand.algosdk.transaction.SignedTransaction; +import com.algorand.algosdk.transaction.Transaction; +import com.algorand.algosdk.util.Encoder; +import com.algorand.algosdk.v2.client.Utils; +import com.algorand.algosdk.v2.client.common.AlgodClient; +import com.algorand.algosdk.v2.client.common.Response; +import com.algorand.algosdk.v2.client.model.CompileResponse; +import com.algorand.algosdk.v2.client.model.PendingTransactionResponse; +import com.algorand.algosdk.v2.client.model.PostTransactionsResponse; +import com.algorand.algosdk.v2.client.model.TransactionParametersResponse; + +public class LSig { + + public static void main(String[] args) throws Exception { + AlgodClient algodClient = ExampleUtils.getAlgodClient(); + List accts = ExampleUtils.getSandboxAccounts(); + Account seedAcct = accts.get(0); + + byte[] tealBinary = compileLsig(algodClient, "lsig/simple.teal"); + // example: LSIG_INIT + LogicSigAccount lsig = new LogicSigAccount(tealBinary, null); + // example: LSIG_INIT + + byte[] tealBinaryWithArgs = compileLsig(algodClient, "lsig/simple.teal"); + // example: LSIG_PASS_ARGS + List tealArgs = new ArrayList(); + // The arguments _must_ be byte arrays + byte[] arg1 = Encoder.encodeUint64(123l); + tealArgs.add(arg1); + LogicSigAccount lsigWithArgs = new LogicSigAccount(tealBinaryWithArgs, tealArgs); + // example: LSIG_PASS_ARGS + + // Create a transaction to seed the lsig address + TransactionParametersResponse seedParams = algodClient.TransactionParams().execute().body(); + Transaction seedTxn = Transaction.PaymentTransactionBuilder() + .suggestedParams(seedParams) + .sender(seedAcct.getAddress()) + .amount(10000000) + .receiver(lsigWithArgs.getAddress()) + .build(); + ExampleUtils.sendPrint(algodClient, seedAcct.signTransaction(seedTxn), "seed lsig"); + + // example: LSIG_SIGN_FULL + TransactionParametersResponse params = algodClient.TransactionParams().execute().body(); + // create a transaction + Transaction txn = Transaction.PaymentTransactionBuilder() + .sender(lsig.getAddress()) + .amount(100000) + .receiver(seedAcct.getAddress()) + .suggestedParams(params) + .build(); + // create the LogicSigTransaction with contract account LogicSigAccount + SignedTransaction stx = Account.signLogicsigTransaction(lsig.lsig, txn); + // send raw LogicSigTransaction to network + Response submitResult = algodClient.RawTransaction() + .rawtxn(Encoder.encodeToMsgPack(stx)).execute(); + String txid = submitResult.body().txId; + // Wait for transaction confirmation + PendingTransactionResponse pTrx = Utils.waitForConfirmation(algodClient, txid, 4); + System.out.printf("Transaction %s confirmed in round %d\n", txid, pTrx.confirmedRound); + // example: LSIG_SIGN_FULL + + // example: LSIG_DELEGATE_FULL + // account signs the logic, and now the logic may be passed instead + // of a signature for a transaction + LogicsigSignature delegateLsig = seedAcct.signLogicsig(lsigWithArgs.lsig); + params = algodClient.TransactionParams().execute().body(); + // create a transaction where the sender is the signer of the lsig + txn = Transaction.PaymentTransactionBuilder() + .sender(seedAcct.getAddress()) + .amount(100000) + .receiver(delegateLsig.toAddress()) + .suggestedParams(params) + .build(); + // Sign the transaction with the delegate lsig + stx = Account.signLogicsigTransaction(delegateLsig, txn); + // send raw LogicSigTransaction to network + submitResult = algodClient.RawTransaction().rawtxn(Encoder.encodeToMsgPack(stx)).execute(); + txid = submitResult.body().txId; + // Wait for transaction confirmation + PendingTransactionResponse delegatResponse = Utils.waitForConfirmation(algodClient, txid, 4); + System.out.printf("Transaction %s confirmed in round %d\n", txid, delegatResponse.confirmedRound); + // example: LSIG_DELEGATE_FULL + } + + public static byte[] compileLsig(AlgodClient algodClient, String path) throws Exception { + // example: LSIG_COMPILE + String tealsrc = Files.readString(Paths.get("lsig/simple.teal")); + Response compileResp = algodClient.TealCompile().source(tealsrc.getBytes()).execute(); + System.out.printf("Program: %s\n", compileResp.body().result); + System.out.printf("Address: %s\n", compileResp.body().hash); + byte[] tealBinary = Encoder.decodeFromBase64(compileResp.body().result); + // example: LSIG_COMPILE + return tealBinary; + } + +} From ef87cb9915fe4bf25d4490c5772112579fc381eb Mon Sep 17 00:00:00 2001 From: Ben Guidarelli Date: Mon, 6 Mar 2023 16:04:59 -0500 Subject: [PATCH 21/22] adding dryrun examples --- .../main/java/com/algorand/examples/ATC.java | 21 ++++++ .../java/com/algorand/examples/Debug.java | 72 +++++++++++++++++++ .../main/java/com/algorand/examples/LSig.java | 2 +- 3 files changed, 94 insertions(+), 1 deletion(-) create mode 100644 examples/src/main/java/com/algorand/examples/Debug.java diff --git a/examples/src/main/java/com/algorand/examples/ATC.java b/examples/src/main/java/com/algorand/examples/ATC.java index 150e42550..a9423c0c3 100644 --- a/examples/src/main/java/com/algorand/examples/ATC.java +++ b/examples/src/main/java/com/algorand/examples/ATC.java @@ -15,6 +15,7 @@ import com.algorand.algosdk.builder.transaction.PaymentTransactionBuilder; import com.algorand.algosdk.crypto.TEALProgram; import com.algorand.algosdk.logic.StateSchema; +import com.algorand.algosdk.transaction.AppBoxReference; import com.algorand.algosdk.transaction.AtomicTransactionComposer; import com.algorand.algosdk.transaction.MethodCallParams; import com.algorand.algosdk.transaction.SignedTransaction; @@ -82,6 +83,7 @@ public static void main(String[] args) throws Exception { atc.addMethodCall(mcp); // example: ATC_ADD_METHOD_CALL + // example: ATC_RESULTS ExecuteResult res = atc.execute(algodClient, 2); System.out.printf("App call (%s) confirmed in round %d\n", res.txIDs, res.confirmedRound); @@ -90,6 +92,25 @@ public static void main(String[] args) throws Exception { methodResult.value); }); // example: ATC_RESULTS + + // example: ATC_BOX_REF + MethodCallTransactionBuilder mct_builder = MethodCallTransactionBuilder.Builder(); + + List boxRefs = new ArrayList<>(); + boxRefs.add(new AppBoxReference(appId.intValue(), "cool-box".getBytes())); + MethodCallParams box_ref_mcp = mct_builder + .suggestedParams(sp) + .applicationId(appId) + .sender(acct.getAddress()) + .method(contract.getMethodByName("add")) + .methodArguments(methodArgs) + .signer(acct.getTransactionSigner()) + .onComplete(Transaction.OnCompletion.NoOpOC) + // Include reference to a box so the app logic may + // use it during evaluation + .boxReferences(boxRefs) + .build(); + // example: ATC_BOX_REF } public static void atcWithTws(AlgodClient algodClient, Account account) throws Exception { diff --git a/examples/src/main/java/com/algorand/examples/Debug.java b/examples/src/main/java/com/algorand/examples/Debug.java new file mode 100644 index 000000000..d0a06d714 --- /dev/null +++ b/examples/src/main/java/com/algorand/examples/Debug.java @@ -0,0 +1,72 @@ +package com.algorand.examples; + +import java.io.FileOutputStream; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.util.ArrayList; +import java.util.List; + +import com.algorand.algosdk.abi.Contract; +import com.algorand.algosdk.account.Account; +import com.algorand.algosdk.builder.transaction.MethodCallTransactionBuilder; +import com.algorand.algosdk.transaction.AtomicTransactionComposer; +import com.algorand.algosdk.transaction.MethodCallParams; +import com.algorand.algosdk.transaction.Transaction; +import com.algorand.algosdk.util.Encoder; +import com.algorand.algosdk.v2.client.Utils; +import com.algorand.algosdk.v2.client.common.AlgodClient; +import com.algorand.algosdk.v2.client.common.Response; +import com.algorand.algosdk.v2.client.model.DryrunRequest; +import com.algorand.algosdk.v2.client.model.DryrunResponse; +import com.algorand.algosdk.v2.client.model.DryrunTxnResult; +import com.algorand.algosdk.v2.client.model.TransactionParametersResponse; + +public class Debug { + + + public static void main(String[] args) throws Exception { + AlgodClient algodClient = ExampleUtils.getAlgodClient(); + List accts = ExampleUtils.getSandboxAccounts(); + Account acct = accts.get(0); + + Long appId = ATC.deployApp(algodClient, acct); + + String jsonContract = Files.readString(Paths.get("calculator/contract.json")); + Contract contract = Encoder.decodeFromJson(jsonContract, Contract.class); + + // example: DEBUG_DRYRUN_DUMP + // Set up the transactions we'd like to dryrun + AtomicTransactionComposer atc = new AtomicTransactionComposer(); + + List methodArgs = new ArrayList(); + methodArgs.add(1); + methodArgs.add(1); + + TransactionParametersResponse sp = algodClient.TransactionParams().execute().body(); + + MethodCallTransactionBuilder mctb = MethodCallTransactionBuilder.Builder(); + MethodCallParams mcp = mctb.applicationId(appId).signer(acct.getTransactionSigner()) + .suggestedParams(sp) + .sender(acct.getAddress()) + .method(contract.getMethodByName("add")) + .methodArguments(methodArgs) + .onComplete(Transaction.OnCompletion.NoOpOC) + .build(); + atc.addMethodCall(mcp); + + DryrunRequest drr = Utils.createDryrun(algodClient, atc.gatherSignatures(), "", 0L, 0L); + + FileOutputStream outfile = new FileOutputStream("my-dryrun.msgpack"); + outfile.write(Encoder.encodeToMsgPack(drr)); + outfile.close(); + // example: DEBUG_DRYRUN_DUMP + + // example: DEBUG_DRYRUN_SUBMIT + Response resp = algodClient.TealDryrun().request(drr).execute(); + DryrunResponse drResp = resp.body(); + DryrunTxnResult dryrunTxnResult = drResp.txns.get(0); + System.out.println(dryrunTxnResult.appCallMessages); + System.out.println(Utils.appTrace(dryrunTxnResult)); + // example: DEBUG_DRYRUN_SUBMIT + } +} diff --git a/examples/src/main/java/com/algorand/examples/LSig.java b/examples/src/main/java/com/algorand/examples/LSig.java index 799e4aaff..924b8563c 100644 --- a/examples/src/main/java/com/algorand/examples/LSig.java +++ b/examples/src/main/java/com/algorand/examples/LSig.java @@ -76,7 +76,7 @@ public static void main(String[] args) throws Exception { // of a signature for a transaction LogicsigSignature delegateLsig = seedAcct.signLogicsig(lsigWithArgs.lsig); params = algodClient.TransactionParams().execute().body(); - // create a transaction where the sender is the signer of the lsig + // create a transaction where the sender is the signer of the lsig txn = Transaction.PaymentTransactionBuilder() .sender(seedAcct.getAddress()) .amount(100000) From 0a5291573f863fa5aa6a87989f5a12abe14c76d1 Mon Sep 17 00:00:00 2001 From: Ben Guidarelli Date: Thu, 16 Mar 2023 11:13:07 -0400 Subject: [PATCH 22/22] shorter api keys, fix fee override --- .../java/com/algorand/examples/ExampleUtils.java | 6 +++--- .../java/com/algorand/examples/IndexerExamples.java | 2 +- .../java/com/algorand/examples/KMDExamples.java | 2 +- .../main/java/com/algorand/examples/Overview.java | 13 ++++++++----- 4 files changed, 13 insertions(+), 10 deletions(-) diff --git a/examples/src/main/java/com/algorand/examples/ExampleUtils.java b/examples/src/main/java/com/algorand/examples/ExampleUtils.java index b8783ec72..07fc8c1e3 100644 --- a/examples/src/main/java/com/algorand/examples/ExampleUtils.java +++ b/examples/src/main/java/com/algorand/examples/ExampleUtils.java @@ -25,16 +25,16 @@ public class ExampleUtils { private static String kmd_host = "http://localhost:4002"; - private static String kmd_token = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"; + private static String kmd_token = "a".repeat(64); private static KmdApi kmd = null; private static String algod_host = "http://localhost"; private static int algod_port = 4001; - private static String algod_token = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"; + private static String algod_token = "a".repeat(64); private static String indexer_host = "http://localhost"; private static int indexer_port = 8980; - private static String indexer_token = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"; + private static String indexer_token = "a".repeat(64); public static AlgodClient getAlgodClient() { return new AlgodClient(algod_host, algod_port, algod_token); diff --git a/examples/src/main/java/com/algorand/examples/IndexerExamples.java b/examples/src/main/java/com/algorand/examples/IndexerExamples.java index 832fa104a..c269af75a 100644 --- a/examples/src/main/java/com/algorand/examples/IndexerExamples.java +++ b/examples/src/main/java/com/algorand/examples/IndexerExamples.java @@ -12,7 +12,7 @@ public static void main(String[] args) throws Exception { // example: CREATE_INDEXER_CLIENT String indexerHost = "http://localhost"; int indexerPort = 8980; - String indexerToken = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"; + String indexerToken = "a".repeat(64); IndexerClient indexerClient = new IndexerClient(indexerHost, indexerPort, indexerToken); // example: CREATE_INDEXER_CLIENT diff --git a/examples/src/main/java/com/algorand/examples/KMDExamples.java b/examples/src/main/java/com/algorand/examples/KMDExamples.java index 86cdba618..9f20115bb 100644 --- a/examples/src/main/java/com/algorand/examples/KMDExamples.java +++ b/examples/src/main/java/com/algorand/examples/KMDExamples.java @@ -25,7 +25,7 @@ public class KMDExamples { public static void main(String[] args) throws ApiException { // example: KMD_CREATE_CLIENT String kmdHost = "http://localhost:4002"; - String kmdToken = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"; + String kmdToken = "a".repeat(64); KmdClient kmdClient = new KmdClient(); kmdClient.setBasePath(kmdHost); diff --git a/examples/src/main/java/com/algorand/examples/Overview.java b/examples/src/main/java/com/algorand/examples/Overview.java index 52290ed45..c2c72d2fb 100644 --- a/examples/src/main/java/com/algorand/examples/Overview.java +++ b/examples/src/main/java/com/algorand/examples/Overview.java @@ -1,9 +1,9 @@ package com.algorand.examples; +import java.math.BigInteger; import java.security.NoSuchAlgorithmException; import java.util.List; import com.algorand.algosdk.v2.client.Utils; -import com.algorand.algosdk.v2.client.algod.AccountInformation; import com.algorand.algosdk.v2.client.common.AlgodClient; import com.algorand.algosdk.v2.client.common.Response; import com.algorand.algosdk.v2.client.model.PendingTransactionResponse; @@ -54,13 +54,16 @@ public static void main(String[] args) throws Exception { // example: SP_MIN_FEE // example: TRANSACTION_FEE_OVERRIDE + BigInteger nullFee = null; Transaction feeOverrideTxn = Transaction.PaymentTransactionBuilder() .sender(acct.getAddress()) .receiver(acct2.getAddress()) .suggestedParams(suggestedParams.body()) - // override the fee given by suggested params - // to set a flat fee of 2x minfee to cover another transaction - // in the same group + // since suggestedParams sets a fee, we have to `null` it out + // or trying to set flatFee will fail with both set + .fee(nullFee) + // override the fee given by suggested params to set a flat + // fee of 2x minfee to cover another transaction in the same group .flatFee(2 * suggestedParams.body().minFee).build(); // example: TRANSACTION_FEE_OVERRIDE @@ -91,7 +94,7 @@ public static AlgodClient createClient() { // example: ALGOD_CREATE_CLIENT String algodHost = "http://localhost"; int algodPort = 4001; - String algodToken = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"; + String algodToken = "a".repeat(64); AlgodClient algodClient = new AlgodClient(algodHost, algodPort, algodToken); // OR if the API provider requires a specific header key for the token