Skip to content

Commit

Permalink
Merge branch 'main' into feat/log-err
Browse files Browse the repository at this point in the history
  • Loading branch information
karczuRF authored Nov 20, 2024
2 parents ef281f0 + 83429bc commit 0aab695
Show file tree
Hide file tree
Showing 20 changed files with 233 additions and 56 deletions.
6 changes: 2 additions & 4 deletions dist-isolation/index.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
window.__TAURI_ISOLATION_HOOK__ = (payload) => {
// at the moment let's not verify or modify anything, just print the content from the hook
if (payload !== null) {
console.log("isolation hook", payload)
}
// TODO at the moment let's not verify or modify anything, just print the content from the hook

return payload
}
2 changes: 1 addition & 1 deletion locales/en/errors.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"manifest-package-name-mismatch": "Tapplet manifest does not match package name. Expected: {{ expectedPackageName }} Received: {{ receivedPackageName }} from: {{- endpoint }}/tapplet.manifest.json",
"failed-to-fetch-tapp-manifest": "Error fetching tapplet manifest: {{ error }}",
"failed-to-fetch-tapp-config": "Error fetching tapplet config: {{ error }}",
"no-pending-transaction-found": "No pending transaction found",
"no-data-in-event": "No data in event",
"no-source-in-event": "No source in event",
Expand Down
2 changes: 1 addition & 1 deletion locales/pl/errors.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"manifest-package-name-mismatch": "Manifest tapplet'u nie pasuje do nazwy pakietu. Oczekiwano: {{ expectedPackageName }} Otrzymano: {{ receivedPackageName }} z: {{- endpoint }}/tapplet.manifest.json",
"failed-to-fetch-tapp-manifest": "Błąd pobierania manifestu tapplet'u: {{ error }}",
"failed-to-fetch-tapp-config": "Błąd pobierania konfiguracji tapplet'u: {{ error }}",
"no-pending-transaction-found": "Nie znaleziono oczekującej transakcji",
"no-data-in-event": "Brak danych w zdarzeniu",
"no-source-in-event": "Brak źródła w zdarzeniu",
Expand Down
25 changes: 22 additions & 3 deletions src-tauri/src/commands.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,13 @@ use crate::{
RequestError::*,
TappletServerError::*,
},
interface::{ DevTappletResponse, InstalledTappletWithName, RegisteredTappletWithVersion },
interface::{
DevTappletResponse,
InstalledTappletWithName,
LaunchedTappResult,
RegisteredTappletWithVersion,
TariPermission,
},
progress_tracker::ProgressTracker,
rpc::{ account_create, balances, free_coins, make_request },
tapplet_installer::{
Expand All @@ -35,6 +41,7 @@ use crate::{
download_asset,
fetch_tapp_registry_manifest,
get_tapp_download_path,
get_tapp_permissions,
},
tapplet_server::start,
AssetServer,
Expand Down Expand Up @@ -126,7 +133,7 @@ pub async fn launch_tapplet(
shutdown_tokens: State<'_, ShutdownTokens>,
db_connection: State<'_, DatabaseConnection>,
app_handle: tauri::AppHandle
) -> Result<String, Error> {
) -> Result<LaunchedTappResult, Error> {
let mut locked_tokens = shutdown_tokens.0.lock().await;
let mut store = SqliteStore::new(db_connection.0.clone());

Expand Down Expand Up @@ -155,6 +162,14 @@ pub async fn launch_tapplet(
}
}

let permissions: Vec<TariPermission> = match get_tapp_permissions(tapplet_path.clone()) {
Ok(p) => p,
Err(e) => {
error!(target: LOG_TARGET,"Error getting permissions: {:?}", e);
return Err(e.into());
}
};

let dist_path = tapplet_path.join(TAPPLET_DIST_DIR);
let handle_start = tauri::async_runtime::spawn(async move { start(dist_path).await });

Expand All @@ -165,7 +180,11 @@ pub async fn launch_tapplet(
}
None => {}
}
Ok(format!("http://{}", addr))

Ok(LaunchedTappResult {
endpoint: format!("http://{}", addr),
permissions,
})
}

#[tauri::command]
Expand Down
6 changes: 3 additions & 3 deletions src-tauri/src/database/models.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use crate::database::schema::*;
use crate::interface::TappletManifest;
use crate::interface::TappletRegistryManifest;
use diesel::prelude::*;
use serde::{ Deserialize, Serialize };

Expand Down Expand Up @@ -67,8 +67,8 @@ pub struct CreateTapplet<'a> {
pub category: &'a str,
}

impl<'a> From<&'a TappletManifest> for CreateTapplet<'a> {
fn from(tapplet_manifest: &'a TappletManifest) -> Self {
impl<'a> From<&'a TappletRegistryManifest> for CreateTapplet<'a> {
fn from(tapplet_manifest: &'a TappletRegistryManifest) -> Self {
CreateTapplet {
registry_id: &tapplet_manifest.id,
package_name: &tapplet_manifest.id,
Expand Down
36 changes: 33 additions & 3 deletions src-tauri/src/interface/registry.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,11 @@ pub struct RegisteredTapplets {
#[serde(rename = "manifestVersion")]
pub manifest_version: String,
#[serde(rename = "registeredTapplets")]
pub registered_tapplets: HashMap<String, TappletManifest>,
pub registered_tapplets: HashMap<String, TappletRegistryManifest>,
}

#[derive(Debug, serde::Deserialize)]
pub struct TappletManifest {
pub struct TappletRegistryManifest {
pub id: String,
pub metadata: Metadata,
pub versions: HashMap<String, Version>,
Expand Down Expand Up @@ -51,6 +51,36 @@ pub struct About {
#[derive(Debug, serde::Deserialize, Clone)]
pub struct Audit {
pub auditor: String,
#[serde(rename = "report")]
#[serde(rename = "reportUrl")]
pub report_url: String,
}

#[derive(Debug, serde::Deserialize)]
pub struct TappletConfig {
#[serde(rename = "packageName")]
pub package_name: String,
pub version: String,
#[serde(rename = "supportedChain")]
pub supported_chain: Vec<String>,
pub permissions: Vec<TariPermission>,
}

#[derive(Debug, Clone, serde::Deserialize, serde::Serialize)]
pub enum TariPermission {
TariPermissionNftGetOwnershipProof,
TariPermissionAccountBalance,
TariPermissionAccountInfo,
TariPermissionAccountList,
TariPermissionKeyList,
TariPermissionTransactionGet,
TariPermissionTransactionSend,
TariPermissionGetNft,
TariPermissionSubstatesRead,
TariPermissionTemplatesRead,
}

#[derive(Debug, Clone, serde::Serialize)]
pub struct LaunchedTappResult {
pub endpoint: String,
pub permissions: Vec<TariPermission>,
}
17 changes: 16 additions & 1 deletion src-tauri/src/tapplet_installer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use crate::{
database::models::TappletVersion,
error::{ Error::{ self, IOError, JsonParsingError, RequestError }, IOError::*, RequestError::* },
hash_calculator::calculate_checksum,
interface::{ RegisteredTapplets, TappletAssets },
interface::{ RegisteredTapplets, TappletAssets, TappletConfig, TariPermission },
};
use log::error;
use crate::constants::TAPPLETS_INSTALLED_DIR;
Expand All @@ -23,8 +23,10 @@ pub fn delete_tapplet(tapplet_path: PathBuf) -> Result<(), Error> {

pub fn check_extracted_files(tapplet_path: PathBuf) -> Result<bool, Error> {
// TODO define all needed files
// universe.tari/tapplets_installed/<tapplet_name>/<version>/package
let tapp_dir: PathBuf = tapplet_path.join("package");
let pkg_json_file = tapp_dir.join("package.json");
// let manifest_file = tapp_dir.join("dist").join("tapplet.manifest.json");
let path = tapplet_path
.into_os_string()
.into_string()
Expand Down Expand Up @@ -150,3 +152,16 @@ pub fn check_files_and_validate_checksum(tapp: TappletVersion, tapp_dir: PathBuf
}
Ok(is_checksum_valid)
}

pub fn get_tapp_permissions(tapp_path: PathBuf) -> Result<Vec<TariPermission>, Error> {
// tapp_dir = universe.tari/tapplets_installed/<tapplet_name>/<version>/package
let tapp_dir: PathBuf = tapp_path.join("package");
let tapp_config = tapp_dir.join("dist").join("tapplet.config.json");
if !tapp_config.exists() {
return Err(IOError(FailedToGetFilePath));
}

let config = fs::read_to_string(tapp_config.clone()).unwrap_or_default();
let tapplet: TappletConfig = serde_json::from_str(&config).map_err(|e| JsonParsingError(e))?;
Ok(tapplet.permissions)
}
17 changes: 15 additions & 2 deletions src/components/ActiveTapplet.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ import { useDispatch } from "react-redux"
import { errorActions } from "../store/error/error.slice"
import { useTranslation } from "react-i18next"
import { ErrorSource } from "../store/error/error.types"
import { providerActions } from "../store/provider/provider.slice"
import { LaunchedTappResult } from "@type/tapplet"

export function ActiveTapplet() {
const { t } = useTranslation("components")
Expand All @@ -17,8 +19,19 @@ export function ActiveTapplet() {

useEffect(() => {
invoke("launch_tapplet", { installedTappletId })
.then((res: unknown) => {
setTappletAddress(res as string)
.then((res: any) => {
const launchedTappParams: LaunchedTappResult = res
setTappletAddress(launchedTappParams.endpoint)
if (launchedTappParams.permissions) {
dispatch(providerActions.updatePermissionsRequest({ permissions: launchedTappParams.permissions }))
} else {
dispatch(
errorActions.showError({
message: `failed-to-fetch-tapp-config | error-${"Tapplet permissions undefined"}`,
errorSource: ErrorSource.BACKEND,
})
)
}
})
.catch((error: string) => dispatch(errorActions.showError({ message: error, errorSource: ErrorSource.BACKEND })))

Expand Down
27 changes: 19 additions & 8 deletions src/components/DevTapplet.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
import { Box } from "@mui/material"
import { useLocation } from "react-router-dom"
import { DevTapplet } from "@type/tapplet"
import { DevTapplet, TappletConfig } from "@type/tapplet"
import { useEffect, useState } from "react"
import { Tapplet } from "./Tapplet"
import { useDispatch } from "react-redux"
import { errorActions } from "../store/error/error.slice"
import { ErrorSource } from "../store/error/error.types"
import { providerActions } from "../store/provider/provider.slice"

export function ActiveDevTapplet() {
let { state }: { state: DevTapplet } = useLocation()
Expand All @@ -15,23 +16,33 @@ export function ActiveDevTapplet() {
useEffect(() => {
const fetchTappletManifest = async () => {
try {
const response = await fetch(`${state?.endpoint}/tapplet.manifest.json`)
const manifest = await response.json()
if (manifest?.packageName === state?.package_name) {
const response = await fetch(`${state?.endpoint}/src/tapplet.config.json`)
const config: TappletConfig = await response.json()
if (config?.packageName === state?.package_name) {
setIsVerified(true)
if (config?.requiredPermissions) {
dispatch(providerActions.updatePermissionsRequest({ permissions: config?.requiredPermissions }))
} else {
dispatch(
errorActions.showError({
message: `failed-to-fetch-tapp-config | error-${"Tapplet permissions undefined"}`,
errorSource: ErrorSource.BACKEND,
})
)
}
} else {
dispatch(
errorActions.showError({
message: `manifest-package-name-mismatch | expectedPackageName-${state?.package_name} & receivedPackageName-${manifest?.packageName} & endpoint-${state?.endpoint}`,
errorSource: ErrorSource.FRONTEND,
message: `manifest-package-name-mismatch | expectedPackageName-${state?.package_name} & receivedPackageName-${config?.packageName} & endpoint-${state?.endpoint}`,
errorSource: ErrorSource.BACKEND,
})
)
}
} catch (error) {
dispatch(
errorActions.showError({
message: `failed-to-fetch-tapp-manifest | error-${error}`,
errorSource: ErrorSource.FRONTEND,
message: `failed-to-fetch-tapp-config | error-${error}`,
errorSource: ErrorSource.BACKEND,
})
)
}
Expand Down
2 changes: 1 addition & 1 deletion src/components/TappletsInstalled.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ export const TappletsInstalled: React.FC = () => {
<ListItemAvatar>
<Avatar src={item.logoAddr} />
</ListItemAvatar>
<ListItemText primary={item.display_name} />
<ListItemText primary={`${item.display_name} v${item.installed_version}`} />
<IconButton aria-label="launch" style={{ marginRight: 10 }}>
<NavLink to={`/${TabKey.ACTIVE_TAPPLET}/${item.installed_tapplet.id}`} style={{ display: "contents" }}>
<Launch color="primary" />
Expand Down
2 changes: 1 addition & 1 deletion src/components/TappletsRegistered.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ export const TappletsRegistered: React.FC = () => {
<ListItemAvatar>
<Avatar src={item.logoAddr} />
</ListItemAvatar>
<ListItemText primary={item.package_name} />
<ListItemText primary={item.display_name} />
<IconButton aria-label="install" onClick={() => handleInstall(item.id)} sx={{ marginLeft: 8 }}>
<InstallDesktop color="primary" />
</IconButton>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,8 @@ export type WindowSize = {
height: number
}

export class TariUniverseProvider implements TariProvider {
public providerName = "TariUniverseProvider"
export class TUInternalProvider implements TariProvider {
public providerName = "TUInternalProvider"
params: WalletDaemonParameters
client: WalletDaemonClient
isProviderConnected: boolean
Expand All @@ -63,12 +63,9 @@ export class TariUniverseProvider implements TariProvider {
return this.client
}

static build(params: WalletDaemonParameters): TariUniverseProvider {
const allPermissions = new TariPermissions()
allPermissions.addPermissions(params.permissions)
allPermissions.addPermissions(params.optionalPermissions)
static build(params: WalletDaemonParameters): TUInternalProvider {
const client = WalletDaemonClient.new(new IPCRpcTransport())
return new TariUniverseProvider(params, client)
return new TUInternalProvider(params, client)
}

public setWindowSize(width: number, height: number): void {
Expand Down
17 changes: 16 additions & 1 deletion src/store/provider/provider.action.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { ListenerEffectAPI, PayloadAction, ThunkDispatch, UnknownAction } from "@reduxjs/toolkit"
import { TransactionEvent } from "@type/transaction"
import { InitProviderRequestPayload } from "./provider.types"
import { InitProviderRequestPayload, UpdatePermissionsRequestPayload } from "./provider.types"
import { providerActions } from "./provider.slice"
import { transactionActions } from "../transaction/transaction.slice"
import { Transaction, TUProviderMethod } from "../transaction/transaction.types"
Expand Down Expand Up @@ -144,3 +144,18 @@ export const initializeAction = () => ({
}
},
})

export const updatePermissionsAction = () => ({
actionCreator: providerActions.updatePermissionsRequest,
effect: async (
action: PayloadAction<UpdatePermissionsRequestPayload>,
listenerApi: ListenerEffectAPI<unknown, ThunkDispatch<unknown, unknown, UnknownAction>, unknown>
) => {
const permissions = action.payload.permissions
try {
listenerApi.dispatch(providerActions.updatePermissionsSuccess({ permissions }))
} catch (error) {
listenerApi.dispatch(providerActions.updatePermissionsFailure({ errorMsg: error as string }))
}
},
})
21 changes: 9 additions & 12 deletions src/store/provider/provider.selector.ts
Original file line number Diff line number Diff line change
@@ -1,28 +1,25 @@
import { permissions as walletPermissions, TariPermissions } from "@tari-project/tarijs"
import { TariPermissions } from "@tari-project/tarijs"
import { createSelector } from "@reduxjs/toolkit"
import { RootState } from "../store"
import { WalletDaemonParameters, TariUniverseProvider } from "@provider/TariUniverseProvider"

const { TariPermissionAccountInfo, TariPermissionKeyList, TariPermissionSubstatesRead, TariPermissionTransactionSend } =
walletPermissions
import { WalletDaemonParameters, TUInternalProvider } from "@provider/TUInternalProvider"
import { toPermission } from "@type/tariPermissions"

const providerStateSelector = (state: RootState) => state.provider

const isInitialized = createSelector([providerStateSelector], (state) => state.isInitialized)

const selectProvider = createSelector([providerStateSelector], (_) => {
// TODO read permissions from tapplet manifest
const selectProvider = createSelector([providerStateSelector], (state) => {
let permissions = new TariPermissions()
permissions.addPermission(new TariPermissionKeyList())
permissions.addPermission(new TariPermissionAccountInfo())
permissions.addPermission(new TariPermissionTransactionSend())
permissions.addPermission(new TariPermissionSubstatesRead())
if (state.permissions) {
state.permissions.map((p) => permissions.addPermission(toPermission(p)))
}

let optionalPermissions = new TariPermissions()
const params: WalletDaemonParameters = {
permissions,
optionalPermissions,
}
return TariUniverseProvider.build(params)
return TUInternalProvider.build(params)
})

export const providerSelector = {
Expand Down
Loading

0 comments on commit 0aab695

Please sign in to comment.