diff --git a/sdk/src/intTest/org/onflow/flow/sdk/ExposeAccountKeyIssueTest.kt b/sdk/src/intTest/org/onflow/flow/sdk/ExposeAccountKeyIssueTest.kt index 0ffea60d..034909e6 100644 --- a/sdk/src/intTest/org/onflow/flow/sdk/ExposeAccountKeyIssueTest.kt +++ b/sdk/src/intTest/org/onflow/flow/sdk/ExposeAccountKeyIssueTest.kt @@ -6,7 +6,12 @@ import org.onflow.flow.sdk.test.FlowServiceAccountCredentials import org.onflow.flow.sdk.test.FlowTestClient import org.onflow.flow.sdk.test.TestAccount import org.junit.jupiter.api.Assertions.* +import org.onflow.flow.sdk.IntegrationTestUtils.getAccount +import org.onflow.flow.sdk.IntegrationTestUtils.getAccountAddressFromResult +import org.onflow.flow.sdk.IntegrationTestUtils.handleResult +import org.onflow.flow.sdk.IntegrationTestUtils.loadScript import java.math.BigDecimal +import java.nio.charset.StandardCharsets @FlowEmulatorTest class ExposeAccountKeyIssueTest { @@ -37,42 +42,13 @@ class ExposeAccountKeyIssueTest { val pair1 = Crypto.generateKeyPair(signatureAlgorithm1) val signer1 = Crypto.getSigner(pair1.private, hashAlgorithm1) + val loadedScript1 = String(loadScript("cadence/expose_account_key_issue/expose_account_key_issue_1.cdc"), StandardCharsets.UTF_8) val createAccountResult = flow.simpleFlowTransaction( serviceAccount.flowAddress, serviceAccount.signer ) { script { - """ - import FlowToken from 0xFLOWTOKEN - import FungibleToken from 0xFUNGIBLETOKEN - - transaction(startingBalance: UFix64, publicKey: String, signatureAlgorithm: UInt8, hashAlgorithm: UInt8) { - prepare(signer: AuthAccount) { - - let newAccount = AuthAccount(payer: signer) - - newAccount.keys.add( - publicKey: PublicKey( - publicKey: publicKey.decodeHex(), - signatureAlgorithm: SignatureAlgorithm(rawValue: signatureAlgorithm)! - ), - hashAlgorithm: HashAlgorithm(rawValue: hashAlgorithm)!, - weight: UFix64(1000) - ) - - let provider = signer.borrow<&FlowToken.Vault>(from: /storage/flowTokenVault) - ?? panic("Could not borrow FlowToken.Vault reference") - - let newVault = newAccount - .getCapability(/public/flowTokenReceiver) - .borrow<&{FungibleToken.Receiver}>() - ?? panic("Could not borrow FungibleToken.Receiver reference") - - let coin <- provider.withdraw(amount: startingBalance) - newVault.deposit(from: <- coin) - } - } - """ + loadedScript1 } arguments { arg { ufix64(startingBalance) } @@ -82,10 +58,10 @@ class ExposeAccountKeyIssueTest { } }.sendAndWaitForSeal() - val createAccountResultData = IntegrationTestUtils.handleResult(createAccountResult, "Failed to create account") - val newAccountAddress = IntegrationTestUtils.getAccountAddressFromResult(createAccountResultData) + val createAccountResultData = handleResult(createAccountResult, "Failed to create account") + val newAccountAddress = getAccountAddressFromResult(createAccountResultData) - val account = IntegrationTestUtils.getAccount(flow, newAccountAddress) + val account = getAccount(flow, newAccountAddress) assertEquals(1, account.keys.size) assertEquals(pair1.public.hex, account.keys[0].publicKey.base16Value) @@ -97,22 +73,10 @@ class ExposeAccountKeyIssueTest { val pair2 = Crypto.generateKeyPair(signatureAlgorithm2) val signer2 = Crypto.getSigner(pair2.private, hashAlgorithm2) + val loadedScript2 = String(loadScript("cadence/expose_account_key_issue/expose_account_key_issue_2.cdc"), StandardCharsets.UTF_8) val addKeyResult = flow.simpleFlowTransaction(newAccountAddress, signer1) { script { - """ - transaction(publicKey: String, signatureAlgorithm: UInt8, hashAlgorithm: UInt8, weight: UFix64) { - prepare(signer: AuthAccount) { - signer.keys.add( - publicKey: PublicKey( - publicKey: publicKey.decodeHex(), - signatureAlgorithm: SignatureAlgorithm(rawValue: signatureAlgorithm)! - ), - hashAlgorithm: HashAlgorithm(rawValue: hashAlgorithm)!, - weight: weight - ) - } - } - """ + loadedScript2 } arguments { arg { string(pair2.public.hex) } @@ -122,9 +86,9 @@ class ExposeAccountKeyIssueTest { } }.sendAndWaitForSeal() - IntegrationTestUtils.handleResult(addKeyResult, "Failed to add key") + handleResult(addKeyResult, "Failed to add key") - val updatedAccount = IntegrationTestUtils.getAccount(flow, newAccountAddress) + val updatedAccount = getAccount(flow, newAccountAddress) assertEquals(2, updatedAccount.keys.size) assertEquals(pair1.public.hex, updatedAccount.keys[0].publicKey.base16Value) @@ -132,25 +96,20 @@ class ExposeAccountKeyIssueTest { assertFalse(updatedAccount.keys[0].revoked) assertFalse(updatedAccount.keys[1].revoked) + val loadedScript3 = String(loadScript("cadence/expose_account_key_issue/expose_account_key_issue_3.cdc"), StandardCharsets.UTF_8) // Remove the second key val removeKeyResult = flow.simpleFlowTransaction(newAccountAddress, signer1) { script { - """ - transaction(index: Int) { - prepare(signer: AuthAccount) { - signer.keys.revoke(keyIndex: index) ?? panic("Key not found to revoke") - } - } - """ + loadedScript3 } arguments { arg { int(1) } } }.sendAndWaitForSeal() - IntegrationTestUtils.handleResult(removeKeyResult, "Failed to remove key") + handleResult(removeKeyResult, "Failed to remove key") - val finalAccount = IntegrationTestUtils.getAccount(flow, newAccountAddress) + val finalAccount = getAccount(flow, newAccountAddress) assertEquals(2, finalAccount.keys.size) assertEquals(pair1.public.hex, finalAccount.keys[0].publicKey.base16Value) diff --git a/sdk/src/intTest/org/onflow/flow/sdk/IntegrationTestUtils.kt b/sdk/src/intTest/org/onflow/flow/sdk/IntegrationTestUtils.kt index ddba64cd..79bb5991 100644 --- a/sdk/src/intTest/org/onflow/flow/sdk/IntegrationTestUtils.kt +++ b/sdk/src/intTest/org/onflow/flow/sdk/IntegrationTestUtils.kt @@ -3,6 +3,7 @@ package org.onflow.flow.sdk import org.onflow.flow.sdk.cadence.AddressField object IntegrationTestUtils { + fun loadScript(name: String): ByteArray = javaClass.classLoader.getResourceAsStream(name)!!.use { it.readAllBytes() } fun newMainnetAccessApi(): FlowAccessApi = Flow.newAccessApi(MAINNET_HOSTNAME) fun newTestnetAccessApi(): FlowAccessApi = Flow.newAccessApi(TESTNET_HOSTNAME) @@ -39,6 +40,6 @@ object IntegrationTestUtils { fun getAccount(api: FlowAccessApi, address: FlowAddress): FlowAccount { val result = api.getAccountAtLatestBlock(address) - return handleResult(result, "Failed to get account at latest block") as FlowAccount + return handleResult(result, "Failed to get account at latest block") } } diff --git a/sdk/src/intTest/org/onflow/flow/sdk/cadence/JsonCadenceTest.kt b/sdk/src/intTest/org/onflow/flow/sdk/cadence/JsonCadenceTest.kt index 2754c92c..be041eee 100644 --- a/sdk/src/intTest/org/onflow/flow/sdk/cadence/JsonCadenceTest.kt +++ b/sdk/src/intTest/org/onflow/flow/sdk/cadence/JsonCadenceTest.kt @@ -2,8 +2,10 @@ package org.onflow.flow.sdk.cadence import kotlinx.serialization.Serializable import org.assertj.core.api.Assertions.assertThat +import org.junit.jupiter.api.BeforeEach import org.junit.jupiter.api.Test import org.onflow.flow.sdk.* +import java.nio.charset.StandardCharsets class JsonCadenceTest { @Serializable @@ -37,11 +39,26 @@ class JsonCadenceTest { val rawValue: Int ) - private val flow = IntegrationTestUtils.newMainnetAccessApi() + private lateinit var flow: FlowAccessApi + + @BeforeEach + fun setup() { + flow = IntegrationTestUtils.newMainnetAccessApi() + } + + private fun loadScriptContent(path: String): String { + return String(IntegrationTestUtils.loadScript(path), StandardCharsets.UTF_8) + } + + private fun executeScript(scriptPath: String): FlowAccessApi.AccessApiCallResponse { + val loadedScript = loadScriptContent(scriptPath) + return flow.simpleFlowScript { + script { loadedScript } + } + } @Test fun `Can parse new JSON Cadence`() { - val flow = IntegrationTestUtils.newMainnetAccessApi() val tx = when (val transactionResult = flow.getTransactionResultById(FlowId("273f68ffe175a0097db60bc7cf5e92c5a775d189af3f5636f5432c1206be771a"))) { is FlowAccessApi.AccessApiCallResponse.Success -> transactionResult.data is FlowAccessApi.AccessApiCallResponse.Error -> throw IllegalStateException("Failed to get transaction result: ${transactionResult.message}", transactionResult.throwable) @@ -53,15 +70,7 @@ class JsonCadenceTest { @Test fun decodeOptional() { - val result = flow.simpleFlowScript { - script { - """ - pub fun main(): Bool? { - return nil - } - """.trimIndent() - } - } + val result = executeScript("cadence/json_cadence/decode_optional.cdc") val data = when (result) { is FlowAccessApi.AccessApiCallResponse.Success -> result.data.jsonCadence.decode() @@ -73,15 +82,7 @@ class JsonCadenceTest { @Test fun decodeOptional2() { - val result = flow.simpleFlowScript { - script { - """ - pub fun main(): Bool? { - return true - } - """.trimIndent() - } - } + val result = executeScript("cadence/json_cadence/decode_optional_2.cdc") val data = when (result) { is FlowAccessApi.AccessApiCallResponse.Success -> result.data.jsonCadence.decode() @@ -93,15 +94,8 @@ class JsonCadenceTest { @Test fun decodeBoolean() { - val result = flow.simpleFlowScript { - script { - """ - pub fun main(): Bool { - return true - } - """.trimIndent() - } - } + val result = executeScript("cadence/json_cadence/decode_boolean.cdc") + val data = when (result) { is FlowAccessApi.AccessApiCallResponse.Success -> result.data.jsonCadence.decode() is FlowAccessApi.AccessApiCallResponse.Error -> throw IllegalStateException("Failed to execute script: ${result.message}", result.throwable) @@ -112,15 +106,7 @@ class JsonCadenceTest { @Test fun decodeArray() { - val result = flow.simpleFlowScript { - script { - """ - pub fun main(): [UInt64] { - return [1,3,4,5] - } - """.trimIndent() - } - } + val result = executeScript("cadence/json_cadence/decode_array.cdc") val data = when (result) { is FlowAccessApi.AccessApiCallResponse.Success -> result.data.jsonCadence.decode>() @@ -133,15 +119,7 @@ class JsonCadenceTest { @Test fun decodeUFix64() { - val result = flow.simpleFlowScript { - script { - """ - pub fun main(): UFix64 { - return 0.789111 - } - """.trimIndent() - } - } + val result = executeScript("cadence/json_cadence/decode_ufix64.cdc") val data = when (result) { is FlowAccessApi.AccessApiCallResponse.Success -> result.data.jsonCadence.decode() @@ -153,30 +131,9 @@ class JsonCadenceTest { @Test fun decodeStruct() { + val loadedScript = loadScriptContent("cadence/json_cadence/decode_struct.cdc") val result = flow.simpleFlowScript { - script { - """ - pub struct StorageInfo { - pub let capacity: Int - pub let used: Int - pub let available: Int - - init(capacity: Int, used: Int, available: Int) { - self.capacity = capacity - self.used = used - self.available = available - } - } - - pub fun main(addr: Address): [StorageInfo] { - let acct = getAccount(addr) - return [StorageInfo(capacity: 1, - used: 2, - available: 3)] - } - """.trimIndent() - } - + script { loadedScript } arg { address("0x84221fe0294044d7") } } @@ -192,43 +149,9 @@ class JsonCadenceTest { @Test fun decodeComplexDict() { + val loadedScript = loadScriptContent("cadence/json_cadence/decode_complex_dict.cdc") val result = flow.simpleFlowScript { - script { - """ - pub struct StorageInfo { - pub let capacity: UInt64 - pub let used: UInt64 - pub let available: UInt64 - pub let foo: Foo - - init(capacity: UInt64, used: UInt64, available: UInt64, foo: Foo) { - self.capacity = capacity - self.used = used - self.available = available - self.foo = foo - } - } - - pub struct Foo { - pub let bar: Int - - init(bar: Int) { - self.bar = bar - } - } - - pub fun main(addr: Address): {String: [StorageInfo]} { - let acct = getAccount(addr) - - let foo = Foo(bar: 1) - return {"test": [StorageInfo(capacity: acct.storageCapacity, - used: acct.storageUsed, - available: acct.storageCapacity - acct.storageUsed, - foo: foo)]} - } - """.trimIndent() - } - + script { loadedScript } arg { address("0x84221fe0294044d7") } } @@ -242,24 +165,7 @@ class JsonCadenceTest { @Test fun decodeResource() { - val result = flow.simpleFlowScript { - script { - """ - pub resource SomeResource { - pub var value: Int - - init(value: Int) { - self.value = value - } - } - - pub fun main(): @SomeResource { - let newResource <- create SomeResource(value: 20) - return <-newResource - } - """.trimIndent() - } - } + val result = executeScript("cadence/json_cadence/decode_resource.cdc") val decodedResource = when (result) { is FlowAccessApi.AccessApiCallResponse.Success -> result.data.jsonCadence.decode() @@ -272,21 +178,7 @@ class JsonCadenceTest { @Test fun decodeEnum() { - val result = flow.simpleFlowScript { - script { - """ - pub enum Color: UInt8 { - pub case red - pub case green - pub case blue - } - - pub fun main() : Color { - return Color.red - } - """.trimIndent() - } - } + val result = executeScript("cadence/json_cadence/decode_enum.cdc") val decodedEnum = when (result) { is FlowAccessApi.AccessApiCallResponse.Success -> result.data.jsonCadence.decode() @@ -299,18 +191,7 @@ class JsonCadenceTest { @Test fun decodeReference() { - val result = flow.simpleFlowScript { - script { - """ - pub let hello = "Hello" - pub let helloRef: &String = &hello as &String - - pub fun main(): &String { - return helloRef - } - """.trimIndent() - } - } + val result = executeScript("cadence/json_cadence/decode_reference.cdc") val decodedReference = when (result) { is FlowAccessApi.AccessApiCallResponse.Success -> result.data.jsonCadence.decodeToAny() diff --git a/sdk/src/intTest/org/onflow/flow/sdk/extensions/ProjectTestExtensionsTest.kt b/sdk/src/intTest/org/onflow/flow/sdk/extensions/ProjectTestExtensionsTest.kt index 88f17745..02ec5254 100644 --- a/sdk/src/intTest/org/onflow/flow/sdk/extensions/ProjectTestExtensionsTest.kt +++ b/sdk/src/intTest/org/onflow/flow/sdk/extensions/ProjectTestExtensionsTest.kt @@ -44,7 +44,7 @@ class ProjectTestExtensionsTest { contracts = [ FlowTestContractDeployment( name = "NothingContract", - codeClasspathLocation = "/cadence/NothingContract.cdc", + codeClasspathLocation = "/cadence/test_extensions/NothingContract.cdc", arguments = [ TestContractArg("name", "The Name"), TestContractArg("description", "The Description"), @@ -74,7 +74,7 @@ class ProjectTestExtensionsTest { ), FlowTestContractDeployment( name = "NothingContract", - codeClasspathLocation = "/cadence/NothingContract.cdc", + codeClasspathLocation = "/cadence/test_extensions/NothingContract.cdc", arguments = [ TestContractArg("name", "The Name"), TestContractArg("description", "The Description"), diff --git a/sdk/src/intTest/org/onflow/flow/sdk/extensions/TestExtensionsTest.kt b/sdk/src/intTest/org/onflow/flow/sdk/extensions/TestExtensionsTest.kt index 8fcd2459..2c70ac56 100644 --- a/sdk/src/intTest/org/onflow/flow/sdk/extensions/TestExtensionsTest.kt +++ b/sdk/src/intTest/org/onflow/flow/sdk/extensions/TestExtensionsTest.kt @@ -35,7 +35,7 @@ class TestExtensionsTest { contracts = [ FlowTestContractDeployment( name = "NothingContract", - codeClasspathLocation = "/cadence/NothingContract.cdc", + codeClasspathLocation = "/cadence/test_extensions/NothingContract.cdc", arguments = [ TestContractArg("name", "The Name"), TestContractArg("description", "The Description"), @@ -51,7 +51,7 @@ class TestExtensionsTest { contracts = [ FlowTestContractDeployment( name = "EmptyContract", - code = "pub contract EmptyContract { init() { } }" + codeClasspathLocation = "/cadence/test_extensions/EmptyContract.cdc", ) ] ) @@ -65,7 +65,7 @@ class TestExtensionsTest { ), FlowTestContractDeployment( name = "NothingContract", - codeClasspathLocation = "/cadence/NothingContract.cdc", + codeClasspathLocation = "/cadence/test_extensions/NothingContract.cdc", arguments = [ TestContractArg("name", "The Name"), TestContractArg("description", "The Description"), @@ -73,7 +73,7 @@ class TestExtensionsTest { ), FlowTestContractDeployment( name = "EmptyContract", - code = "pub contract EmptyContract { init() { } }" + codeClasspathLocation = "/cadence/test_extensions/EmptyContract.cdc", ) ] ) @@ -88,14 +88,11 @@ class TestExtensionsTest { contracts = [ FlowTestContractDeployment( name = "ContractInterface", - code = "pub contract interface ContractInterface { }" + codeClasspathLocation = "/cadence/test_extensions/ContractInterface.cdc", ), FlowTestContractDeployment( name = "ContractSuccessor", - code = """ - import ContractInterface from 0xCONTRACTINTERFACE - pub contract ContractSuccessor : ContractInterface { init() { } } - """ + codeClasspathLocation = "/cadence/test_extensions/ContractSuccessor.cdc", ), ] ) diff --git a/sdk/src/intTest/org/onflow/flow/sdk/transaction/TransactionCreationTest.kt b/sdk/src/intTest/org/onflow/flow/sdk/transaction/TransactionCreationTest.kt index 713e22ff..7e8d8c21 100644 --- a/sdk/src/intTest/org/onflow/flow/sdk/transaction/TransactionCreationTest.kt +++ b/sdk/src/intTest/org/onflow/flow/sdk/transaction/TransactionCreationTest.kt @@ -2,13 +2,17 @@ package org.onflow.flow.sdk.transaction import org.onflow.flow.sdk.* import org.onflow.flow.sdk.crypto.Crypto -import org.onflow.flow.sdk.IntegrationTestUtils.transaction import org.assertj.core.api.Assertions.assertThat import org.onflow.flow.sdk.test.FlowEmulatorTest import org.onflow.flow.sdk.test.FlowServiceAccountCredentials import org.onflow.flow.sdk.test.FlowTestClient import org.onflow.flow.sdk.test.TestAccount import org.junit.jupiter.api.Test +import org.onflow.flow.sdk.IntegrationTestUtils.getAccount +import org.onflow.flow.sdk.IntegrationTestUtils.handleResult +import org.onflow.flow.sdk.IntegrationTestUtils.loadScript +import org.onflow.flow.sdk.IntegrationTestUtils.transaction +import java.nio.charset.StandardCharsets @FlowEmulatorTest class TransactionCreationTest { @@ -47,7 +51,7 @@ class TransactionCreationTest { @Test fun `Can create an account using the transaction DSL`() { val latestBlockId = getLatestBlockId(accessAPI) - val payerAccount = IntegrationTestUtils.getAccount(accessAPI, serviceAccount.flowAddress) + val payerAccount = getAccount(accessAPI, serviceAccount.flowAddress) val newAccountKeyPair = Crypto.generateKeyPair(SignatureAlgorithm.ECDSA_P256) val newAccountPublicKey = FlowAccountKey( @@ -57,16 +61,11 @@ class TransactionCreationTest { weight = 1000 ) + val loadedScript = String(loadScript("cadence/transaction_creation/transaction_creation.cdc"), StandardCharsets.UTF_8) + val tx = flowTransaction { script { - """ - transaction(publicKey: String) { - prepare(signer: AuthAccount) { - let account = AuthAccount(payer: signer) - account.addPublicKey(publicKey.decodeHex()) - } - } - """ + loadedScript } arguments { @@ -93,9 +92,9 @@ class TransactionCreationTest { } } - val txID = IntegrationTestUtils.handleResult(accessAPI.sendTransaction(tx), "Failed to send transaction") + val txID = handleResult(accessAPI.sendTransaction(tx), "Failed to send transaction") - val result = IntegrationTestUtils.handleResult(waitForSeal(accessAPI, txID), "Failed to wait for seal") + val result = handleResult(waitForSeal(accessAPI, txID), "Failed to wait for seal") assertThat(result).isNotNull assertThat(result.status).isEqualTo(FlowTransactionStatus.SEALED) @@ -111,16 +110,11 @@ class TransactionCreationTest { weight = 1000 ) + val loadedScript = String(loadScript("cadence/transaction_creation/transaction_creation_simple_transaction.cdc"), StandardCharsets.UTF_8) + val transactionResult = accessAPI.simpleFlowTransaction(serviceAccount.flowAddress, serviceAccount.signer) { script { - """ - transaction(publicKey: String) { - prepare(signer: AuthAccount) { - let account = AuthAccount(payer: signer) - account.addPublicKey(publicKey.decodeHex()) - } - } - """ + loadedScript } arguments { @@ -128,13 +122,13 @@ class TransactionCreationTest { } }.sendAndWaitForSeal() - val result = IntegrationTestUtils.handleResult(transactionResult, "Failed to create account") + val result = handleResult(transactionResult, "Failed to create account") assertThat(result.status).isEqualTo(FlowTransactionStatus.SEALED) } private fun getLatestBlockId(api: FlowAccessApi): FlowId { val result = api.getLatestBlockHeader() - return IntegrationTestUtils.handleResult(result, "Failed to get latest block header").id + return handleResult(result, "Failed to get latest block header").id } } diff --git a/sdk/src/intTest/org/onflow/flow/sdk/transaction/TransactionDecodingTest.kt b/sdk/src/intTest/org/onflow/flow/sdk/transaction/TransactionDecodingTest.kt index 53248053..ddd40314 100644 --- a/sdk/src/intTest/org/onflow/flow/sdk/transaction/TransactionDecodingTest.kt +++ b/sdk/src/intTest/org/onflow/flow/sdk/transaction/TransactionDecodingTest.kt @@ -4,6 +4,8 @@ import org.onflow.flow.sdk.* import org.assertj.core.api.Assertions.assertThat import org.onflow.flow.sdk.test.FlowEmulatorTest import org.junit.jupiter.api.Test +import org.onflow.flow.sdk.IntegrationTestUtils.loadScript +import java.nio.charset.StandardCharsets @FlowEmulatorTest class TransactionDecodingTest { @@ -52,8 +54,10 @@ class TransactionDecodingTest { val proposerAddress = "f8d6e0586b0a20c7" val payerAddress = "ee82856bf20e2aa6" + val loadedScript = String(loadScript("cadence/transaction_decoding/transaction_decoding_precompute_txid.cdc"), StandardCharsets.UTF_8) + var testTx = FlowTransaction( - script = FlowScript("transaction { execute { log(\"Hello, World!\") } }"), + script = FlowScript(loadedScript), arguments = emptyList(), referenceBlockId = FlowId.of(byteArrayOf(1, 2).copyOf(32)), gasLimit = 42, diff --git a/sdk/src/intTest/org/onflow/flow/sdk/transaction/TransactionIntegrationTest.kt b/sdk/src/intTest/org/onflow/flow/sdk/transaction/TransactionIntegrationTest.kt index 8b8a447b..6c653f0d 100644 --- a/sdk/src/intTest/org/onflow/flow/sdk/transaction/TransactionIntegrationTest.kt +++ b/sdk/src/intTest/org/onflow/flow/sdk/transaction/TransactionIntegrationTest.kt @@ -5,14 +5,17 @@ import org.onflow.flow.sdk.test.FlowEmulatorTest import org.assertj.core.api.Assertions.assertThat import org.junit.jupiter.api.Test import org.junit.jupiter.api.fail +import org.onflow.flow.sdk.IntegrationTestUtils.handleResult +import org.onflow.flow.sdk.IntegrationTestUtils.newMainnetAccessApi +import org.onflow.flow.sdk.IntegrationTestUtils.newTestnetAccessApi @FlowEmulatorTest class TransactionIntegrationTest { @Test fun wut() { val account = try { - IntegrationTestUtils.handleResult( - IntegrationTestUtils.newTestnetAccessApi().getAccountAtLatestBlock(FlowAddress("0x6bd3869f2631beb3")), + handleResult( + newTestnetAccessApi().getAccountAtLatestBlock(FlowAddress("0x6bd3869f2631beb3")), "Failed to get account" ) } catch (e: Exception) { @@ -23,16 +26,16 @@ class TransactionIntegrationTest { @Test fun `Can connect to mainnet`() { - val accessAPI = IntegrationTestUtils.newMainnetAccessApi() + val accessAPI = newMainnetAccessApi() try { - IntegrationTestUtils.handleResult(accessAPI.ping(), "Failed to ping") + handleResult(accessAPI.ping(), "Failed to ping") } catch (e: Exception) { fail("Failed to ping mainnet: ${e.message}") } val address = FlowAddress("e467b9dd11fa00df") val account = try { - IntegrationTestUtils.handleResult( + handleResult( accessAPI.getAccountAtLatestBlock(address), "Failed to get account" ) @@ -47,9 +50,9 @@ class TransactionIntegrationTest { @Test fun `Can get network parameters`() { - val accessAPI = IntegrationTestUtils.newMainnetAccessApi() + val accessAPI = newMainnetAccessApi() val networkParams = try { - IntegrationTestUtils.handleResult( + handleResult( accessAPI.getNetworkParameters(), "Failed to get network parameters" ) @@ -62,9 +65,9 @@ class TransactionIntegrationTest { @Test fun `Can get latest protocol state snapshot`() { - val accessAPI = IntegrationTestUtils.newMainnetAccessApi() + val accessAPI = newMainnetAccessApi() val snapshot = try { - IntegrationTestUtils.handleResult( + handleResult( accessAPI.getLatestProtocolStateSnapshot(), "Failed to get latest protocol state snapshot" ) @@ -77,11 +80,11 @@ class TransactionIntegrationTest { @Test fun `Can parse events`() { - val accessApi = IntegrationTestUtils.newMainnetAccessApi() + val accessApi = newMainnetAccessApi() // https://flowscan.org/transaction/8c2e9d37a063240f236aa181e1454eb62991b42302534d4d6dd3839c2df0ef14 val tx = try { - IntegrationTestUtils.handleResult( + handleResult( accessApi.getTransactionById(FlowId("8c2e9d37a063240f236aa181e1454eb62991b42302534d4d6dd3839c2df0ef14")), "Failed to get transaction" ) @@ -92,7 +95,7 @@ class TransactionIntegrationTest { assertThat(tx).isNotNull val results = try { - IntegrationTestUtils.handleResult( + handleResult( accessApi.getTransactionResultById(FlowId("8c2e9d37a063240f236aa181e1454eb62991b42302534d4d6dd3839c2df0ef14")), "Failed to get transaction results" ) @@ -119,10 +122,10 @@ class TransactionIntegrationTest { @Test fun `Can get block header by id`() { - val accessAPI = IntegrationTestUtils.newMainnetAccessApi() + val accessAPI = newMainnetAccessApi() val latestBlock = try { - IntegrationTestUtils.handleResult( + handleResult( accessAPI.getLatestBlock(true), "Failed to get latest block" ) @@ -133,7 +136,7 @@ class TransactionIntegrationTest { assertThat(latestBlock).isNotNull val blockHeaderById = try { - IntegrationTestUtils.handleResult( + handleResult( accessAPI.getBlockHeaderById(latestBlock.id), "Failed to get block header by ID" ) @@ -146,10 +149,10 @@ class TransactionIntegrationTest { @Test fun `Can get block header by height`() { - val accessAPI = IntegrationTestUtils.newMainnetAccessApi() + val accessAPI = newMainnetAccessApi() val latestBlock = try { - IntegrationTestUtils.handleResult( + handleResult( accessAPI.getLatestBlock(true), "Failed to get latest block" ) @@ -160,7 +163,7 @@ class TransactionIntegrationTest { assertThat(latestBlock).isNotNull val blockHeader = try { - IntegrationTestUtils.handleResult( + handleResult( accessAPI.getBlockHeaderByHeight(latestBlock.height), "Failed to get block header by height" ) @@ -174,10 +177,10 @@ class TransactionIntegrationTest { @Test fun `Can get latest block`() { - val accessAPI = IntegrationTestUtils.newMainnetAccessApi() + val accessAPI = newMainnetAccessApi() val latestBlock = try { - IntegrationTestUtils.handleResult( + handleResult( accessAPI.getLatestBlock(true), "Failed to get latest block" ) @@ -190,10 +193,10 @@ class TransactionIntegrationTest { @Test fun `Can get block by id`() { - val accessAPI = IntegrationTestUtils.newMainnetAccessApi() + val accessAPI = newMainnetAccessApi() val latestBlock = try { - IntegrationTestUtils.handleResult( + handleResult( accessAPI.getLatestBlock(true), "Failed to get latest block" ) @@ -204,7 +207,7 @@ class TransactionIntegrationTest { assertThat(latestBlock).isNotNull val blockById = try { - IntegrationTestUtils.handleResult( + handleResult( accessAPI.getBlockById(latestBlock.id), "Failed to get block by ID" ) @@ -218,10 +221,10 @@ class TransactionIntegrationTest { @Test fun `Can get block by height`() { - val accessAPI = IntegrationTestUtils.newMainnetAccessApi() + val accessAPI = newMainnetAccessApi() val latestBlock = try { - IntegrationTestUtils.handleResult( + handleResult( accessAPI.getLatestBlock(true), "Failed to get latest block" ) @@ -232,7 +235,7 @@ class TransactionIntegrationTest { assertThat(latestBlock).isNotNull val blockByHeight = try { - IntegrationTestUtils.handleResult( + handleResult( accessAPI.getBlockByHeight(latestBlock.height), "Failed to get block by height" ) @@ -246,11 +249,11 @@ class TransactionIntegrationTest { @Test fun `Can get account by address`() { - val accessAPI = IntegrationTestUtils.newMainnetAccessApi() + val accessAPI = newMainnetAccessApi() val address = FlowAddress("18eb4ee6b3c026d2") val account = try { - IntegrationTestUtils.handleResult( + handleResult( accessAPI.getAccountByAddress(address), "Failed to get account by address" ) @@ -264,11 +267,11 @@ class TransactionIntegrationTest { @Test fun `Can get account by address at latest block`() { - val accessAPI = IntegrationTestUtils.newMainnetAccessApi() + val accessAPI = newMainnetAccessApi() val address = FlowAddress("18eb4ee6b3c026d2") val account = try { - IntegrationTestUtils.handleResult( + handleResult( accessAPI.getAccountAtLatestBlock(address), "Failed to get account at latest block" ) @@ -282,10 +285,10 @@ class TransactionIntegrationTest { @Test fun `Can get account by block height`() { - val accessAPI = IntegrationTestUtils.newMainnetAccessApi() + val accessAPI = newMainnetAccessApi() val latestBlock = try { - IntegrationTestUtils.handleResult( + handleResult( accessAPI.getLatestBlock(true), "Failed to get latest block" ) @@ -294,7 +297,7 @@ class TransactionIntegrationTest { } val blockHeader = try { - IntegrationTestUtils.handleResult( + handleResult( accessAPI.getBlockHeaderByHeight(latestBlock.height), "Failed to get block header by height" ) @@ -304,7 +307,7 @@ class TransactionIntegrationTest { val address = FlowAddress("18eb4ee6b3c026d2") val account = try { - IntegrationTestUtils.handleResult( + handleResult( accessAPI.getAccountByBlockHeight(address, blockHeader.height), "Failed to get account by block height" ) diff --git a/sdk/src/intTest/org/onflow/flow/sdk/transaction/TransactionSigningTest.kt b/sdk/src/intTest/org/onflow/flow/sdk/transaction/TransactionSigningTest.kt index c84b891c..2fa5650e 100644 --- a/sdk/src/intTest/org/onflow/flow/sdk/transaction/TransactionSigningTest.kt +++ b/sdk/src/intTest/org/onflow/flow/sdk/transaction/TransactionSigningTest.kt @@ -1,16 +1,15 @@ package org.onflow.flow.sdk.transaction -import org.onflow.flow.sdk.FlowAccessApi -import org.onflow.flow.sdk.FlowAddress -import org.onflow.flow.sdk.IntegrationTestUtils.transaction -import org.onflow.flow.sdk.bytesToHex import org.onflow.flow.sdk.crypto.Crypto -import org.onflow.flow.sdk.simpleFlowTransaction import org.onflow.flow.sdk.test.FlowEmulatorTest import org.onflow.flow.sdk.test.FlowServiceAccountCredentials import org.onflow.flow.sdk.test.FlowTestClient import org.onflow.flow.sdk.test.TestAccount import org.junit.jupiter.api.Test +import org.onflow.flow.sdk.* +import org.onflow.flow.sdk.IntegrationTestUtils.loadScript +import org.onflow.flow.sdk.IntegrationTestUtils.transaction +import java.nio.charset.StandardCharsets import kotlin.random.Random @FlowEmulatorTest @@ -46,15 +45,10 @@ class TransactionSigningTest { @Test fun `Byte arrays are properly handled`() { + val loadedScript = String(loadScript("cadence/transaction_signing/transaction_signing_byte_arrays.cdc"), StandardCharsets.UTF_8) accessAPI.simpleFlowTransaction(serviceAccount.flowAddress, serviceAccount.signer) { script { - """ - transaction(bytes: [UInt8]) { - prepare(signer: AuthAccount) { - log(bytes) - } - } - """.trimIndent() + loadedScript } arguments { arg { byteArray(Random.nextBytes(2048)) } diff --git a/sdk/src/intTest/resources/cadence/expose_account_key_issue/expose_account_key_issue_1.cdc b/sdk/src/intTest/resources/cadence/expose_account_key_issue/expose_account_key_issue_1.cdc new file mode 100644 index 00000000..bfbbc3a0 --- /dev/null +++ b/sdk/src/intTest/resources/cadence/expose_account_key_issue/expose_account_key_issue_1.cdc @@ -0,0 +1,29 @@ +import FlowToken from 0xFLOWTOKEN +import FungibleToken from 0xFUNGIBLETOKEN + +transaction(startingBalance: UFix64, publicKey: String, signatureAlgorithm: UInt8, hashAlgorithm: UInt8) { + prepare(signer: AuthAccount) { + + let newAccount = AuthAccount(payer: signer) + + newAccount.keys.add( + publicKey: PublicKey( + publicKey: publicKey.decodeHex(), + signatureAlgorithm: SignatureAlgorithm(rawValue: signatureAlgorithm)! + ), + hashAlgorithm: HashAlgorithm(rawValue: hashAlgorithm)!, + weight: UFix64(1000) + ) + + let provider = signer.borrow<&FlowToken.Vault>(from: /storage/flowTokenVault) + ?? panic("Could not borrow FlowToken.Vault reference") + + let newVault = newAccount + .getCapability(/public/flowTokenReceiver) + .borrow<&{FungibleToken.Receiver}>() + ?? panic("Could not borrow FungibleToken.Receiver reference") + + let coin <- provider.withdraw(amount: startingBalance) + newVault.deposit(from: <- coin) + } +} \ No newline at end of file diff --git a/sdk/src/intTest/resources/cadence/expose_account_key_issue/expose_account_key_issue_2.cdc b/sdk/src/intTest/resources/cadence/expose_account_key_issue/expose_account_key_issue_2.cdc new file mode 100644 index 00000000..4bed02b4 --- /dev/null +++ b/sdk/src/intTest/resources/cadence/expose_account_key_issue/expose_account_key_issue_2.cdc @@ -0,0 +1,12 @@ +transaction(publicKey: String, signatureAlgorithm: UInt8, hashAlgorithm: UInt8, weight: UFix64) { + prepare(signer: AuthAccount) { + signer.keys.add( + publicKey: PublicKey( + publicKey: publicKey.decodeHex(), + signatureAlgorithm: SignatureAlgorithm(rawValue: signatureAlgorithm)! + ), + hashAlgorithm: HashAlgorithm(rawValue: hashAlgorithm)!, + weight: weight + ) + } +} \ No newline at end of file diff --git a/sdk/src/intTest/resources/cadence/expose_account_key_issue/expose_account_key_issue_3.cdc b/sdk/src/intTest/resources/cadence/expose_account_key_issue/expose_account_key_issue_3.cdc new file mode 100644 index 00000000..f20fcd34 --- /dev/null +++ b/sdk/src/intTest/resources/cadence/expose_account_key_issue/expose_account_key_issue_3.cdc @@ -0,0 +1,5 @@ +transaction(index: Int) { + prepare(signer: AuthAccount) { + signer.keys.revoke(keyIndex: index) ?? panic("Key not found to revoke") + } +} \ No newline at end of file diff --git a/sdk/src/intTest/resources/cadence/json_cadence/decode_array.cdc b/sdk/src/intTest/resources/cadence/json_cadence/decode_array.cdc new file mode 100644 index 00000000..ae557cd5 --- /dev/null +++ b/sdk/src/intTest/resources/cadence/json_cadence/decode_array.cdc @@ -0,0 +1,3 @@ +pub fun main(): [UInt64] { + return [1,3,4,5] +} \ No newline at end of file diff --git a/sdk/src/intTest/resources/cadence/json_cadence/decode_boolean.cdc b/sdk/src/intTest/resources/cadence/json_cadence/decode_boolean.cdc new file mode 100644 index 00000000..3a14b6a5 --- /dev/null +++ b/sdk/src/intTest/resources/cadence/json_cadence/decode_boolean.cdc @@ -0,0 +1,3 @@ +pub fun main(): Bool { + return true +} \ No newline at end of file diff --git a/sdk/src/intTest/resources/cadence/json_cadence/decode_complex_dict.cdc b/sdk/src/intTest/resources/cadence/json_cadence/decode_complex_dict.cdc new file mode 100644 index 00000000..b7c67f48 --- /dev/null +++ b/sdk/src/intTest/resources/cadence/json_cadence/decode_complex_dict.cdc @@ -0,0 +1,31 @@ +pub struct StorageInfo { + pub let capacity: UInt64 + pub let used: UInt64 + pub let available: UInt64 + pub let foo: Foo + + init(capacity: UInt64, used: UInt64, available: UInt64, foo: Foo) { + self.capacity = capacity + self.used = used + self.available = available + self.foo = foo + } +} + +pub struct Foo { + pub let bar: Int + + init(bar: Int) { + self.bar = bar + } +} + +pub fun main(addr: Address): {String: [StorageInfo]} { + let acct = getAccount(addr) + + let foo = Foo(bar: 1) + return {"test": [StorageInfo(capacity: acct.storageCapacity, + used: acct.storageUsed, + available: acct.storageCapacity - acct.storageUsed, + foo: foo)]} +} \ No newline at end of file diff --git a/sdk/src/intTest/resources/cadence/json_cadence/decode_enum.cdc b/sdk/src/intTest/resources/cadence/json_cadence/decode_enum.cdc new file mode 100644 index 00000000..8e95e64a --- /dev/null +++ b/sdk/src/intTest/resources/cadence/json_cadence/decode_enum.cdc @@ -0,0 +1,9 @@ +pub enum Color: UInt8 { + pub case red + pub case green + pub case blue +} + +pub fun main() : Color { + return Color.red +} \ No newline at end of file diff --git a/sdk/src/intTest/resources/cadence/json_cadence/decode_optional.cdc b/sdk/src/intTest/resources/cadence/json_cadence/decode_optional.cdc new file mode 100644 index 00000000..e1af1714 --- /dev/null +++ b/sdk/src/intTest/resources/cadence/json_cadence/decode_optional.cdc @@ -0,0 +1,3 @@ +pub fun main(): Bool? { + return nil +} \ No newline at end of file diff --git a/sdk/src/intTest/resources/cadence/json_cadence/decode_optional_2.cdc b/sdk/src/intTest/resources/cadence/json_cadence/decode_optional_2.cdc new file mode 100644 index 00000000..89bfb544 --- /dev/null +++ b/sdk/src/intTest/resources/cadence/json_cadence/decode_optional_2.cdc @@ -0,0 +1,3 @@ +pub fun main(): Bool? { + return true +} \ No newline at end of file diff --git a/sdk/src/intTest/resources/cadence/json_cadence/decode_reference.cdc b/sdk/src/intTest/resources/cadence/json_cadence/decode_reference.cdc new file mode 100644 index 00000000..dc3439f5 --- /dev/null +++ b/sdk/src/intTest/resources/cadence/json_cadence/decode_reference.cdc @@ -0,0 +1,6 @@ +pub let hello = "Hello" +pub let helloRef: &String = &hello as &String + +pub fun main(): &String { + return helloRef +} \ No newline at end of file diff --git a/sdk/src/intTest/resources/cadence/json_cadence/decode_resource.cdc b/sdk/src/intTest/resources/cadence/json_cadence/decode_resource.cdc new file mode 100644 index 00000000..6aa2825a --- /dev/null +++ b/sdk/src/intTest/resources/cadence/json_cadence/decode_resource.cdc @@ -0,0 +1,12 @@ +pub resource SomeResource { + pub var value: Int + + init(value: Int) { + self.value = value + } +} + +pub fun main(): @SomeResource { + let newResource <- create SomeResource(value: 20) + return <-newResource +} \ No newline at end of file diff --git a/sdk/src/intTest/resources/cadence/json_cadence/decode_struct.cdc b/sdk/src/intTest/resources/cadence/json_cadence/decode_struct.cdc new file mode 100644 index 00000000..24cfef4b --- /dev/null +++ b/sdk/src/intTest/resources/cadence/json_cadence/decode_struct.cdc @@ -0,0 +1,16 @@ +pub struct StorageInfo { + pub let capacity: Int + pub let used: Int + pub let available: Int + + init(capacity: Int, used: Int, available: Int) { + self.capacity = capacity + self.used = used + self.available = available + } +} + +pub fun main(addr: Address): [StorageInfo] { + let acct = getAccount(addr) + return [StorageInfo(capacity: 1, used: 2, available: 3)] +} \ No newline at end of file diff --git a/sdk/src/intTest/resources/cadence/json_cadence/decode_ufix64.cdc b/sdk/src/intTest/resources/cadence/json_cadence/decode_ufix64.cdc new file mode 100644 index 00000000..2e3dabe1 --- /dev/null +++ b/sdk/src/intTest/resources/cadence/json_cadence/decode_ufix64.cdc @@ -0,0 +1,3 @@ +pub fun main(): UFix64 { + return 0.789111 +} \ No newline at end of file diff --git a/sdk/src/intTest/resources/cadence/test_extensions/ContractInterface.cdc b/sdk/src/intTest/resources/cadence/test_extensions/ContractInterface.cdc new file mode 100644 index 00000000..a0de7f77 --- /dev/null +++ b/sdk/src/intTest/resources/cadence/test_extensions/ContractInterface.cdc @@ -0,0 +1 @@ +pub contract interface ContractInterface { } \ No newline at end of file diff --git a/sdk/src/intTest/resources/cadence/test_extensions/ContractSuccessor.cdc b/sdk/src/intTest/resources/cadence/test_extensions/ContractSuccessor.cdc new file mode 100644 index 00000000..059fc9f3 --- /dev/null +++ b/sdk/src/intTest/resources/cadence/test_extensions/ContractSuccessor.cdc @@ -0,0 +1,2 @@ +import ContractInterface from 0xCONTRACTINTERFACE +pub contract ContractSuccessor : ContractInterface { init() { } } \ No newline at end of file diff --git a/sdk/src/intTest/resources/cadence/test_extensions/EmptyContract.cdc b/sdk/src/intTest/resources/cadence/test_extensions/EmptyContract.cdc new file mode 100644 index 00000000..4db1fce6 --- /dev/null +++ b/sdk/src/intTest/resources/cadence/test_extensions/EmptyContract.cdc @@ -0,0 +1 @@ +pub contract EmptyContract { init() { } } \ No newline at end of file diff --git a/sdk/src/intTest/resources/cadence/NothingContract.cdc b/sdk/src/intTest/resources/cadence/test_extensions/NothingContract.cdc similarity index 100% rename from sdk/src/intTest/resources/cadence/NothingContract.cdc rename to sdk/src/intTest/resources/cadence/test_extensions/NothingContract.cdc diff --git a/sdk/src/intTest/resources/cadence/test_utils_create_account.cdc b/sdk/src/intTest/resources/cadence/test_utils_create_account.cdc new file mode 100644 index 00000000..7443f8fc --- /dev/null +++ b/sdk/src/intTest/resources/cadence/test_utils_create_account.cdc @@ -0,0 +1,29 @@ +import FlowToken from 0xFLOWTOKEN +import FungibleToken from 0xFUNGIBLETOKEN + +transaction(startingBalance: UFix64, publicKey: String, signatureAlgorithm: UInt8, hashAlgorithm: UInt8) { + prepare(signer: AuthAccount) { + + let newAccount = AuthAccount(payer: signer) + + let provider = signer.borrow<&FlowToken.Vault>(from: /storage/flowTokenVault) + ?? panic("Could not borrow FlowToken.Vault reference") + + let newVault = newAccount + .getCapability(/public/flowTokenReceiver) + .borrow<&{FungibleToken.Receiver}>() + ?? panic("Could not borrow FungibleToken.Receiver reference") + + let coin <- provider.withdraw(amount: startingBalance) + newVault.deposit(from: <- coin) + + newAccount.keys.add( + publicKey: PublicKey( + publicKey: publicKey.decodeHex(), + signatureAlgorithm: SignatureAlgorithm(rawValue: signatureAlgorithm)! + ), + hashAlgorithm: HashAlgorithm(rawValue: hashAlgorithm)!, + weight: UFix64(1000) + ) + } +} \ No newline at end of file diff --git a/sdk/src/intTest/resources/cadence/transaction_creation/transaction_creation.cdc b/sdk/src/intTest/resources/cadence/transaction_creation/transaction_creation.cdc new file mode 100644 index 00000000..416f7b58 --- /dev/null +++ b/sdk/src/intTest/resources/cadence/transaction_creation/transaction_creation.cdc @@ -0,0 +1,6 @@ +transaction(publicKey: String) { + prepare(signer: AuthAccount) { + let account = AuthAccount(payer: signer) + account.addPublicKey(publicKey.decodeHex()) + } +} \ No newline at end of file diff --git a/sdk/src/intTest/resources/cadence/transaction_creation/transaction_creation_simple_transaction.cdc b/sdk/src/intTest/resources/cadence/transaction_creation/transaction_creation_simple_transaction.cdc new file mode 100644 index 00000000..416f7b58 --- /dev/null +++ b/sdk/src/intTest/resources/cadence/transaction_creation/transaction_creation_simple_transaction.cdc @@ -0,0 +1,6 @@ +transaction(publicKey: String) { + prepare(signer: AuthAccount) { + let account = AuthAccount(payer: signer) + account.addPublicKey(publicKey.decodeHex()) + } +} \ No newline at end of file diff --git a/sdk/src/intTest/resources/cadence/transaction_decoding/transaction_decoding_precompute_txid.cdc b/sdk/src/intTest/resources/cadence/transaction_decoding/transaction_decoding_precompute_txid.cdc new file mode 100644 index 00000000..ebf9f800 --- /dev/null +++ b/sdk/src/intTest/resources/cadence/transaction_decoding/transaction_decoding_precompute_txid.cdc @@ -0,0 +1 @@ +transaction { execute { log("Hello, World!") } } \ No newline at end of file diff --git a/sdk/src/intTest/resources/cadence/transaction_signing/transaction_signing_byte_arrays.cdc b/sdk/src/intTest/resources/cadence/transaction_signing/transaction_signing_byte_arrays.cdc new file mode 100644 index 00000000..e10f0f9d --- /dev/null +++ b/sdk/src/intTest/resources/cadence/transaction_signing/transaction_signing_byte_arrays.cdc @@ -0,0 +1,5 @@ +transaction(bytes: [UInt8]) { + prepare(signer: AuthAccount) { + log(bytes) + } +} \ No newline at end of file diff --git a/sdk/src/test/kotlin/org/onflow/flow/sdk/ScriptTest.kt b/sdk/src/test/kotlin/org/onflow/flow/sdk/ScriptTest.kt index 7352a58b..399dd915 100644 --- a/sdk/src/test/kotlin/org/onflow/flow/sdk/ScriptTest.kt +++ b/sdk/src/test/kotlin/org/onflow/flow/sdk/ScriptTest.kt @@ -7,7 +7,9 @@ import org.onflow.flow.sdk.test.FlowTestClient import org.junit.jupiter.api.Assertions.assertEquals import org.junit.jupiter.api.Assertions.assertTrue import org.junit.jupiter.api.Test +import org.onflow.flow.sdk.TestUtils.loadScript import java.math.BigDecimal +import java.nio.charset.StandardCharsets @JsonCadenceConversion(TestClassConverterJson::class) open class TestClass( @@ -50,13 +52,10 @@ class ScriptTest { @Test fun `Can execute a script`() { + val loadedScript = String(loadScript("cadence/hello_world.cdc"), StandardCharsets.UTF_8) val result = accessAPI.simpleFlowScript { script { - """ - pub fun main(): String { - return "Hello World" - } - """ + loadedScript } } @@ -76,33 +75,11 @@ class ScriptTest { @Test fun `Can input and export arguments`() { val address = "e467b9dd11fa00df" + val loadedScript = String(loadScript("cadence/import_export_arguments.cdc"), StandardCharsets.UTF_8) val result = accessAPI.simpleFlowScript { script { - """ - pub struct TestClass { - pub let address: Address - pub let balance: UFix64 - pub let hashAlgorithm: HashAlgorithm - pub let isValid: Bool - - init(address: Address, balance: UFix64, hashAlgorithm: HashAlgorithm, isValid: Bool) { - self.address = address - self.balance = balance - self.hashAlgorithm = hashAlgorithm - self.isValid = isValid - } - } - - pub fun main(address: Address): TestClass { - return TestClass( - address: address, - balance: UFix64(1234), - hashAlgorithm: HashAlgorithm.SHA3_256, - isValid: true - ) - } - """ + loadedScript } arg { address(address) } } @@ -159,51 +136,11 @@ class ScriptTest { ) } } + val loadedScript = String(loadScript("cadence/domain_tags.cdc"), StandardCharsets.UTF_8) val result = accessAPI.simpleFlowScript { script { - """ - import Crypto - - pub fun main( - rawPublicKeys: [String], - weights: [UFix64], - signatures: [String], - message: String, - ): Bool { - - var i = 0 - let keyList = Crypto.KeyList() - for rawPublicKey in rawPublicKeys { - keyList.add( - PublicKey( - publicKey: rawPublicKey.decodeHex(), - signatureAlgorithm: SignatureAlgorithm.ECDSA_P256 - ), - hashAlgorithm: HashAlgorithm.SHA3_256, - weight: weights[i], - ) - i = i + 1 - } - - i = 0 - let signatureSet: [Crypto.KeyListSignature] = [] - for signature in signatures { - signatureSet.append( - Crypto.KeyListSignature( - keyIndex: i, - signature: signature.decodeHex() - ) - ) - i = i + 1 - } - - return keyList.verify( - signatureSet: signatureSet, - signedData: message.decodeHex(), - ) - } - """ + loadedScript } arg { publicKeys } arg { weights } diff --git a/sdk/src/test/kotlin/org/onflow/flow/sdk/TestUtils.kt b/sdk/src/test/kotlin/org/onflow/flow/sdk/TestUtils.kt index 53133c9a..0fcd723f 100644 --- a/sdk/src/test/kotlin/org/onflow/flow/sdk/TestUtils.kt +++ b/sdk/src/test/kotlin/org/onflow/flow/sdk/TestUtils.kt @@ -7,4 +7,6 @@ object TestUtils { private const val MAINNET_HOSTNAME = "access.mainnet.nodes.onflow.org" private const val TESTNET_HOSTNAME = "access.devnet.nodes.onflow.org" + + fun loadScript(name: String): ByteArray = javaClass.classLoader.getResourceAsStream(name)!!.use { it.readAllBytes() } } diff --git a/sdk/src/test/resources/cadence/domain_tags.cdc b/sdk/src/test/resources/cadence/domain_tags.cdc new file mode 100644 index 00000000..8ce05603 --- /dev/null +++ b/sdk/src/test/resources/cadence/domain_tags.cdc @@ -0,0 +1,40 @@ +import Crypto + +pub fun main( + rawPublicKeys: [String], + weights: [UFix64], + signatures: [String], + message: String, +): Bool { + + var i = 0 + let keyList = Crypto.KeyList() + for rawPublicKey in rawPublicKeys { + keyList.add( + PublicKey( + publicKey: rawPublicKey.decodeHex(), + signatureAlgorithm: SignatureAlgorithm.ECDSA_P256 + ), + hashAlgorithm: HashAlgorithm.SHA3_256, + weight: weights[i], + ) + i = i + 1 + } + + i = 0 + let signatureSet: [Crypto.KeyListSignature] = [] + for signature in signatures { + signatureSet.append( + Crypto.KeyListSignature( + keyIndex: i, + signature: signature.decodeHex() + ) + ) + i = i + 1 + } + + return keyList.verify( + signatureSet: signatureSet, + signedData: message.decodeHex(), + ) +} \ No newline at end of file diff --git a/sdk/src/test/resources/cadence/hello_world.cdc b/sdk/src/test/resources/cadence/hello_world.cdc new file mode 100644 index 00000000..1ceec420 --- /dev/null +++ b/sdk/src/test/resources/cadence/hello_world.cdc @@ -0,0 +1,3 @@ +pub fun main(): String { + return "Hello World" + } \ No newline at end of file diff --git a/sdk/src/test/resources/cadence/import_export_arguments.cdc b/sdk/src/test/resources/cadence/import_export_arguments.cdc new file mode 100644 index 00000000..be2ccfa8 --- /dev/null +++ b/sdk/src/test/resources/cadence/import_export_arguments.cdc @@ -0,0 +1,22 @@ +pub struct TestClass { + pub let address: Address + pub let balance: UFix64 + pub let hashAlgorithm: HashAlgorithm + pub let isValid: Bool + + init(address: Address, balance: UFix64, hashAlgorithm: HashAlgorithm, isValid: Bool) { + self.address = address + self.balance = balance + self.hashAlgorithm = hashAlgorithm + self.isValid = isValid + } +} + +pub fun main(address: Address): TestClass { + return TestClass( + address: address, + balance: UFix64(1234), + hashAlgorithm: HashAlgorithm.SHA3_256, + isValid: true + ) +} \ No newline at end of file diff --git a/sdk/src/testFixtures/kotlin/org/onflow/flow/sdk/test/FlowTestUtil.kt b/sdk/src/testFixtures/kotlin/org/onflow/flow/sdk/test/FlowTestUtil.kt index 862d3d18..8a19359d 100644 --- a/sdk/src/testFixtures/kotlin/org/onflow/flow/sdk/test/FlowTestUtil.kt +++ b/sdk/src/testFixtures/kotlin/org/onflow/flow/sdk/test/FlowTestUtil.kt @@ -7,9 +7,16 @@ import org.onflow.flow.sdk.impl.FlowAccessApiImpl import java.io.File import java.io.IOException import java.math.BigDecimal +import java.nio.charset.StandardCharsets import kotlin.io.path.createTempDirectory object FlowTestUtil { + private fun loadScript(name: String): ByteArray { + val resource = javaClass.classLoader.getResourceAsStream(name) + ?: throw IllegalArgumentException("Script file $name not found") + return resource.use { it.readAllBytes() } + } + @JvmStatic @JvmOverloads fun deployContracts( @@ -76,43 +83,14 @@ object FlowTestUtil { hashAlgo: HashAlgorithm, balance: BigDecimal = BigDecimal(0.01) ): FlowAccessApi.AccessApiCallResponse { + val loadedScript = String(loadScript("cadence/test_utils_create_account.cdc"), StandardCharsets.UTF_8) val transactionResult = api.simpleFlowTransaction( address = serviceAccount.flowAddress, signer = serviceAccount.signer, keyIndex = serviceAccount.keyIndex ) { script { - """ - import FlowToken from 0xFLOWTOKEN - import FungibleToken from 0xFUNGIBLETOKEN - - transaction(startingBalance: UFix64, publicKey: String, signatureAlgorithm: UInt8, hashAlgorithm: UInt8) { - prepare(signer: AuthAccount) { - - let newAccount = AuthAccount(payer: signer) - - let provider = signer.borrow<&FlowToken.Vault>(from: /storage/flowTokenVault) - ?? panic("Could not borrow FlowToken.Vault reference") - - let newVault = newAccount - .getCapability(/public/flowTokenReceiver) - .borrow<&{FungibleToken.Receiver}>() - ?? panic("Could not borrow FungibleToken.Receiver reference") - - let coin <- provider.withdraw(amount: startingBalance) - newVault.deposit(from: <- coin) - - newAccount.keys.add( - publicKey: PublicKey( - publicKey: publicKey.decodeHex(), - signatureAlgorithm: SignatureAlgorithm(rawValue: signatureAlgorithm)! - ), - hashAlgorithm: HashAlgorithm(rawValue: hashAlgorithm)!, - weight: UFix64(1000) - ) - } - } - """ + loadedScript } gasLimit(1000) arguments {