Skip to content

Commit

Permalink
app updated to compatible with stellar-cli also
Browse files Browse the repository at this point in the history
  • Loading branch information
tolgayayci committed Jul 25, 2024
1 parent ce0d5a7 commit 90a484c
Show file tree
Hide file tree
Showing 20 changed files with 295 additions and 133 deletions.
71 changes: 64 additions & 7 deletions main/background.ts
Original file line number Diff line number Diff line change
Expand Up @@ -324,16 +324,23 @@ if (isProd) {
if (
command &&
(command === "contract" ||
command === "lab xdr" ||
command === "lab" ||
command === "xdr" ||
command === "events")
) {
const formattedResult = result
? `Result: ${JSON.stringify(result)}`
: "";

// Check the installed CLI type
const versionOutput = await executeSorobanCommand("--version");
const cliType = versionOutput.trim().startsWith("stellar")
? "stellar"
: "soroban";

commandLog.info(
"soroban",
command ? command : "",
cliType,
command,
subcommand ? subcommand : "",
args ? args.join(" ") : "",
flags ? flags.join(" ") : "",
Expand All @@ -344,7 +351,7 @@ if (isProd) {

return result;
} catch (error) {
log.error("Error while executing Soroban command:", error);
log.error("Error while executing command:", error);
throw error;
}
}
Expand Down Expand Up @@ -467,14 +474,64 @@ if (isProd) {
try {
if (mainWindow) {
const result = await executeSorobanCommand("--version");
const isSorobanInstalled = result.trim().startsWith("soroban");
return isSorobanInstalled;
const trimmedResult = result.trim();

if (trimmedResult.startsWith("stellar")) {
const versionMatch = trimmedResult.match(/stellar (\d+\.\d+\.\d+)/);
if (versionMatch) {
return {
installed: true,
type: "stellar",
version: versionMatch[1],
};
}
} else if (trimmedResult.startsWith("soroban")) {
const versionMatch = trimmedResult.match(/soroban (\d+\.\d+\.\d+)/);
if (versionMatch) {
return {
installed: true,
type: "soroban",
version: versionMatch[1],
};
}
}

// If we couldn't parse the version, but it starts with stellar or soroban
if (
trimmedResult.startsWith("stellar") ||
trimmedResult.startsWith("soroban")
) {
return {
installed: true,
type: trimmedResult.startsWith("stellar") ? "stellar" : "soroban",
version: "unknown",
};
}

// If we get here, the command succeeded but the output was unexpected
return {
installed: false,
type: null,
version: null,
error: "Unexpected output format",
};
} else {
console.error("Main window not found");
return {
installed: false,
type: null,
version: null,
error: "Main window not found",
};
}
} catch (error) {
console.error(`Error while checking for Soroban installation: ${error}`);
return false;
return {
installed: false,
type: null,
version: null,
error: error.message || "Unknown error",
};
}
});

Expand Down
77 changes: 52 additions & 25 deletions main/helpers/soroban-helper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,37 +11,64 @@ export function executeSorobanCommand(
const flagStr = flags || [];
const allArgs = [command, subcommand, ...argStr, ...flagStr].filter(Boolean);

const commandStr = `soroban ${allArgs.join(" ")}`;

return new Promise((resolve, reject) => {
const child = spawn("soroban", allArgs, { cwd: path, shell: true });

let stdoutData = "";
let stderrData = "";

child.stdout.on("data", (data) => {
stdoutData += data;
});
// Check if stellar is available
const checkStellar = spawn("stellar", ["--version"], { shell: true });

child.stderr.on("data", (data) => {
stderrData += data;
checkStellar.on("error", () => {
// If stellar command fails, use soroban
const commandStr = `soroban ${allArgs.join(" ")}`;
const child = spawn("soroban", allArgs, { cwd: path, shell: true });
handleChildProcess(child, commandStr, resolve, reject);
});

child.on("error", (error) => {
reject(error);
});

child.on("close", (code) => {
if (code !== 0) {
reject(
new Error(
`Command "${commandStr}" failed with exit code ${code}: ${stderrData}`
)
);
checkStellar.on("close", (code) => {
if (code === 0) {
// If stellar is available, use stellar
const commandStr = `stellar ${allArgs.join(" ")}`;
const child = spawn("stellar", allArgs, { cwd: path, shell: true });
handleChildProcess(child, commandStr, resolve, reject);
} else {
const combinedOutput = stdoutData + stderrData;
resolve(combinedOutput.trim());
// If stellar check fails, use soroban
const commandStr = `soroban ${allArgs.join(" ")}`;
const child = spawn("soroban", allArgs, { cwd: path, shell: true });
handleChildProcess(child, commandStr, resolve, reject);
}
});
});
}

function handleChildProcess(
child: ReturnType<typeof spawn>,
commandStr: string,
resolve: (value: string | PromiseLike<string>) => void,
reject: (reason?: any) => void
) {
let stdoutData = "";
let stderrData = "";

child.stdout.on("data", (data) => {
stdoutData += data;
});

child.stderr.on("data", (data) => {
stderrData += data;
});

child.on("error", (error) => {
reject(error);
});

child.on("close", (code) => {
if (code !== 0) {
reject(
new Error(
`Command "${commandStr}" failed with exit code ${code}: ${stderrData}`
)
);
} else {
const combinedOutput = stdoutData + stderrData;
resolve(combinedOutput.trim());
}
});
}
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"private": false,
"name": "sora",
"description": "Sora | Soroban Desktop Application",
"version": "0.2.0",
"version": "0.2.1",
"author": "Tolga Yaycı <[email protected]>",
"main": "app/background.js",
"repository": {
Expand Down
37 changes: 24 additions & 13 deletions renderer/components/about/About.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,8 @@ import { Button } from "components/ui/button";

export default function EnvironmentVariables() {
const [soraAppVersion, setSoraAppVersion] = useState("Loading...");
const [sorobanVersion, setSorobanVersion] = useState("Loading...");
const [cliType, setCliType] = useState("Loading...");
const [cliVersion, setCliVersion] = useState("Loading...");
const [sorobanEnvVersion, setSorobanEnvVersion] = useState("Loading...");
const [sorobanEnvInterfaceVersion, setSorobanEnvInterfaceVersion] =
useState("Loading...");
Expand All @@ -26,13 +27,27 @@ export default function EnvironmentVariables() {

useEffect(() => {
async function fetchVersionData() {
const versionData = await window.sorobanApi.getSorobanVersion();
try {
const installationInfo = await window.sorobanApi.isSorobanInstalled();
const versionData = await window.sorobanApi.getSorobanVersion();

setSorobanVersion(versionData.sorobanVersion);
setSorobanEnvVersion(versionData.sorobanEnvVersion);
setSorobanEnvInterfaceVersion(versionData.sorobanEnvInterfaceVersion);
setStellarXdrVersion(versionData.stellarXdrVersion);
setXdrCurrVersion(versionData.xdrCurrVersion);
if (typeof installationInfo === "object") {
setCliType(installationInfo.type || "Unknown");
setCliVersion(installationInfo.version || "Unknown");
} else {
setCliType("Unknown");
setCliVersion("Unknown");
}

setSorobanEnvVersion(versionData.sorobanEnvVersion);
setSorobanEnvInterfaceVersion(versionData.sorobanEnvInterfaceVersion);
setStellarXdrVersion(versionData.stellarXdrVersion);
setXdrCurrVersion(versionData.xdrCurrVersion);
} catch (error) {
console.error("Error fetching version data:", error);
setCliType("Error");
setCliVersion("Error fetching data");
}
}

fetchVersionData();
Expand Down Expand Up @@ -68,12 +83,8 @@ export default function EnvironmentVariables() {
<Input value={soraAppVersion} placeholder="0.2.0" disabled />
</div>
<div className="flex flex-col justify-between space-y-3">
<Label className="w-full">Soroban Version</Label>
<Input
value={sorobanVersion}
placeholder="Not Defined"
disabled
/>
<Label className="w-full">Stellar/Soroban Version</Label>
<Input value={cliVersion} placeholder="Not Defined" disabled />
</div>
<div className="flex flex-col justify-between space-y-3">
<Label className="w-full">Soroban-Env Version</Label>
Expand Down
37 changes: 29 additions & 8 deletions renderer/components/common/is-soroban-installed.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,18 @@ import {
AlertDialogTitle,
} from "components/ui/alert-dialog";

export default function SorobanNotInstalled() {
interface SorobanInstallationProps {
installationInfo: {
installed: boolean;
type: string | null;
version: string | null;
error?: string;
};
}

export default function SorobanInstallationAlert({
installationInfo,
}: SorobanInstallationProps) {
async function openExternalLink(url: string) {
try {
await window.sorobanApi.openExternalLink(url);
Expand All @@ -26,25 +37,35 @@ export default function SorobanNotInstalled() {
}
}

const title = installationInfo.installed
? `${installationInfo.type} is installed!`
: "Soroban/Stellar is not installed!";

const description = installationInfo.installed
? `You have ${installationInfo.type} version ${installationInfo.version} installed.`
: "You need to install Soroban or Stellar to use this application. Please visit the repository for more information.";

return (
<AlertDialog open={true}>
<AlertDialogContent>
<AlertDialogHeader>
<AlertDialogTitle>Soroban is not installed!</AlertDialogTitle>
<AlertDialogTitle>{title}</AlertDialogTitle>
<AlertDialogDescription>
You need to install Soroban to use this application. Please visit
the repository for more information.
{description}
{installationInfo.error && (
<p className="text-red-500 mt-2">
Error: {installationInfo.error}
</p>
)}
</AlertDialogDescription>
</AlertDialogHeader>
<AlertDialogFooter>
<AlertDialogCancel onClick={() => reloadApplication() as any}>
<AlertDialogCancel onClick={() => reloadApplication()}>
Reload Application
</AlertDialogCancel>
<AlertDialogAction
onClick={() =>
openExternalLink(
"https://github.com/tolgayayci/soroban-cli-gui"
) as any
openExternalLink("https://github.com/tolgayayci/soroban-cli-gui")
}
>
Visit GitHub
Expand Down
26 changes: 23 additions & 3 deletions renderer/components/contracts/command-selector.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -103,9 +103,29 @@ const CliCommandSelector = ({
})
.join(" ");

setLatestCommand(
`soroban contract ${selectedCommandDetails.value} ${argsString} ${optionsString}`
);
// Check the installation info and set the command accordingly
window.sorobanApi
.isSorobanInstalled()
.then((installationInfo) => {
let commandPrefix = "soroban";
if (
typeof installationInfo === "object" &&
installationInfo.type === "stellar"
) {
commandPrefix = "stellar";
}

setLatestCommand(
`${commandPrefix} contract ${selectedCommandDetails.value} ${argsString} ${optionsString}`
);
})
.catch((error) => {
console.error("Error checking installation:", error);
// Fallback to soroban if there's an error
setLatestCommand(
`soroban contract ${selectedCommandDetails.value} ${argsString} ${optionsString}`
);
});
};

useEffect(() => {
Expand Down
6 changes: 1 addition & 5 deletions renderer/components/identities/forms/removeIdentity.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,7 @@ export const removeIdentityFormSchema = z.object({
identity_name: z
.string()
.min(3, "Identity name must be at least 3 characters long.")
.max(255, "Identity name must be at most 255 characters long.")
.regex(
/^[A-Za-z0-9.\-_@]+$/,
"Only the characters ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz.-_@0123456789 are valid in identity names."
),
.max(255, "Identity name must be at most 255 characters long."),
global: z.boolean().optional(),
config_dir: z.string().optional(),
});
Expand Down
Loading

0 comments on commit 90a484c

Please sign in to comment.