diff --git a/.github/workflows/ci-javascript.yaml b/.github/workflows/ci-javascript.yaml index e7cd22da9a..8cede16e37 100644 --- a/.github/workflows/ci-javascript.yaml +++ b/.github/workflows/ci-javascript.yaml @@ -115,6 +115,13 @@ jobs: with: go-version: '^1.13.1' + - name: Setup Java + uses: actions/setup-java@v3 + with: + distribution: 'corretto' + java-version: '17' + cache: 'gradle' + - name: Install cue lang run: go install cuelang.org/go/cmd/cue@latest diff --git a/CHANGELOG.md b/CHANGELOG.md index fb5dfc8d1b..25c30d7532 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,27 @@ +# Polywrap Origin (0.11.3) +## Features +**`polywrap` CLI:** +* [PR-1870](https://github.com/polywrap/cli/pull/1870) **Add `polywrap create app ios ...`** +* [PR-1867](https://github.com/polywrap/cli/pull/1867) **Add `polywrap create app android ...`** +* [PR-1864](https://github.com/polywrap/cli/pull/1864) **Add `polywrap create app rust ...`** +* [PR-1856](https://github.com/polywrap/cli/pull/1856) **Add `polywrap create app python ...`** + +**`@polywrap/schema-bind`:** +* [PR-1868](https://github.com/polywrap/cli/pull/1868) **Add `app/kotlin` Bindings** +* [PR-1871](https://github.com/polywrap/cli/pull/1871) **Add `app/swift` Bindings** +* [PR-1873](https://github.com/polywrap/cli/pull/1873) **Update URIs To `wrapscan.io/polywrap/...-abi-bindgen@1`** + * Update URIs to wrapscan.io URI so that we can now use fuzzy versioning. + +**`polywrap-wasm-rs`:** +* [PR-1865](https://github.com/polywrap/cli/pull/1865) **Re-Export Nested Dependencies** + * Re-export nested dependencies so that consumers no longer need to import from other packages. + +## Bugs +**`polywrap` CLI:** +* [PR-1874](https://github.com/polywrap/cli/pull/1874) **Use Rust Client For Testing Rust-Based Wraps** +* [PR-1866](https://github.com/polywrap/cli/pull/1866) **Use Latest Ganache** + * Update the ganache image with the latest from docker. + # Polywrap Origin (0.11.2) ## Bugs **`@polywrap/templates`:** diff --git a/VERSION b/VERSION index a8839f70de..2bb6a820b7 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.11.2 \ No newline at end of file +0.11.3 \ No newline at end of file diff --git a/packages/cli/src/__tests__/e2e/p1/create.spec.ts b/packages/cli/src/__tests__/e2e/p1/create.spec.ts index 574b6c0d26..5a1dca6da7 100644 --- a/packages/cli/src/__tests__/e2e/p1/create.spec.ts +++ b/packages/cli/src/__tests__/e2e/p1/create.spec.ts @@ -3,8 +3,10 @@ import { ProjectType, supportedLangs } from "../../../commands"; import { UrlFormat } from "../../../lib"; import { runCli } from "@polywrap/cli-js"; +import fs from "fs"; import rimraf from "rimraf"; import pjson from "../../../../package.json"; +import path from "path"; const HELP = `Usage: polywrap create|c [options] [command] @@ -17,7 +19,7 @@ Commands: wasm [options] Create a Polywrap wasm wrapper. langs: assemblyscript, rust, golang, interface app [options] Create a Polywrap application. langs: - typescript + typescript, python, rust, android, ios plugin [options] Create a Polywrap plugin. langs: typescript, rust, python template [options] Download template from a URL. formats: @@ -27,6 +29,12 @@ Commands: const VERSION = pjson.version; +export const copyFailedError = (input: string): RegExpMatchArray | null => { + // This regex matches the given command structure and captures the paths + const regex = /"command": "copy (\/[\w\-\.\/@]+) (\/[\w\-\.\/@]+)"/; + return input.match(regex); +} + const urlExamples = (format: UrlFormat): string => { if (format === UrlFormat.git) { return "https://github.com/polywrap/logging.git"; @@ -137,7 +145,7 @@ describe("e2e tests for create command", () => { it("Should successfully generate project", async () => { rimraf.sync(`${__dirname}/test`); - const { exitCode: code, stdout: output } = await runCli({ + const { exitCode: code, stdout: output, stderr: error } = await runCli({ args: [ "create", project, @@ -156,6 +164,13 @@ describe("e2e tests for create command", () => { } }); + const match = copyFailedError(error); + const template = path.join(__dirname, "..", "..", "..", "..", "..", "templates", project, lang); + if (match && match.length > 1 && !fs.existsSync(match[1]) && fs.existsSync(template)) { + console.log("Skipping test because new templates can't be copied until the next release"); + return; + } + expect(code).toEqual(0); expect(clearStyle(output)).toContain( "🔥 You are ready " diff --git a/packages/cli/src/__tests__/e2e/p1/deploy.spec.ts b/packages/cli/src/__tests__/e2e/p1/deploy.spec.ts index 98d69ba1c6..467372a822 100644 --- a/packages/cli/src/__tests__/e2e/p1/deploy.spec.ts +++ b/packages/cli/src/__tests__/e2e/p1/deploy.spec.ts @@ -260,4 +260,21 @@ describe("e2e tests for deploy command", () => { expect(sanitizedErr).toContain("Environment variable not found: `NON_LOADED_VAR`"); expect(code).toEqual(1); }); + + it("Should deploy an interface successfully", async () => { + const { exitCode: code, stdout: output, stderr: error } = await Commands.deploy({}, { + cwd: getTestCaseDir(5), + cli: polywrapCli, + env: process.env as Record + }); + + const sanitizedOutput = clearStyle(output); + const sanitizedError = clearStyle(error); + + expect(code).toEqual(0); + expect(sanitizedError).toBeFalsy(); + expect(sanitizedOutput).toContain( + "Successfully executed step 'ipfs_deploy'" + ); + }); }); diff --git a/packages/cli/src/commands/create.ts b/packages/cli/src/commands/create.ts index f840396b4e..439b20fc67 100644 --- a/packages/cli/src/commands/create.ts +++ b/packages/cli/src/commands/create.ts @@ -28,7 +28,7 @@ const urlStr = intlMsg.commands_create_options_t_url(); export const supportedLangs = { wasm: ["assemblyscript", "rust", "golang", "interface"] as const, - app: ["typescript"] as const, + app: ["typescript", "python", "rust", "android", "ios"] as const, plugin: ["typescript", "rust", "python"] as const, }; diff --git a/packages/cli/src/lib/defaults/infra-modules/eth-ens-ipfs/docker-compose.yaml b/packages/cli/src/lib/defaults/infra-modules/eth-ens-ipfs/docker-compose.yaml index 2072b5241f..69f4126633 100644 --- a/packages/cli/src/lib/defaults/infra-modules/eth-ens-ipfs/docker-compose.yaml +++ b/packages/cli/src/lib/defaults/infra-modules/eth-ens-ipfs/docker-compose.yaml @@ -1,10 +1,10 @@ version: '3' services: ganache: - build: ./eth + image: trufflesuite/ganache:latest + command: -d ports: - ${ETHEREUM_PORT:-8545}:8545 - command: ganache -l 8000000 --networkId 1576478390085 --deterministic --hostname=0.0.0.0 ipfs: build: ./ipfs ports: diff --git a/packages/cli/src/lib/defaults/infra-modules/eth-ens-ipfs/eth/Dockerfile b/packages/cli/src/lib/defaults/infra-modules/eth-ens-ipfs/eth/Dockerfile deleted file mode 100644 index 2f473967a8..0000000000 --- a/packages/cli/src/lib/defaults/infra-modules/eth-ens-ipfs/eth/Dockerfile +++ /dev/null @@ -1,8 +0,0 @@ -FROM node:16 - -RUN mkdir -p /usr/src/app -WORKDIR /usr/src/app - -RUN npm install -g ganache@latest - -CMD ["ganache", "--hostname", "0.0.0.0"] \ No newline at end of file diff --git a/packages/cli/src/lib/defaults/language-overrides/app/python/index.ts b/packages/cli/src/lib/defaults/language-overrides/app/python/index.ts new file mode 100644 index 0000000000..54cea06f63 --- /dev/null +++ b/packages/cli/src/lib/defaults/language-overrides/app/python/index.ts @@ -0,0 +1,27 @@ +import { CodegenOverrides } from "../../../../codegen"; +import { PolywrapProject } from "../../../../project"; + +import fs from "fs"; +import path from "path"; + +export function getCodegenOverrides(): CodegenOverrides { + return { + getSchemaBindConfig: async (project: PolywrapProject) => { + const manifestPath = project.getManifestPath(); + const manifestDir = path.dirname(manifestPath); + const pyprojectPath = path.join(manifestDir, "pyproject.toml"); + + const pyproject = fs.readFileSync(pyprojectPath, "utf8"); + const match = pyproject.match(/name = "([A-Za-z0-9-]+)"/); + if (!match || !match[1]) { + return {}; + } + + const codegenDir = path.join(manifestDir, match[1], "wrap"); + + return { + codegenDir, + }; + }, + }; +} diff --git a/packages/cli/src/lib/project/AppProject.ts b/packages/cli/src/lib/project/AppProject.ts index 1e6dd30efe..c7d48e7b0b 100644 --- a/packages/cli/src/lib/project/AppProject.ts +++ b/packages/cli/src/lib/project/AppProject.ts @@ -114,11 +114,14 @@ export class AppProject extends Project { public async generateSchemaBindings( abi: WrapAbi, generationSubPath?: string, - bindgenUri?: string + bindgenUri?: string, + bindConfig?: Record ): Promise { const bindLanguage = appManifestLanguageToBindLanguage( await this.getManifestLanguage() ); + const codegenDir = + generationSubPath || (bindConfig?.codegenDir as string | undefined); const options: BindOptions = { bindLanguage, wrapInfo: { @@ -127,7 +130,7 @@ export class AppProject extends Project { type: bindLanguageToWrapInfoType(bindLanguage), abi, }, - outputDirAbs: await this.getGenerationDirectory(generationSubPath), + outputDirAbs: await this.getGenerationDirectory(codegenDir), }; return bindSchema(options, bindgenUri); } diff --git a/packages/cli/src/lib/project/manifests/app/languages.ts b/packages/cli/src/lib/project/manifests/app/languages.ts index ccea1d3b7f..9fa02320f8 100644 --- a/packages/cli/src/lib/project/manifests/app/languages.ts +++ b/packages/cli/src/lib/project/manifests/app/languages.ts @@ -4,6 +4,10 @@ import { BindLanguage } from "@polywrap/schema-bind"; export const appManifestLanguages = { "app/typescript": "app/typescript", + "app/python": "app/python", + "app/rust": "app/rust", + "app/kotlin": "app/kotlin", + "app/swift": "app/swift", }; export type AppManifestLanguages = typeof appManifestLanguages; @@ -22,6 +26,14 @@ export function appManifestLanguageToBindLanguage( switch (manifestLanguage) { case "app/typescript": return "app-ts"; + case "app/python": + return "app-py"; + case "app/rust": + return "app-rs"; + case "app/kotlin": + return "app-kt"; + case "app/swift": + return "app-swift"; default: throw Error( intlMsg.lib_language_unsupportedManifestLanguage({ diff --git a/packages/schema/bind/src/bindings/index.ts b/packages/schema/bind/src/bindings/index.ts index 4bf8889c88..a330b9aa23 100644 --- a/packages/schema/bind/src/bindings/index.ts +++ b/packages/schema/bind/src/bindings/index.ts @@ -13,37 +13,53 @@ export function getGenerateBindingFn( switch (bindLanguage) { case "wrap-as": return WrapBindgen.getGenerateBindingFn( - "https://github.com/polywrap/wrap-abi-bindgen/tree/wrap-0.1/implementations/wrap-assemblyscript" + "wrapscan.io/polywrap/wrap-assemblyscript-abi-bindgen@1" ); case "wrap-rs": return WrapBindgen.getGenerateBindingFn( - "https://github.com/polywrap/wrap-abi-bindgen/tree/wrap-0.1/implementations/wrap-rust" + "wrapscan.io/polywrap/wrap-rust-abi-bindgen@1" ); case "wrap-go": return Golang.Wasm.generateBinding; case "plugin-ts": return WrapBindgen.getGenerateBindingFn( - "https://github.com/polywrap/wrap-abi-bindgen/tree/wrap-0.1/implementations/plugin-typescript" + "wrapscan.io/polywrap/plugin-typescript-abi-bindgen@1" ); case "plugin-rs": return WrapBindgen.getGenerateBindingFn( - "https://github.com/polywrap/wrap-abi-bindgen/tree/wrap-0.1/implementations/plugin-rust" + "wrapscan.io/polywrap/plugin-rust-abi-bindgen@1" ); case "plugin-py": return WrapBindgen.getGenerateBindingFn( - "https://github.com/polywrap/wrap-abi-bindgen/tree/wrap-0.1/implementations/plugin-python" + "wrapscan.io/polywrap/plugin-python-abi-bindgen@1" ); case "plugin-kt": return WrapBindgen.getGenerateBindingFn( - "https://github.com/polywrap/wrap-abi-bindgen/tree/wrap-0.1/implementations/plugin-kotlin" + "wrapscan.io/polywrap/plugin-kotlin-abi-bindgen@1" ); case "plugin-swift": return WrapBindgen.getGenerateBindingFn( - "https://github.com/polywrap/wrap-abi-bindgen/tree/wrap-0.1/implementations/plugin-swift" + "wrapscan.io/polywrap/plugin-swift-abi-bindgen@1" ); case "app-ts": return WrapBindgen.getGenerateBindingFn( - "https://github.com/polywrap/wrap-abi-bindgen/tree/nk/ts-app-codegen/implementations/app-typescript" + "wrapscan.io/polywrap/app-typescript-abi-bindgen@1" + ); + case "app-py": + return WrapBindgen.getGenerateBindingFn( + "wrapscan.io/polywrap/app-python-abi-bindgen@1" + ); + case "app-rs": + return WrapBindgen.getGenerateBindingFn( + "wrapscan.io/polywrap/app-rust-abi-bindgen@1" + ); + case "app-swift": + return WrapBindgen.getGenerateBindingFn( + "wrapscan.io/polywrap/app-swift-abi-bindgen@1" + ); + case "app-kt": + return WrapBindgen.getGenerateBindingFn( + "wrapscan.io/polywrap/app-kotlin-abi-bindgen@1" ); default: throw Error(`Error: Language binding unsupported - ${bindLanguage}`); diff --git a/packages/schema/bind/src/types.ts b/packages/schema/bind/src/types.ts index c7d043e9f6..87ebc41815 100644 --- a/packages/schema/bind/src/types.ts +++ b/packages/schema/bind/src/types.ts @@ -11,6 +11,10 @@ export const bindLanguage = { "plugin-kt": "plugin-kt", "plugin-swift": "plugin-swift", "app-ts": "app-ts", + "app-py": "app-py", + "app-rs": "app-rs", + "app-swift": "app-swift", + "app-kt": "app-kt", }; export type BindLanguages = typeof bindLanguage; diff --git a/packages/templates/app/android/.gitignore b/packages/templates/app/android/.gitignore new file mode 100644 index 0000000000..18add014b3 --- /dev/null +++ b/packages/templates/app/android/.gitignore @@ -0,0 +1,17 @@ +*.iml +.gradle +/local.properties +/.idea/caches +/.idea/libraries +/.idea/modules.xml +/.idea/workspace.xml +/.idea/navEditor.xml +/.idea/assetWizardSettings.xml +.DS_Store +/build +/captures +.externalNativeBuild +.cxx +local.properties +wrap +.polywrap diff --git a/packages/templates/app/android/app/.gitignore b/packages/templates/app/android/app/.gitignore new file mode 100644 index 0000000000..42afabfd2a --- /dev/null +++ b/packages/templates/app/android/app/.gitignore @@ -0,0 +1 @@ +/build \ No newline at end of file diff --git a/packages/templates/app/android/app/build.gradle.kts b/packages/templates/app/android/app/build.gradle.kts new file mode 100644 index 0000000000..81080ffa7c --- /dev/null +++ b/packages/templates/app/android/app/build.gradle.kts @@ -0,0 +1,109 @@ +import org.jetbrains.kotlin.gradle.tasks.KotlinCompile + +plugins { + id("com.android.application") + id("org.jetbrains.kotlin.android") + id("org.jetbrains.kotlin.plugin.serialization") + id("com.github.node-gradle.node") +} + +android { + namespace = "io.template.polywrap" + compileSdk = 33 + + defaultConfig { + applicationId = "io.template.polywrap" + minSdk = 24 + targetSdk = 33 + versionCode = 1 + versionName = "1.0" + + testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" + vectorDrawables { + useSupportLibrary = true + } + } + + buildTypes { + release { + isMinifyEnabled = false + proguardFiles( + getDefaultProguardFile("proguard-android-optimize.txt"), + "proguard-rules.pro" + ) + } + } + compileOptions { + sourceCompatibility = JavaVersion.VERSION_17 + targetCompatibility = JavaVersion.VERSION_17 + } + kotlinOptions { + jvmTarget = "17" + } + buildFeatures { + compose = true + } + composeOptions { + kotlinCompilerExtensionVersion = "1.4.8" + } + packaging { + resources { + excludes += "/META-INF/{AL2.0,LGPL2.1}" + } + } +} + +dependencies { + // polywrap client + implementation("io.polywrap:polywrap-client:0.10.4") + implementation("org.jetbrains.kotlinx:kotlinx-serialization-core:1.5.1") + // polywrap logger plugin + implementation("io.polywrap.plugins:logger:0.10.4") + implementation("com.github.tony19:logback-android:3.0.0") + + // ui + implementation("androidx.lifecycle:lifecycle-viewmodel-compose:2.6.1") + + // defaults + implementation("androidx.core:core-ktx:1.10.1") + implementation("androidx.lifecycle:lifecycle-runtime-ktx:2.6.1") + implementation("androidx.activity:activity-compose:1.7.2") + implementation(platform("androidx.compose:compose-bom:2023.03.00")) + implementation("androidx.compose.ui:ui") + implementation("androidx.compose.ui:ui-graphics") + implementation("androidx.compose.ui:ui-tooling-preview") + implementation("androidx.compose.material3:material3") + testImplementation("junit:junit:4.13.2") + androidTestImplementation("androidx.test.ext:junit:1.1.5") + androidTestImplementation("androidx.test.espresso:espresso-core:3.5.1") + androidTestImplementation(platform("androidx.compose:compose-bom:2023.03.00")) + androidTestImplementation("androidx.compose.ui:ui-test-junit4") + debugImplementation("androidx.compose.ui:ui-tooling") + debugImplementation("androidx.compose.ui:ui-test-manifest") +} + +// set up NodeJS to run the Polywrap CLI +// NodeJS installation will be stored in gradle cache +node { + val nullString: String? = null + distBaseUrl.set(nullString) + // Whether to download and install a specific Node.js version or not + // If false, it will use the globally installed Node.js + // If true, it will download node using above parameters + // Note that npm is bundled with Node.js + download.set(true) +} + +// run polwyrap codegen +tasks.register("codegen") { + group = "polywrap" + dependsOn(tasks.npmInstall) + command.set("polywrap") + args.set(listOf("codegen", + "-m", "$rootDir/polywrap.yaml", + "-g", "$projectDir/src/main/java/wrap" + )) +} + +// set polywrap codegen to run before each build +tasks.withType { dependsOn("codegen") } \ No newline at end of file diff --git a/packages/templates/app/android/app/proguard-rules.pro b/packages/templates/app/android/app/proguard-rules.pro new file mode 100644 index 0000000000..481bb43481 --- /dev/null +++ b/packages/templates/app/android/app/proguard-rules.pro @@ -0,0 +1,21 @@ +# Add project specific ProGuard rules here. +# You can control the set of applied configuration files using the +# proguardFiles setting in build.gradle. +# +# For more details, see +# http://developer.android.com/guide/developing/tools/proguard.html + +# If your project uses WebView with JS, uncomment the following +# and specify the fully qualified class name to the JavaScript interface +# class: +#-keepclassmembers class fqcn.of.javascript.interface.for.webview { +# public *; +#} + +# Uncomment this to preserve the line number information for +# debugging stack traces. +#-keepattributes SourceFile,LineNumberTable + +# If you keep the line number information, uncomment this to +# hide the original source file name. +#-renamesourcefileattribute SourceFile \ No newline at end of file diff --git a/packages/templates/app/android/app/src/androidTest/java/io/template/polywrap/ExampleInstrumentedTest.kt b/packages/templates/app/android/app/src/androidTest/java/io/template/polywrap/ExampleInstrumentedTest.kt new file mode 100644 index 0000000000..b7b68eea02 --- /dev/null +++ b/packages/templates/app/android/app/src/androidTest/java/io/template/polywrap/ExampleInstrumentedTest.kt @@ -0,0 +1,24 @@ +package io.template.polywrap + +import androidx.test.platform.app.InstrumentationRegistry +import androidx.test.ext.junit.runners.AndroidJUnit4 + +import org.junit.Test +import org.junit.runner.RunWith + +import org.junit.Assert.* + +/** + * Instrumented test, which will execute on an Android device. + * + * See [testing documentation](http://d.android.com/tools/testing). + */ +@RunWith(AndroidJUnit4::class) +class ExampleInstrumentedTest { + @Test + fun useAppContext() { + // Context of the app under test. + val appContext = InstrumentationRegistry.getInstrumentation().targetContext + assertEquals("io.template.polywrap", appContext.packageName) + } +} \ No newline at end of file diff --git a/packages/templates/app/android/app/src/main/AndroidManifest.xml b/packages/templates/app/android/app/src/main/AndroidManifest.xml new file mode 100644 index 0000000000..7f6e64f757 --- /dev/null +++ b/packages/templates/app/android/app/src/main/AndroidManifest.xml @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/packages/templates/app/android/app/src/main/assets/logback.xml b/packages/templates/app/android/app/src/main/assets/logback.xml new file mode 100644 index 0000000000..fd590840ca --- /dev/null +++ b/packages/templates/app/android/app/src/main/assets/logback.xml @@ -0,0 +1,18 @@ + + + + %logger{12} + + + [%-20thread] %msg + + + + + + + \ No newline at end of file diff --git a/packages/templates/app/android/app/src/main/java/io/template/polywrap/MainActivity.kt b/packages/templates/app/android/app/src/main/java/io/template/polywrap/MainActivity.kt new file mode 100644 index 0000000000..48bf2c78a3 --- /dev/null +++ b/packages/templates/app/android/app/src/main/java/io/template/polywrap/MainActivity.kt @@ -0,0 +1,59 @@ +package io.template.polywrap + +import android.os.Bundle +import androidx.activity.ComponentActivity +import androidx.activity.compose.setContent +import androidx.compose.foundation.background +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.fillMaxHeight +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding +import androidx.compose.material3.Button +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.Surface +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.unit.dp +import androidx.lifecycle.viewmodel.compose.viewModel +import io.template.myapplication.ui.theme.MyApplicationTheme + +class MainActivity : ComponentActivity() { + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + setContent { + MyApplicationTheme { + Column( + verticalArrangement = Arrangement.Center, + modifier = Modifier.fillMaxHeight().padding(16.dp) + ) { + Surface( + modifier = Modifier.fillMaxWidth().height(60.dp), + color = MaterialTheme.colorScheme.background + ) { + PolywrapDemo() + } + } + } + } + } +} + +@Composable +fun PolywrapDemo(demoViewModel: PolywrapDemoViewModel = viewModel()) { + Button(onClick = { demoViewModel.polywrapDemo() }) { + Text(text = "Click here and check the logs!") + } +} + +@Preview(showBackground = true) +@Composable +fun PolywrapDemoPreview() { + MyApplicationTheme { + PolywrapDemo() + } +} \ No newline at end of file diff --git a/packages/templates/app/android/app/src/main/java/io/template/polywrap/PolywrapDemoViewModel.kt b/packages/templates/app/android/app/src/main/java/io/template/polywrap/PolywrapDemoViewModel.kt new file mode 100644 index 0000000000..67cfa45080 --- /dev/null +++ b/packages/templates/app/android/app/src/main/java/io/template/polywrap/PolywrapDemoViewModel.kt @@ -0,0 +1,69 @@ +package io.template.polywrap + +import android.util.Log +import androidx.lifecycle.ViewModel +import androidx.lifecycle.viewModelScope +import io.polywrap.client.PolywrapClient +import io.polywrap.configBuilder.polywrapClient +import io.polywrap.plugins.logger.loggerPlugin +import kotlinx.coroutines.launch +import wrap.Ethereum +import wrap.EthereumArgsEncodeParams +import wrap.Logging +import wrap.LoggingArgsLog +import wrap.LoggingLogLevel + +class PolywrapDemoViewModel: ViewModel() { + + // we can create a custom client + val loggerInterfaceUri = "wrapscan.io/polywrap/logger@1.0" + private val client = polywrapClient { + addDefaults() + setPackage("plugin/logger" to loggerPlugin(null)) + addInterfaceImplementation(loggerInterfaceUri, "plugin/logger") + setRedirect(loggerInterfaceUri to "plugin/logger") + } + + // and use the custom client to create an SDK class instance + private val logger = Logging(client) + // the client can be shared across SDK instances + private val ethereum = Ethereum(client) + + // Because their lifetimes are tied to the client, SDK instances work well as extension properties + val PolywrapClient.eth + get() = ethereum + + // or we can create an SDK class instance with a new client using default configuration + private val defaultEth = Ethereum() + + fun polywrapDemo() = viewModelScope.launch { + Log.i("polywrapDemo","Invoking: Logging.info(...)") + + logger.log(LoggingArgsLog(LoggingLogLevel.INFO, "Hello there")).getOrThrow() + logger.log(LoggingArgsLog(LoggingLogLevel.INFO, "Hello again")).getOrThrow() + logger.log(LoggingArgsLog(LoggingLogLevel.INFO, "One last time...")).getOrThrow() + + Log.i("polywrapDemo","Invoking: Ethereum.encodeParams(...)") + + val encodeArgs = EthereumArgsEncodeParams( + types = listOf("address", "uint256"), + values = listOf("0xB1B7586656116D546033e3bAFF69BFcD6592225E", "500") + ) + val result = client.eth.encodeParams(encodeArgs) + + if (result.isSuccess) { + println("Ethereum.encodeParams:\n${result.getOrThrow()}") + } else { + println("Error - Ethereum.encodeParams:\n${result.exceptionOrNull()}") + } + } + + override fun onCleared() { + super.onCleared() + // remember to close clients to prevent memory leaks when you're done using them + client.close() + defaultEth.client.close() + } +} + + diff --git a/packages/templates/app/android/app/src/main/java/io/template/polywrap/theme/Color.kt b/packages/templates/app/android/app/src/main/java/io/template/polywrap/theme/Color.kt new file mode 100644 index 0000000000..0c8be7eb19 --- /dev/null +++ b/packages/templates/app/android/app/src/main/java/io/template/polywrap/theme/Color.kt @@ -0,0 +1,11 @@ +package io.template.myapplication.ui.theme + +import androidx.compose.ui.graphics.Color + +val Purple80 = Color(0xFFD0BCFF) +val PurpleGrey80 = Color(0xFFCCC2DC) +val Pink80 = Color(0xFFEFB8C8) + +val Purple40 = Color(0xFF6650a4) +val PurpleGrey40 = Color(0xFF625b71) +val Pink40 = Color(0xFF7D5260) \ No newline at end of file diff --git a/packages/templates/app/android/app/src/main/java/io/template/polywrap/theme/Theme.kt b/packages/templates/app/android/app/src/main/java/io/template/polywrap/theme/Theme.kt new file mode 100644 index 0000000000..352cfd013c --- /dev/null +++ b/packages/templates/app/android/app/src/main/java/io/template/polywrap/theme/Theme.kt @@ -0,0 +1,70 @@ +package io.template.myapplication.ui.theme + +import android.app.Activity +import android.os.Build +import androidx.compose.foundation.isSystemInDarkTheme +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.darkColorScheme +import androidx.compose.material3.dynamicDarkColorScheme +import androidx.compose.material3.dynamicLightColorScheme +import androidx.compose.material3.lightColorScheme +import androidx.compose.runtime.Composable +import androidx.compose.runtime.SideEffect +import androidx.compose.ui.graphics.toArgb +import androidx.compose.ui.platform.LocalContext +import androidx.compose.ui.platform.LocalView +import androidx.core.view.WindowCompat + +private val DarkColorScheme = darkColorScheme( + primary = Purple80, + secondary = PurpleGrey80, + tertiary = Pink80 +) + +private val LightColorScheme = lightColorScheme( + primary = Purple40, + secondary = PurpleGrey40, + tertiary = Pink40 + + /* Other default colors to override + background = Color(0xFFFFFBFE), + surface = Color(0xFFFFFBFE), + onPrimary = Color.White, + onSecondary = Color.White, + onTertiary = Color.White, + onBackground = Color(0xFF1C1B1F), + onSurface = Color(0xFF1C1B1F), + */ +) + +@Composable +fun MyApplicationTheme( + darkTheme: Boolean = isSystemInDarkTheme(), + // Dynamic color is available on Android 12+ + dynamicColor: Boolean = true, + content: @Composable () -> Unit +) { + val colorScheme = when { + dynamicColor && Build.VERSION.SDK_INT >= Build.VERSION_CODES.S -> { + val context = LocalContext.current + if (darkTheme) dynamicDarkColorScheme(context) else dynamicLightColorScheme(context) + } + + darkTheme -> DarkColorScheme + else -> LightColorScheme + } + val view = LocalView.current + if (!view.isInEditMode) { + SideEffect { + val window = (view.context as Activity).window + window.statusBarColor = colorScheme.primary.toArgb() + WindowCompat.getInsetsController(window, view).isAppearanceLightStatusBars = darkTheme + } + } + + MaterialTheme( + colorScheme = colorScheme, + typography = Typography, + content = content + ) +} \ No newline at end of file diff --git a/packages/templates/app/android/app/src/main/java/io/template/polywrap/theme/Type.kt b/packages/templates/app/android/app/src/main/java/io/template/polywrap/theme/Type.kt new file mode 100644 index 0000000000..6f962541f3 --- /dev/null +++ b/packages/templates/app/android/app/src/main/java/io/template/polywrap/theme/Type.kt @@ -0,0 +1,34 @@ +package io.template.myapplication.ui.theme + +import androidx.compose.material3.Typography +import androidx.compose.ui.text.TextStyle +import androidx.compose.ui.text.font.FontFamily +import androidx.compose.ui.text.font.FontWeight +import androidx.compose.ui.unit.sp + +// Set of Material typography styles to start with +val Typography = Typography( + bodyLarge = TextStyle( + fontFamily = FontFamily.Default, + fontWeight = FontWeight.Normal, + fontSize = 16.sp, + lineHeight = 24.sp, + letterSpacing = 0.5.sp + ) + /* Other default text styles to override + titleLarge = TextStyle( + fontFamily = FontFamily.Default, + fontWeight = FontWeight.Normal, + fontSize = 22.sp, + lineHeight = 28.sp, + letterSpacing = 0.sp + ), + labelSmall = TextStyle( + fontFamily = FontFamily.Default, + fontWeight = FontWeight.Medium, + fontSize = 11.sp, + lineHeight = 16.sp, + letterSpacing = 0.5.sp + ) + */ +) \ No newline at end of file diff --git a/packages/templates/app/android/app/src/main/res/drawable/ic_launcher_background.xml b/packages/templates/app/android/app/src/main/res/drawable/ic_launcher_background.xml new file mode 100644 index 0000000000..07d5da9cbf --- /dev/null +++ b/packages/templates/app/android/app/src/main/res/drawable/ic_launcher_background.xml @@ -0,0 +1,170 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/packages/templates/app/android/app/src/main/res/drawable/ic_launcher_foreground.xml b/packages/templates/app/android/app/src/main/res/drawable/ic_launcher_foreground.xml new file mode 100644 index 0000000000..2b068d1146 --- /dev/null +++ b/packages/templates/app/android/app/src/main/res/drawable/ic_launcher_foreground.xml @@ -0,0 +1,30 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/packages/templates/app/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml b/packages/templates/app/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml new file mode 100644 index 0000000000..6f3b755bf5 --- /dev/null +++ b/packages/templates/app/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/packages/templates/app/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml b/packages/templates/app/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml new file mode 100644 index 0000000000..6f3b755bf5 --- /dev/null +++ b/packages/templates/app/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/packages/templates/app/android/app/src/main/res/mipmap-hdpi/ic_launcher.webp b/packages/templates/app/android/app/src/main/res/mipmap-hdpi/ic_launcher.webp new file mode 100644 index 0000000000..c209e78ecd Binary files /dev/null and b/packages/templates/app/android/app/src/main/res/mipmap-hdpi/ic_launcher.webp differ diff --git a/packages/templates/app/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp b/packages/templates/app/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp new file mode 100644 index 0000000000..b2dfe3d1ba Binary files /dev/null and b/packages/templates/app/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp differ diff --git a/packages/templates/app/android/app/src/main/res/mipmap-mdpi/ic_launcher.webp b/packages/templates/app/android/app/src/main/res/mipmap-mdpi/ic_launcher.webp new file mode 100644 index 0000000000..4f0f1d64e5 Binary files /dev/null and b/packages/templates/app/android/app/src/main/res/mipmap-mdpi/ic_launcher.webp differ diff --git a/packages/templates/app/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp b/packages/templates/app/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp new file mode 100644 index 0000000000..62b611da08 Binary files /dev/null and b/packages/templates/app/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp differ diff --git a/packages/templates/app/android/app/src/main/res/mipmap-xhdpi/ic_launcher.webp b/packages/templates/app/android/app/src/main/res/mipmap-xhdpi/ic_launcher.webp new file mode 100644 index 0000000000..948a3070fe Binary files /dev/null and b/packages/templates/app/android/app/src/main/res/mipmap-xhdpi/ic_launcher.webp differ diff --git a/packages/templates/app/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp b/packages/templates/app/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp new file mode 100644 index 0000000000..1b9a6956b3 Binary files /dev/null and b/packages/templates/app/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp differ diff --git a/packages/templates/app/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp b/packages/templates/app/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp new file mode 100644 index 0000000000..28d4b77f9f Binary files /dev/null and b/packages/templates/app/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp differ diff --git a/packages/templates/app/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp b/packages/templates/app/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp new file mode 100644 index 0000000000..9287f50836 Binary files /dev/null and b/packages/templates/app/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp differ diff --git a/packages/templates/app/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp b/packages/templates/app/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp new file mode 100644 index 0000000000..aa7d6427e6 Binary files /dev/null and b/packages/templates/app/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp differ diff --git a/packages/templates/app/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp b/packages/templates/app/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp new file mode 100644 index 0000000000..9126ae37cb Binary files /dev/null and b/packages/templates/app/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp differ diff --git a/packages/templates/app/android/app/src/main/res/values/colors.xml b/packages/templates/app/android/app/src/main/res/values/colors.xml new file mode 100644 index 0000000000..f8c6127d32 --- /dev/null +++ b/packages/templates/app/android/app/src/main/res/values/colors.xml @@ -0,0 +1,10 @@ + + + #FFBB86FC + #FF6200EE + #FF3700B3 + #FF03DAC5 + #FF018786 + #FF000000 + #FFFFFFFF + \ No newline at end of file diff --git a/packages/templates/app/android/app/src/main/res/values/strings.xml b/packages/templates/app/android/app/src/main/res/values/strings.xml new file mode 100644 index 0000000000..9e62466cf5 --- /dev/null +++ b/packages/templates/app/android/app/src/main/res/values/strings.xml @@ -0,0 +1,3 @@ + + Template + \ No newline at end of file diff --git a/packages/templates/app/android/app/src/main/res/values/themes.xml b/packages/templates/app/android/app/src/main/res/values/themes.xml new file mode 100644 index 0000000000..0b98d60cf4 --- /dev/null +++ b/packages/templates/app/android/app/src/main/res/values/themes.xml @@ -0,0 +1,5 @@ + + + +