From 84b781078934cc368a733eb15ba72a111ec6b12f Mon Sep 17 00:00:00 2001
From: Marcos
Date: Fri, 29 Nov 2024 19:25:50 -0300
Subject: [PATCH 01/34] add conditional mount
---
src/lib/remix/index.ts | 2 +-
src/routes/+page.svelte | 68 ++++++++++++++++++++++++++++++-----------
2 files changed, 52 insertions(+), 18 deletions(-)
diff --git a/src/lib/remix/index.ts b/src/lib/remix/index.ts
index b97f542..f4ca0aa 100644
--- a/src/lib/remix/index.ts
+++ b/src/lib/remix/index.ts
@@ -4,7 +4,7 @@ import { listenOnThemeChanged } from "./theme";
import { listenOnCompilerResults } from "./compiler";
import { initLogger } from "./logger";
-export const initPlugin = () => {
+export const initRemixPlugin = () => {
const plugin = new PluginClient({ allowOrigins: ['https://remix.ethereum.org'] });
const client = createClient(plugin);
diff --git a/src/routes/+page.svelte b/src/routes/+page.svelte
index df960dc..cdd30c4 100644
--- a/src/routes/+page.svelte
+++ b/src/routes/+page.svelte
@@ -1,5 +1,5 @@
-
- To get started with Deploy With Defender , you need to
- have an
- OpenZeppelin Defender Account
- (It's free) and setup an
-
+ To get started with Deploy With Defender , you need to
+ have an
+ OpenZeppelin Defender Account
+ (It's free) and setup an
+
+ API Key and Secret .
- API Key and Secret .
-
+
+ {/if}
+
+ {#if parent === 'wizard'}
+
Defender Deploy in Wizard
+ {/if}
{#if globalState.error}
From 96e76d9af2e3b0e55602453a3ee4529696ef91b3 Mon Sep 17 00:00:00 2001
From: Marcos
Date: Mon, 2 Dec 2024 18:25:34 -0300
Subject: [PATCH 02/34] split wizard from remix UI
---
src/lib/remix/compiler.ts | 2 +-
.../components/ApprovalProcess.svelte | 2 +-
.../components/Deploy.svelte} | 2 +-
src/lib/{ => remix}/components/Network.svelte | 2 +-
src/lib/{ => remix}/components/Setup.svelte | 2 +-
.../components/shared/Button.svelte | 0
.../components/shared/Dropdown.svelte | 0
src/lib/{ => remix}/state/state.svelte.ts | 0
src/lib/wizard/index.ts | 4 +
src/routes/+page.svelte | 160 ++----------------
src/routes/remix.svelte | 142 ++++++++++++++++
src/routes/wizard.svelte | 4 +
12 files changed, 170 insertions(+), 150 deletions(-)
rename src/lib/{ => remix}/components/ApprovalProcess.svelte (99%)
rename src/lib/{components/Depoy.svelte => remix/components/Deploy.svelte} (99%)
rename src/lib/{ => remix}/components/Network.svelte (96%)
rename src/lib/{ => remix}/components/Setup.svelte (97%)
rename src/lib/{ => remix}/components/shared/Button.svelte (100%)
rename src/lib/{ => remix}/components/shared/Dropdown.svelte (100%)
rename src/lib/{ => remix}/state/state.svelte.ts (100%)
create mode 100644 src/lib/wizard/index.ts
create mode 100644 src/routes/remix.svelte
create mode 100644 src/routes/wizard.svelte
diff --git a/src/lib/remix/compiler.ts b/src/lib/remix/compiler.ts
index ab3233d..efeff24 100644
--- a/src/lib/remix/compiler.ts
+++ b/src/lib/remix/compiler.ts
@@ -1,4 +1,4 @@
-import { globalState } from "$lib/state/state.svelte";
+import { globalState } from "$lib/remix/state/state.svelte";
import type { PluginClient } from "@remixproject/plugin"
import type { CompilationFileSources, CompilationResult, lastCompilationResult } from "@remixproject/plugin-api";
diff --git a/src/lib/components/ApprovalProcess.svelte b/src/lib/remix/components/ApprovalProcess.svelte
similarity index 99%
rename from src/lib/components/ApprovalProcess.svelte
rename to src/lib/remix/components/ApprovalProcess.svelte
index bb7f430..ae873a8 100644
--- a/src/lib/components/ApprovalProcess.svelte
+++ b/src/lib/remix/components/ApprovalProcess.svelte
@@ -1,5 +1,5 @@
- {#if parent === 'remix'}
-
- To get started with Deploy With Defender , you need to
- have an
- OpenZeppelin Defender Account
- (It's free) and setup an
-
- API Key and Secret .
-
+ {#if parent === 'none'}
+
⚠️ This page is meant to be embedded in an iframe! ⚠️
{/if}
{#if parent === 'wizard'}
-
Defender Deploy in Wizard
+
{/if}
- {#if globalState.error}
-
-
{globalState.error ?? ""}
-
+ {#if parent === 'remix'}
+
{/if}
-
-
- {#each [0, 1, 2, 3] as index}
-
-
-
- {#if currentTab === index}
-
-
- {#if index === 0}
wait(1000).then(() => toggle(1))}/>{/if}
- {#if index === 1} wait(1000).then(() => toggle(2))}/>{/if}
- {#if index === 2} {/if}
- {#if index === 3} {/if}
-
-
- {/if}
-
- {/each}
-
-
diff --git a/src/routes/remix.svelte b/src/routes/remix.svelte
new file mode 100644
index 0000000..1ea85d3
--- /dev/null
+++ b/src/routes/remix.svelte
@@ -0,0 +1,142 @@
+
+
+
+ To get started with Deploy With Defender , you need to
+ have an
+ OpenZeppelin Defender Account
+ (It's free) and setup an
+
+ API Key and Secret .
+
+
+{#if globalState.error}
+
+
{globalState.error ?? ""}
+
+{/if}
+
+
+ {#each [0, 1, 2, 3] as index}
+
+
+
+ {#if currentTab === index}
+
+
+ {#if index === 0}
wait(1000).then(() => toggle(1))}/>{/if}
+ {#if index === 1} wait(1000).then(() => toggle(2))}/>{/if}
+ {#if index === 2} {/if}
+ {#if index === 3} {/if}
+
+
+ {/if}
+
+ {/each}
+
+
+
diff --git a/src/routes/wizard.svelte b/src/routes/wizard.svelte
new file mode 100644
index 0000000..105abb4
--- /dev/null
+++ b/src/routes/wizard.svelte
@@ -0,0 +1,4 @@
+
+
+Defender Deploy in Wizard
\ No newline at end of file
From c79fc0c8798a2a59201999a8e59de4bdb1ca57bd Mon Sep 17 00:00:00 2001
From: Marcos
Date: Tue, 3 Dec 2024 08:17:36 -0300
Subject: [PATCH 03/34] feat: install compiler and setup
---
package.json | 3 +-
pnpm-lock.yaml | 57 ++++++++++++++++++++++++++++++++++++++
src/lib/models/solc.ts | 20 +++++++++++++
src/lib/wizard/compiler.ts | 23 +++++++++++++++
4 files changed, 102 insertions(+), 1 deletion(-)
create mode 100644 src/lib/models/solc.ts
create mode 100644 src/lib/wizard/compiler.ts
diff --git a/package.json b/package.json
index ed54db7..5cc57b4 100644
--- a/package.json
+++ b/package.json
@@ -26,6 +26,7 @@
"@remixproject/plugin-utils": "^0.3.38",
"@sveltejs/adapter-netlify": "^4.3.6",
"bootstrap": "^5.3.3",
- "ethers": "^6.13.4"
+ "ethers": "^6.13.4",
+ "solc": "^0.8.28"
}
}
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index fbd3b7e..927600d 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -32,6 +32,9 @@ importers:
ethers:
specifier: ^6.13.4
version: 6.13.4
+ solc:
+ specifier: ^0.8.28
+ version: 0.8.28
devDependencies:
'@sveltejs/adapter-auto':
specifier: ^3.0.0
@@ -660,6 +663,13 @@ packages:
resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==}
engines: {node: '>= 0.8'}
+ command-exists@1.2.9:
+ resolution: {integrity: sha512-LTQ/SGc+s0Xc0Fu5WaKnR0YiygZkm9eKFvyS+fRsU7/ZWFF8ykFM6Pc9aCVf1+xasOOZpO3BAVgVrKvsqKHV7w==}
+
+ commander@8.3.0:
+ resolution: {integrity: sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==}
+ engines: {node: '>= 12'}
+
cookie@0.6.0:
resolution: {integrity: sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==}
engines: {node: '>= 0.6'}
@@ -926,6 +936,10 @@ packages:
magic-string@0.30.12:
resolution: {integrity: sha512-Ea8I3sQMVXr8JhN4z+H/d8zwo+tYDgHE9+5G4Wnrwhs0gaK9fXTKx0Tw5Xwsd/bCPTTZNRAdpyzvoeORe9LYpw==}
+ memorystream@0.3.1:
+ resolution: {integrity: sha512-S3UwM3yj5mtUSEfP41UZmt/0SCoVYUcU1rkXv+BQ5Ig8ndL4sPoJNBUJERafdPb5jjHJGuMgytgKvKIf58XNBw==}
+ engines: {node: '>= 0.10.0'}
+
mime-db@1.52.0:
resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==}
engines: {node: '>= 0.6'}
@@ -973,6 +987,10 @@ packages:
encoding:
optional: true
+ os-tmpdir@1.0.2:
+ resolution: {integrity: sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==}
+ engines: {node: '>=0.10.0'}
+
package-json-from-dist@1.0.1:
resolution: {integrity: sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==}
@@ -1027,6 +1045,10 @@ packages:
safe-buffer@5.1.2:
resolution: {integrity: sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==}
+ semver@5.7.2:
+ resolution: {integrity: sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==}
+ hasBin: true
+
set-cookie-parser@2.7.1:
resolution: {integrity: sha512-IOc8uWeOZgnb3ptbCURJWNjWUPcO3ZnTTdzsurqERrP6nPyv+paC55vJM0LpOlT2ne+Ix+9+CRG1MNLlyZ4GjQ==}
@@ -1053,6 +1075,11 @@ packages:
resolution: {integrity: sha512-BPwJGUeDaDCHihkORDchNyyTvWFhcusy1XMmhEVTQTwGeybFbp8YEmB+njbPnth1FibULBSBVwCQni25XlCUDg==}
engines: {node: '>=18'}
+ solc@0.8.28:
+ resolution: {integrity: sha512-AFCiJ+b4RosyyNhnfdVH4ZR1+TxiL91iluPjw0EJslIu4LXGM9NYqi2z5y8TqochC4tcH9QsHfwWhOIC9jPDKA==}
+ engines: {node: '>=10.0.0'}
+ hasBin: true
+
source-map-js@1.2.1:
resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==}
engines: {node: '>=0.10.0'}
@@ -1091,6 +1118,10 @@ packages:
tiny-glob@0.2.9:
resolution: {integrity: sha512-g/55ssRPUjShh+xkfx9UPDXqhckHEsHr4Vd9zX55oSdGZc/MD0m3sferOkwWtp98bv+kcVfEHtRJgBVJzelrzg==}
+ tmp@0.0.33:
+ resolution: {integrity: sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==}
+ engines: {node: '>=0.6.0'}
+
totalist@3.0.1:
resolution: {integrity: sha512-sf4i37nQ2LBx4m3wB74y+ubopq6W/dIzXg0FDGjsYnZHVa1Da8FH853wlL2gtUhg+xJXjfk3kUZS3BRoQeoQBQ==}
engines: {node: '>=6'}
@@ -2048,6 +2079,10 @@ snapshots:
dependencies:
delayed-stream: 1.0.0
+ command-exists@1.2.9: {}
+
+ commander@8.3.0: {}
+
cookie@0.6.0: {}
core-util-is@1.0.3: {}
@@ -2330,6 +2365,8 @@ snapshots:
dependencies:
'@jridgewell/sourcemap-codec': 1.5.0
+ memorystream@0.3.1: {}
+
mime-db@1.52.0: {}
mime-types@2.1.35:
@@ -2358,6 +2395,8 @@ snapshots:
dependencies:
whatwg-url: 5.0.0
+ os-tmpdir@1.0.2: {}
+
package-json-from-dist@1.0.1: {}
pako@1.0.11: {}
@@ -2427,6 +2466,8 @@ snapshots:
safe-buffer@5.1.2: {}
+ semver@5.7.2: {}
+
set-cookie-parser@2.7.1: {}
set-function-length@1.2.2:
@@ -2454,6 +2495,18 @@ snapshots:
mrmime: 2.0.0
totalist: 3.0.1
+ solc@0.8.28:
+ dependencies:
+ command-exists: 1.2.9
+ commander: 8.3.0
+ follow-redirects: 1.15.9
+ js-sha3: 0.8.0
+ memorystream: 0.3.1
+ semver: 5.7.2
+ tmp: 0.0.33
+ transitivePeerDependencies:
+ - debug
+
source-map-js@1.2.1: {}
string-width@4.2.3:
@@ -2513,6 +2566,10 @@ snapshots:
globalyzer: 0.1.0
globrex: 0.1.2
+ tmp@0.0.33:
+ dependencies:
+ os-tmpdir: 1.0.2
+
totalist@3.0.1: {}
tr46@0.0.3: {}
diff --git a/src/lib/models/solc.ts b/src/lib/models/solc.ts
new file mode 100644
index 0000000..f63b98d
--- /dev/null
+++ b/src/lib/models/solc.ts
@@ -0,0 +1,20 @@
+export type CompilerInput = {
+ /**
+ * The language, currently only Solidity is supported.
+ */
+ language: string;
+ /**
+ * Name of the file and the content of the file.
+ * e.g. { 'test.sol': { content: 'contract C { function f() public { L.f(); } }' } }
+ */
+ sources: Record;
+ /**
+ * Settings for the compiler.
+ * e.g. { outputSelection: { '*': { '*': ['*'] } }"
+ */
+ settings: {
+ outputSelection: Record>;
+ };
+};
+
+export type ImportContents = Record;
\ No newline at end of file
diff --git a/src/lib/wizard/compiler.ts b/src/lib/wizard/compiler.ts
new file mode 100644
index 0000000..ed0f5cc
--- /dev/null
+++ b/src/lib/wizard/compiler.ts
@@ -0,0 +1,23 @@
+const solc = require('solc');
+
+import type { ImportContents } from "$lib/models/solc";
+import type { CompilerInput } from "$lib/models/solc";
+
+export class SolidityCompiler {
+ getContent(path: string, contents: Record) {
+ if (contents[path]) {
+ return contents[path];
+ }
+ return { error: 'File not found' };
+ }
+
+ compile(input: CompilerInput, contents: ImportContents) {
+ const findImports = (path: string) => this.getContent(path, contents);
+ const output = solc.compile(JSON.stringify(input), { import: findImports });
+ return output;
+ }
+}
+
+export const Compiler = new SolidityCompiler();
+
+
From 39bceb83d1c544271d4d5d0cd1ec02a7fc416770 Mon Sep 17 00:00:00 2001
From: Marcos
Date: Tue, 3 Dec 2024 09:29:03 -0300
Subject: [PATCH 04/34] feat: add support to solidity compiler
---
src/app.d.ts | 5 +++++
src/lib/api.ts | 11 +++++++++++
src/lib/wizard/compiler.ts | 23 -----------------------
src/lib/wizard/index.ts | 4 +---
src/routes/compiler/+server.ts | 19 +++++++++++++++++++
src/routes/compiler/compiler.ts | 20 ++++++++++++++++++++
src/routes/wizard.svelte | 6 +++++-
7 files changed, 61 insertions(+), 27 deletions(-)
delete mode 100644 src/lib/wizard/compiler.ts
create mode 100644 src/routes/compiler/+server.ts
create mode 100644 src/routes/compiler/compiler.ts
diff --git a/src/app.d.ts b/src/app.d.ts
index ad92508..f122aeb 100644
--- a/src/app.d.ts
+++ b/src/app.d.ts
@@ -13,3 +13,8 @@ declare global {
declare interface Window {
ethereum?: import('ethers').Eip1193Provider & import('ethers').BrowserProvider;
}
+
+// solc does not have a type definition file.
+declare module 'solc' {
+ export function compile(input: string, opts?: any): any;
+}
\ No newline at end of file
diff --git a/src/lib/api.ts b/src/lib/api.ts
index 38a29c4..26180f0 100644
--- a/src/lib/api.ts
+++ b/src/lib/api.ts
@@ -1,6 +1,7 @@
import type { CreateApprovalProcessRequest } from "./models/approval-process";
import type { Credentials } from "./models/auth";
import type { DeployContractRequest, UpdateDeploymentRequest } from "./models/deploy";
+import type { CompilerInput } from "./models/solc";
class ApiClient {
credentials: Credentials | null = null;
@@ -72,6 +73,16 @@ class ApiClient {
return response.json();
}
+
+ async compile(input: CompilerInput) {
+ const response = await fetch("/compiler", {
+ method: "POST",
+ headers: { "Content-Type": "application/json" },
+ body: JSON.stringify({ input }),
+ });
+
+ return response.json();
+ }
}
export const API = new ApiClient();
diff --git a/src/lib/wizard/compiler.ts b/src/lib/wizard/compiler.ts
deleted file mode 100644
index ed0f5cc..0000000
--- a/src/lib/wizard/compiler.ts
+++ /dev/null
@@ -1,23 +0,0 @@
-const solc = require('solc');
-
-import type { ImportContents } from "$lib/models/solc";
-import type { CompilerInput } from "$lib/models/solc";
-
-export class SolidityCompiler {
- getContent(path: string, contents: Record) {
- if (contents[path]) {
- return contents[path];
- }
- return { error: 'File not found' };
- }
-
- compile(input: CompilerInput, contents: ImportContents) {
- const findImports = (path: string) => this.getContent(path, contents);
- const output = solc.compile(JSON.stringify(input), { import: findImports });
- return output;
- }
-}
-
-export const Compiler = new SolidityCompiler();
-
-
diff --git a/src/lib/wizard/index.ts b/src/lib/wizard/index.ts
index eba0485..53ea232 100644
--- a/src/lib/wizard/index.ts
+++ b/src/lib/wizard/index.ts
@@ -1,4 +1,2 @@
export const initWizardPlugin = () => {
- // when users configure a contract, the plugin gets the results.
- // listenToContracts();
-}
+}
\ No newline at end of file
diff --git a/src/routes/compiler/+server.ts b/src/routes/compiler/+server.ts
new file mode 100644
index 0000000..09a1d47
--- /dev/null
+++ b/src/routes/compiler/+server.ts
@@ -0,0 +1,19 @@
+import type { CompilerInput } from "$lib/models/solc";
+import { json } from '@sveltejs/kit';
+import { SolidityCompiler } from "./compiler";
+import { attempt } from "$lib/utils/attempt";
+
+
+export async function POST({ request }: { request: Request }) {
+ const { input }: { input: CompilerInput } = await request.json();
+
+ const compiler = new SolidityCompiler();
+
+ const [output, error] = await attempt(() => JSON.parse(compiler.compile(input)));
+
+ if (error) {
+ return json({ success: false, error: error.msg });
+ }
+
+ return json({ success: true, data: { output } });
+}
\ No newline at end of file
diff --git a/src/routes/compiler/compiler.ts b/src/routes/compiler/compiler.ts
new file mode 100644
index 0000000..55cc516
--- /dev/null
+++ b/src/routes/compiler/compiler.ts
@@ -0,0 +1,20 @@
+import solc from 'solc';
+
+import type { ImportContents } from "$lib/models/solc";
+import type { CompilerInput } from "$lib/models/solc";
+
+export class SolidityCompiler {
+ getContent(path: string, contents: Record) {
+ if (contents[path]) {
+ return contents[path];
+ }
+ return { error: 'File not found' };
+ }
+
+ compile(input: CompilerInput, contents?: ImportContents) {
+ const shouldFindImports = contents !== undefined;
+ const findImports = (path: string) => shouldFindImports ? this.getContent(path, contents) : undefined;
+ const output = solc.compile(JSON.stringify(input), shouldFindImports ? { import: findImports } : undefined);
+ return output;
+ }
+}
diff --git a/src/routes/wizard.svelte b/src/routes/wizard.svelte
index 105abb4..01cc9b5 100644
--- a/src/routes/wizard.svelte
+++ b/src/routes/wizard.svelte
@@ -1,4 +1,8 @@
-Defender Deploy in Wizard
\ No newline at end of file
+Defender Deploy in Wizard
From ecd01cccff0bf99daf43c947c5a0b681d9d2d848 Mon Sep 17 00:00:00 2001
From: Marcos
Date: Tue, 3 Dec 2024 09:32:10 -0300
Subject: [PATCH 05/34] fmt
---
src/lib/models/solc.ts | 2 +-
src/lib/wizard/index.ts | 2 +-
src/routes/compiler/+server.ts | 2 +-
3 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/src/lib/models/solc.ts b/src/lib/models/solc.ts
index f63b98d..d7a3c25 100644
--- a/src/lib/models/solc.ts
+++ b/src/lib/models/solc.ts
@@ -17,4 +17,4 @@ export type CompilerInput = {
};
};
-export type ImportContents = Record;
\ No newline at end of file
+export type ImportContents = Record;
diff --git a/src/lib/wizard/index.ts b/src/lib/wizard/index.ts
index 53ea232..01cde03 100644
--- a/src/lib/wizard/index.ts
+++ b/src/lib/wizard/index.ts
@@ -1,2 +1,2 @@
export const initWizardPlugin = () => {
-}
\ No newline at end of file
+}
diff --git a/src/routes/compiler/+server.ts b/src/routes/compiler/+server.ts
index 09a1d47..fcb0260 100644
--- a/src/routes/compiler/+server.ts
+++ b/src/routes/compiler/+server.ts
@@ -16,4 +16,4 @@ export async function POST({ request }: { request: Request }) {
}
return json({ success: true, data: { output } });
-}
\ No newline at end of file
+}
From 9ce364f150b5853d54fb91e5a13186129a279ba5 Mon Sep 17 00:00:00 2001
From: Marcos
Date: Tue, 3 Dec 2024 09:34:17 -0300
Subject: [PATCH 06/34] fmt
---
src/app.d.ts | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/app.d.ts b/src/app.d.ts
index f122aeb..e2c24df 100644
--- a/src/app.d.ts
+++ b/src/app.d.ts
@@ -17,4 +17,4 @@ declare interface Window {
// solc does not have a type definition file.
declare module 'solc' {
export function compile(input: string, opts?: any): any;
-}
\ No newline at end of file
+}
From 847d7e96431540a63f41b4c31207ddb84457ebf3 Mon Sep 17 00:00:00 2001
From: Marcos
Date: Tue, 3 Dec 2024 15:38:49 -0300
Subject: [PATCH 07/34] feat: listen to wizard changes
---
src/lib/wizard/components/Configure.svelte | 9 +++
src/lib/wizard/index.ts | 13 +++-
src/lib/wizard/models/contract.ts | 76 ++++++++++++++++++++++
src/lib/wizard/state.svelte.ts | 6 ++
src/routes/+page.svelte | 15 ++---
src/routes/remix.svelte | 4 ++
src/routes/wizard.svelte | 7 +-
7 files changed, 119 insertions(+), 11 deletions(-)
create mode 100644 src/lib/wizard/components/Configure.svelte
create mode 100644 src/lib/wizard/models/contract.ts
create mode 100644 src/lib/wizard/state.svelte.ts
diff --git a/src/lib/wizard/components/Configure.svelte b/src/lib/wizard/components/Configure.svelte
new file mode 100644
index 0000000..b62fc13
--- /dev/null
+++ b/src/lib/wizard/components/Configure.svelte
@@ -0,0 +1,9 @@
+
+
+
+
+ Contract: {JSON.stringify(wizardState.contract, null, 2)}
+
diff --git a/src/lib/wizard/index.ts b/src/lib/wizard/index.ts
index eba0485..cf783fc 100644
--- a/src/lib/wizard/index.ts
+++ b/src/lib/wizard/index.ts
@@ -1,4 +1,15 @@
+import type { DefenderDeployMessage } from "./models/contract";
+import { globalState } from "./state.svelte";
+
export const initWizardPlugin = () => {
// when users configure a contract, the plugin gets the results.
- // listenToContracts();
+ listenToContracts();
+}
+
+function listenToContracts() {
+ window.addEventListener('message', function (e: MessageEvent) {
+ if (e.data.kind === 'oz-wizard-defender-deploy') {
+ globalState.contract = e.data.contract;
+ }
+ });
}
diff --git a/src/lib/wizard/models/contract.ts b/src/lib/wizard/models/contract.ts
new file mode 100644
index 0000000..bf524fc
--- /dev/null
+++ b/src/lib/wizard/models/contract.ts
@@ -0,0 +1,76 @@
+/**
+ * Interfaces for the contract object returned by the wizard.
+ */
+
+export interface Contract {
+ name: string;
+ license: string;
+ parents: Parent[];
+ natspecTags: NatspecTag[];
+ imports: ImportContract[];
+ functions: ContractFunction[];
+ constructorCode: string[];
+ constructorArgs: FunctionArgument[];
+ variables: string[];
+ upgradeable: boolean;
+}
+
+export interface NatspecTag {
+ key: string;
+ value: string;
+}
+
+export type Value = string | number | { lit: string } | { note: string, value: Value };
+
+export interface Parent {
+ contract: ImportContract;
+ params: Value[];
+ importOnly?: boolean;
+}
+
+export interface ImportContract extends ReferencedContract {
+ path: string;
+}
+
+export interface ReferencedContract {
+ name: string;
+ transpiled?: boolean;
+}
+
+export interface Using {
+ library: ImportContract;
+ usingFor: string;
+}
+
+export interface BaseFunction {
+ name: string;
+ args: FunctionArgument[];
+ returns?: string[];
+ kind: FunctionKind;
+ mutability?: FunctionMutability;
+}
+
+export interface ContractFunction extends BaseFunction {
+ override: Set;
+ modifiers: string[];
+ code: string[];
+ mutability: FunctionMutability;
+ final: boolean;
+ comments: string[];
+}
+
+export type FunctionKind = 'internal' | 'public';
+export type FunctionMutability = typeof mutabilityRank[number];
+
+// Order is important
+const mutabilityRank = ['pure', 'view', 'nonpayable', 'payable'] as const;
+
+export interface FunctionArgument {
+ type: string | ReferencedContract;
+ name: string;
+}
+
+export interface DefenderDeployMessage {
+ kind: 'oz-wizard-defender-deploy';
+ contract: Contract;
+}
diff --git a/src/lib/wizard/state.svelte.ts b/src/lib/wizard/state.svelte.ts
new file mode 100644
index 0000000..3c60954
--- /dev/null
+++ b/src/lib/wizard/state.svelte.ts
@@ -0,0 +1,6 @@
+
+import type { Contract } from "./models/contract";
+
+export const wizardState = $state<{ contract: Contract | undefined }>({
+ contract: undefined,
+});
diff --git a/src/routes/+page.svelte b/src/routes/+page.svelte
index 51c8760..9703914 100644
--- a/src/routes/+page.svelte
+++ b/src/routes/+page.svelte
@@ -20,20 +20,17 @@
// assumes that when in dev mode and
// the ancestor origin is localhost, we are in the wizard
if (dev && ancestorOrigin.includes("localhost")) {
- parent = 'wizard';
- return;
+ return parent = 'wizard';
}
- if (ancestorOrigin.includes("remix.ethereum")) {
- parent = 'remix';
- return initRemixPlugin();
+ if (ancestorOrigin.includes("wizard.openzeppelin")) {
+ return parent = 'wizard';
}
- if (ancestorOrigin.includes("wizard.openzeppelin")) {
- parent = 'wizard';
- // TODO: init wizard plugin
- return;
+ if (ancestorOrigin.includes("remix.ethereum")) {
+ return parent = 'remix';
}
+
});
diff --git a/src/routes/remix.svelte b/src/routes/remix.svelte
index a36362f..6e704fc 100644
--- a/src/routes/remix.svelte
+++ b/src/routes/remix.svelte
@@ -1,4 +1,6 @@
diff --git a/src/routes/wizard.svelte b/src/routes/wizard.svelte
index 105abb4..d6faccd 100644
--- a/src/routes/wizard.svelte
+++ b/src/routes/wizard.svelte
@@ -1,4 +1,9 @@
-
Defender Deploy in Wizard
\ No newline at end of file
+
From 1505a17d0ba1dcdb2d6feb60aff497eb3867a281 Mon Sep 17 00:00:00 2001
From: Marcos
Date: Wed, 4 Dec 2024 10:15:11 -0300
Subject: [PATCH 08/34] change contract sources interface
---
src/lib/api.ts | 1 +
src/lib/wizard/components/Configure.svelte | 14 +++-
src/lib/wizard/index.ts | 11 +++-
src/lib/wizard/models/contract.ts | 76 ----------------------
src/lib/wizard/models/sources.ts | 12 ++++
src/lib/wizard/state.svelte.ts | 6 +-
6 files changed, 36 insertions(+), 84 deletions(-)
delete mode 100644 src/lib/wizard/models/contract.ts
create mode 100644 src/lib/wizard/models/sources.ts
diff --git a/src/lib/api.ts b/src/lib/api.ts
index 38a29c4..0ccf40a 100644
--- a/src/lib/api.ts
+++ b/src/lib/api.ts
@@ -1,6 +1,7 @@
import type { CreateApprovalProcessRequest } from "./models/approval-process";
import type { Credentials } from "./models/auth";
import type { DeployContractRequest, UpdateDeploymentRequest } from "./models/deploy";
+import type { ContractSources } from "./wizard/models/sources";
class ApiClient {
credentials: Credentials | null = null;
diff --git a/src/lib/wizard/components/Configure.svelte b/src/lib/wizard/components/Configure.svelte
index b62fc13..97015bc 100644
--- a/src/lib/wizard/components/Configure.svelte
+++ b/src/lib/wizard/components/Configure.svelte
@@ -1,9 +1,19 @@
+ async function compile() {
+ // if (!wizardState.sources) return;
+ // const result = await API.compile(wizardState.sources);
+ // console.log(result);
+ }
+
- Contract: {JSON.stringify(wizardState.contract, null, 2)}
+ Contract to compile: {wizardState.sources?.target}
+
+
+ Compile
+
diff --git a/src/lib/wizard/index.ts b/src/lib/wizard/index.ts
index cf783fc..c39e2da 100644
--- a/src/lib/wizard/index.ts
+++ b/src/lib/wizard/index.ts
@@ -1,5 +1,10 @@
-import type { DefenderDeployMessage } from "./models/contract";
-import { globalState } from "./state.svelte";
+import type { ContractSources } from "./models/sources";
+import { wizardState } from "./state.svelte";
+
+export interface DefenderDeployMessage {
+ kind: 'oz-wizard-defender-deploy';
+ sources: ContractSources;
+}
export const initWizardPlugin = () => {
// when users configure a contract, the plugin gets the results.
@@ -9,7 +14,7 @@ export const initWizardPlugin = () => {
function listenToContracts() {
window.addEventListener('message', function (e: MessageEvent) {
if (e.data.kind === 'oz-wizard-defender-deploy') {
- globalState.contract = e.data.contract;
+ wizardState.sources = e.data.sources;
}
});
}
diff --git a/src/lib/wizard/models/contract.ts b/src/lib/wizard/models/contract.ts
deleted file mode 100644
index bf524fc..0000000
--- a/src/lib/wizard/models/contract.ts
+++ /dev/null
@@ -1,76 +0,0 @@
-/**
- * Interfaces for the contract object returned by the wizard.
- */
-
-export interface Contract {
- name: string;
- license: string;
- parents: Parent[];
- natspecTags: NatspecTag[];
- imports: ImportContract[];
- functions: ContractFunction[];
- constructorCode: string[];
- constructorArgs: FunctionArgument[];
- variables: string[];
- upgradeable: boolean;
-}
-
-export interface NatspecTag {
- key: string;
- value: string;
-}
-
-export type Value = string | number | { lit: string } | { note: string, value: Value };
-
-export interface Parent {
- contract: ImportContract;
- params: Value[];
- importOnly?: boolean;
-}
-
-export interface ImportContract extends ReferencedContract {
- path: string;
-}
-
-export interface ReferencedContract {
- name: string;
- transpiled?: boolean;
-}
-
-export interface Using {
- library: ImportContract;
- usingFor: string;
-}
-
-export interface BaseFunction {
- name: string;
- args: FunctionArgument[];
- returns?: string[];
- kind: FunctionKind;
- mutability?: FunctionMutability;
-}
-
-export interface ContractFunction extends BaseFunction {
- override: Set;
- modifiers: string[];
- code: string[];
- mutability: FunctionMutability;
- final: boolean;
- comments: string[];
-}
-
-export type FunctionKind = 'internal' | 'public';
-export type FunctionMutability = typeof mutabilityRank[number];
-
-// Order is important
-const mutabilityRank = ['pure', 'view', 'nonpayable', 'payable'] as const;
-
-export interface FunctionArgument {
- type: string | ReferencedContract;
- name: string;
-}
-
-export interface DefenderDeployMessage {
- kind: 'oz-wizard-defender-deploy';
- contract: Contract;
-}
diff --git a/src/lib/wizard/models/sources.ts b/src/lib/wizard/models/sources.ts
new file mode 100644
index 0000000..adde68f
--- /dev/null
+++ b/src/lib/wizard/models/sources.ts
@@ -0,0 +1,12 @@
+
+
+export interface ContractSources {
+ target: string;
+ sources: SolcInputSources;
+}
+
+export interface SolcInputSources {
+ [source: string]: {
+ content: string;
+ };
+}
\ No newline at end of file
diff --git a/src/lib/wizard/state.svelte.ts b/src/lib/wizard/state.svelte.ts
index 3c60954..d5c9a40 100644
--- a/src/lib/wizard/state.svelte.ts
+++ b/src/lib/wizard/state.svelte.ts
@@ -1,6 +1,6 @@
-import type { Contract } from "./models/contract";
+import type { ContractSources } from "./models/sources";
-export const wizardState = $state<{ contract: Contract | undefined }>({
- contract: undefined,
+export const wizardState = $state<{ sources: ContractSources | undefined }>({
+ sources: undefined,
});
From 492c6703dc26d8c59f70389e13786fc730c067da Mon Sep 17 00:00:00 2001
From: Marcos
Date: Wed, 4 Dec 2024 11:58:32 -0300
Subject: [PATCH 09/34] fix: load contract to compile
---
src/lib/wizard/components/Configure.svelte | 17 ++++++++++-------
1 file changed, 10 insertions(+), 7 deletions(-)
diff --git a/src/lib/wizard/components/Configure.svelte b/src/lib/wizard/components/Configure.svelte
index 5557dfb..e9eb6b9 100644
--- a/src/lib/wizard/components/Configure.svelte
+++ b/src/lib/wizard/components/Configure.svelte
@@ -1,24 +1,27 @@
- Contract to compile: {wizardState.sources?.target}
+ Contract to compile: {getMainContractName(wizardState.sources)}
Compile
-
- result: {JSON.stringify(result, null, 2)}
From 03083036f3d507f222f376132ae0ea78e7f364cf Mon Sep 17 00:00:00 2001
From: Marcos
Date: Wed, 4 Dec 2024 16:29:35 -0300
Subject: [PATCH 10/34] add support to tailwind + add initial styles
---
package.json | 3 +
pnpm-lock.yaml | 609 +++++++++++++++++-
postcss.config.js | 6 +
.../wizard/components/Configuration.svelte | 53 ++
src/lib/wizard/components/Configure.svelte | 27 -
src/lib/wizard/components/Network.svelte | 19 +
.../wizard/components/shared/Dropdown.svelte | 61 ++
src/lib/wizard/state.svelte.ts | 4 +-
src/routes/+page.svelte | 11 +-
src/routes/wizard.svelte | 47 +-
src/wizard-app.css | 3 +
tailwind.config.js | 9 +
12 files changed, 811 insertions(+), 41 deletions(-)
create mode 100644 postcss.config.js
create mode 100644 src/lib/wizard/components/Configuration.svelte
delete mode 100644 src/lib/wizard/components/Configure.svelte
create mode 100644 src/lib/wizard/components/Network.svelte
create mode 100644 src/lib/wizard/components/shared/Dropdown.svelte
create mode 100644 src/wizard-app.css
create mode 100644 tailwind.config.js
diff --git a/package.json b/package.json
index 5cc57b4..dbe9cb2 100644
--- a/package.json
+++ b/package.json
@@ -13,8 +13,11 @@
"@sveltejs/adapter-auto": "^3.0.0",
"@sveltejs/kit": "^2.0.0",
"@sveltejs/vite-plugin-svelte": "^4.0.0",
+ "autoprefixer": "^10.4.20",
+ "postcss": "^8.4.49",
"svelte": "^5.0.0",
"svelte-check": "^4.0.0",
+ "tailwindcss": "^3.4.16",
"typescript": "^5.0.0",
"vite": "^5.0.3"
},
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 927600d..dabf56c 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -45,12 +45,21 @@ importers:
'@sveltejs/vite-plugin-svelte':
specifier: ^4.0.0
version: 4.0.0(svelte@5.1.6)(vite@5.4.10(@types/node@22.9.0))
+ autoprefixer:
+ specifier: ^10.4.20
+ version: 10.4.20(postcss@8.4.49)
+ postcss:
+ specifier: ^8.4.49
+ version: 8.4.49
svelte:
specifier: ^5.0.0
version: 5.1.6
svelte-check:
specifier: ^4.0.0
version: 4.0.5(svelte@5.1.6)(typescript@5.6.3)
+ tailwindcss:
+ specifier: ^3.4.16
+ version: 3.4.16
typescript:
specifier: ^5.0.0
version: 5.6.3
@@ -66,6 +75,10 @@ packages:
'@adraffy/ens-normalize@1.11.0':
resolution: {integrity: sha512-/3DDPKHqqIqxUULp8yP4zODUY1i+2xvVWsv8A79xGWdCAG+8sb0hRh0Rk2QyOJUnnbyPUAZYcpBuRe3nS2OIUg==}
+ '@alloc/quick-lru@5.2.0':
+ resolution: {integrity: sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==}
+ engines: {node: '>=10'}
+
'@ampproject/remapping@2.3.0':
resolution: {integrity: sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==}
engines: {node: '>=6.0.0'}
@@ -333,6 +346,18 @@ packages:
resolution: {integrity: sha512-V1JJ1WTRUqHHrOSh597hURcMqVKVGL/ea3kv0gSnEdsEZ0/+VyPghM1lMNGc00z7CIQorSvbKpuJkxvuHbvdbg==}
engines: {node: '>= 16'}
+ '@nodelib/fs.scandir@2.1.5':
+ resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==}
+ engines: {node: '>= 8'}
+
+ '@nodelib/fs.stat@2.0.5':
+ resolution: {integrity: sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==}
+ engines: {node: '>= 8'}
+
+ '@nodelib/fs.walk@1.2.8':
+ resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==}
+ engines: {node: '>= 8'}
+
'@openzeppelin/defender-sdk-account-client@1.15.2':
resolution: {integrity: sha512-lhYf1rBtac1MBbKP/ALgkjUhVulqo45RtaemTP9xI6BwUCCb4nq2SSKM82UN5sOE2I+VXSbPXf8w91bao5Mmmg==}
@@ -383,6 +408,10 @@ packages:
'@openzeppelin/defender-sdk@1.15.2':
resolution: {integrity: sha512-Pt7MR+kzhsBfEQvW/cAOgLGb498x3Oq91G15GQ+g+cl978IpQgqx8rneZPv3aoQE5ipIk6EtWJlOl+tIAARKVg==}
+ '@pkgjs/parseargs@0.11.0':
+ resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==}
+ engines: {node: '>=14'}
+
'@polka/url@1.0.0-next.28':
resolution: {integrity: sha512-8LduaNlMZGwdZ6qWrKlfa+2M4gahzFkprZiAt2TF8uS0qQgBizKXpXURqvTJ4WtmupWxaLqjRb2UCTe72mu+Aw==}
@@ -594,6 +623,16 @@ packages:
resolution: {integrity: sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==}
engines: {node: '>=12'}
+ any-promise@1.3.0:
+ resolution: {integrity: sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==}
+
+ anymatch@3.1.3:
+ resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==}
+ engines: {node: '>= 8'}
+
+ arg@5.0.2:
+ resolution: {integrity: sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==}
+
aria-query@5.3.2:
resolution: {integrity: sha512-COROpnaoap1E2F000S62r6A60uHZnmlvomhfyT2DlTcrY1OrBKn2UhH7qn5wTC9zMvD0AY7csdPSNwKP+7WiQw==}
engines: {node: '>= 0.4'}
@@ -604,6 +643,13 @@ packages:
asynckit@0.4.0:
resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==}
+ autoprefixer@10.4.20:
+ resolution: {integrity: sha512-XY25y5xSv/wEoqzDyXXME4AFfkZI0P23z6Fs3YgymDnKJkCGOnkL0iTxCa85UTqaSgfcqyf3UA6+c7wUvx/16g==}
+ engines: {node: ^10 || ^12 || >=14}
+ hasBin: true
+ peerDependencies:
+ postcss: ^8.1.0
+
available-typed-arrays@1.0.7:
resolution: {integrity: sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==}
engines: {node: '>= 0.4'}
@@ -624,6 +670,10 @@ packages:
bech32@1.1.4:
resolution: {integrity: sha512-s0IrSOzLlbvX7yp4WBfPITzpAU8sqQcpsmwXDiKwrG4r491vwCO/XpejasRNl0piBMe/DvP4Tz0mIS/X1DPJBQ==}
+ binary-extensions@2.3.0:
+ resolution: {integrity: sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==}
+ engines: {node: '>=8'}
+
bn.js@4.12.0:
resolution: {integrity: sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==}
@@ -638,9 +688,18 @@ packages:
brace-expansion@2.0.1:
resolution: {integrity: sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==}
+ braces@3.0.3:
+ resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==}
+ engines: {node: '>=8'}
+
brorand@1.1.0:
resolution: {integrity: sha512-cKV8tMCEpQs4hK/ik71d6LrPOnpkpGBR0wzxqr68g2m/LB2GxVYQroAjMJZRVM1Y4BCjCKc3vAamxSzOY2RP+w==}
+ browserslist@4.24.2:
+ resolution: {integrity: sha512-ZIc+Q62revdMcqC6aChtW4jz3My3klmCO1fEmINZY/8J3EpBg5/A/D0AKmBveUh6pgoeycoMkVMko84tuYS+Gg==}
+ engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7}
+ hasBin: true
+
buffer@4.9.2:
resolution: {integrity: sha512-xq+q3SRMOxGivLhBNaUdC64hDTQwejJ+H0T/NB1XMtTVEwNTrfFF3gAxiyW0Bu/xWEGhjVKgUcMhCrUy2+uCWg==}
@@ -648,6 +707,17 @@ packages:
resolution: {integrity: sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==}
engines: {node: '>= 0.4'}
+ camelcase-css@2.0.1:
+ resolution: {integrity: sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==}
+ engines: {node: '>= 6'}
+
+ caniuse-lite@1.0.30001686:
+ resolution: {integrity: sha512-Y7deg0Aergpa24M3qLC5xjNklnKnhsmSyR/V89dLZ1n0ucJIFNs7PgR2Yfa/Zf6W79SbBicgtGxZr2juHkEUIA==}
+
+ chokidar@3.6.0:
+ resolution: {integrity: sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==}
+ engines: {node: '>= 8.10.0'}
+
chokidar@4.0.1:
resolution: {integrity: sha512-n8enUVCED/KVRQlab1hr3MVpcVMvxtZjmEa956u+4YijlmQED223XMSYj2tLuKvr4jcCTzNNMpQDUer72MMmzA==}
engines: {node: '>= 14.16.0'}
@@ -666,6 +736,10 @@ packages:
command-exists@1.2.9:
resolution: {integrity: sha512-LTQ/SGc+s0Xc0Fu5WaKnR0YiygZkm9eKFvyS+fRsU7/ZWFF8ykFM6Pc9aCVf1+xasOOZpO3BAVgVrKvsqKHV7w==}
+ commander@4.1.1:
+ resolution: {integrity: sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==}
+ engines: {node: '>= 6'}
+
commander@8.3.0:
resolution: {integrity: sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==}
engines: {node: '>= 12'}
@@ -689,6 +763,11 @@ packages:
resolution: {integrity: sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==}
engines: {node: '>= 8'}
+ cssesc@3.0.0:
+ resolution: {integrity: sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==}
+ engines: {node: '>=4'}
+ hasBin: true
+
debug@4.3.7:
resolution: {integrity: sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==}
engines: {node: '>=6.0'}
@@ -713,6 +792,12 @@ packages:
devalue@5.1.1:
resolution: {integrity: sha512-maua5KUiapvEwiEAe+XnlZ3Rh0GD+qI1J/nb9vrJc3muPXvcF/8gXYTWF76+5DAqHyDUtOIImEuo0YKE9mshVw==}
+ didyoumean@1.2.2:
+ resolution: {integrity: sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==}
+
+ dlv@1.1.3:
+ resolution: {integrity: sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==}
+
dotenv@16.4.5:
resolution: {integrity: sha512-ZmdL2rui+eB2YwhsWzjInR8LldtZHGDoQ1ugH85ppHKwpUHL7j7rN0Ti9NCnGiQbhaZ11FpR+7ao1dNsmduNUg==}
engines: {node: '>=12'}
@@ -720,6 +805,9 @@ packages:
eastasianwidth@0.2.0:
resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==}
+ electron-to-chromium@1.5.68:
+ resolution: {integrity: sha512-FgMdJlma0OzUYlbrtZ4AeXjKxKPk6KT8WOP8BjcqxWtlg8qyJQjRzPJzUtUn5GBg1oQ26hFs7HOOHJMYiJRnvQ==}
+
elliptic@6.5.4:
resolution: {integrity: sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ==}
@@ -742,6 +830,10 @@ packages:
engines: {node: '>=12'}
hasBin: true
+ escalade@3.2.0:
+ resolution: {integrity: sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==}
+ engines: {node: '>=6'}
+
esm-env@1.1.4:
resolution: {integrity: sha512-oO82nKPHKkzIj/hbtuDYy/JHqBHFlMIW36SDiPCVsj87ntDLcWN+sJ1erdVryd4NxODacFTsdrIE3b7IamqbOg==}
@@ -765,6 +857,13 @@ packages:
fast-base64-decode@1.0.0:
resolution: {integrity: sha512-qwaScUgUGBYeDNRnbc/KyllVU88Jk1pRHPStuF/lO7B0/RTRLj7U0lkdTAutlBblY08rwZDff6tNU9cjv6j//Q==}
+ fast-glob@3.3.2:
+ resolution: {integrity: sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==}
+ engines: {node: '>=8.6.0'}
+
+ fastq@1.17.1:
+ resolution: {integrity: sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==}
+
fdir@6.4.2:
resolution: {integrity: sha512-KnhMXsKSPZlAhp7+IjUkRZKPb4fUyccpDrdFXbi4QL1qkmFh9kVY09Yox+n4MaOb3lHZ1Tv829C3oaaXoMYPDQ==}
peerDependencies:
@@ -773,6 +872,10 @@ packages:
picomatch:
optional: true
+ fill-range@7.1.1:
+ resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==}
+ engines: {node: '>=8'}
+
follow-redirects@1.15.9:
resolution: {integrity: sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ==}
engines: {node: '>=4.0'}
@@ -793,6 +896,9 @@ packages:
resolution: {integrity: sha512-tzN8e4TX8+kkxGPK8D5u0FNmjPUjw3lwC9lSLxxoB/+GtsJG91CO8bSWy73APlgAZzZbXEYZJuxjkHH2w+Ezhw==}
engines: {node: '>= 6'}
+ fraction.js@4.3.7:
+ resolution: {integrity: sha512-ZsDfxO51wGAXREY55a7la9LScWpwv9RxIrYABrlvOFBlH/ShPnrtsXeuUIfXKKOVicNxQ+o8JTbJvjS4M89yew==}
+
fs-extra@11.2.0:
resolution: {integrity: sha512-PmDi3uwK5nFuXh7XDTlVnS17xJS7vW36is2+w3xcv8SVxiB4NyATf4ctkVY5bkSjX0Y4nbvZCq1/EjtEyr9ktw==}
engines: {node: '>=14.14'}
@@ -809,6 +915,18 @@ packages:
resolution: {integrity: sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==}
engines: {node: '>= 0.4'}
+ glob-parent@5.1.2:
+ resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==}
+ engines: {node: '>= 6'}
+
+ glob-parent@6.0.2:
+ resolution: {integrity: sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==}
+ engines: {node: '>=10.13.0'}
+
+ glob@10.4.5:
+ resolution: {integrity: sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==}
+ hasBin: true
+
glob@11.0.0:
resolution: {integrity: sha512-9UiX/Bl6J2yaBbxKoEBRm4Cipxgok8kQYcOPEhScPwebu2I0HoQOuYdIO6S3hLuWoZgpDpwQZMzTFxgpkyT76g==}
engines: {node: 20 || >=22}
@@ -867,10 +985,22 @@ packages:
resolution: {integrity: sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA==}
engines: {node: '>= 0.4'}
+ is-binary-path@2.1.0:
+ resolution: {integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==}
+ engines: {node: '>=8'}
+
is-callable@1.2.7:
resolution: {integrity: sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==}
engines: {node: '>= 0.4'}
+ is-core-module@2.15.1:
+ resolution: {integrity: sha512-z0vtXSwucUJtANQWldhbtbt7BnL0vxiFjIdDLAatwhDYty2bad6s+rijD6Ri4YuYJubLzIJLUidCh09e1djEVQ==}
+ engines: {node: '>= 0.4'}
+
+ is-extglob@2.1.1:
+ resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==}
+ engines: {node: '>=0.10.0'}
+
is-fullwidth-code-point@3.0.0:
resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==}
engines: {node: '>=8'}
@@ -879,6 +1009,14 @@ packages:
resolution: {integrity: sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A==}
engines: {node: '>= 0.4'}
+ is-glob@4.0.3:
+ resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==}
+ engines: {node: '>=0.10.0'}
+
+ is-number@7.0.0:
+ resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==}
+ engines: {node: '>=0.12.0'}
+
is-reference@3.0.2:
resolution: {integrity: sha512-v3rht/LgVcsdZa3O2Nqs+NMowLOxeOm7Ay9+/ARQ2F+qEoANRcqrjAZKGN0v8ymUetZGgkp26LTnGT7H0Qo9Pg==}
@@ -900,10 +1038,17 @@ packages:
peerDependencies:
ws: '*'
+ jackspeak@3.4.3:
+ resolution: {integrity: sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==}
+
jackspeak@4.0.2:
resolution: {integrity: sha512-bZsjR/iRjl1Nk1UkjGpAzLNfQtzuijhn2g+pbZb98HQ1Gk8vM9hfbxeMBP+M2/UUdwj0RqGG3mlvk2MsAqwvEw==}
engines: {node: 20 || >=22}
+ jiti@1.21.6:
+ resolution: {integrity: sha512-2yTgeWTWzMWkHu6Jp9NKgePDaYHbntiwvYuuJLbbN9vl7DC9DvXKOB2BC3ZZ92D3cvV/aflH0osDfwpHepQ53w==}
+ hasBin: true
+
js-cookie@2.2.1:
resolution: {integrity: sha512-HvdH2LzI/EAZcUwA8+0nKNtWHqS+ZmijLA30RwZA0bo7ToCckjK5MkGhjED9KoRcXO6BaGI3I9UIzSA1FKFPOQ==}
@@ -923,12 +1068,22 @@ packages:
lie@3.3.0:
resolution: {integrity: sha512-UaiMJzeWRlEujzAuw5LokY1L5ecNQYZKfmyZ9L7wDHb/p5etKaxXhohBcrw0EYby+G/NA52vRSN4N39dxHAIwQ==}
+ lilconfig@3.1.3:
+ resolution: {integrity: sha512-/vlFKAoH5Cgt3Ie+JLhRbwOsCQePABiU3tJ1egGvyQ+33R/vcwM2Zl2QR/LzjsBeItPt3oSVXapn+m4nQDvpzw==}
+ engines: {node: '>=14'}
+
+ lines-and-columns@1.2.4:
+ resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==}
+
locate-character@3.0.0:
resolution: {integrity: sha512-SW13ws7BjaeJ6p7Q6CO2nchbYEc3X3J6WrmTTDto7yMPqVSZTUyY5Tjbid+Ab8gLnATtygYtiDIJGQRRn2ZOiA==}
lodash@4.17.21:
resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==}
+ lru-cache@10.4.3:
+ resolution: {integrity: sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==}
+
lru-cache@11.0.2:
resolution: {integrity: sha512-123qHRfJBmo2jXDbo/a5YOQrJoHF/GNQTLzQ5+IdK5pWpceK17yRc6ozlWd25FxvGKQbIUs91fDFkXmDHTKcyA==}
engines: {node: 20 || >=22}
@@ -940,6 +1095,14 @@ packages:
resolution: {integrity: sha512-S3UwM3yj5mtUSEfP41UZmt/0SCoVYUcU1rkXv+BQ5Ig8ndL4sPoJNBUJERafdPb5jjHJGuMgytgKvKIf58XNBw==}
engines: {node: '>= 0.10.0'}
+ merge2@1.4.1:
+ resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==}
+ engines: {node: '>= 8'}
+
+ micromatch@4.0.8:
+ resolution: {integrity: sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==}
+ engines: {node: '>=8.6'}
+
mime-db@1.52.0:
resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==}
engines: {node: '>= 0.6'}
@@ -958,6 +1121,10 @@ packages:
resolution: {integrity: sha512-ethXTt3SGGR+95gudmqJ1eNhRO7eGEGIgYA9vnPatK4/etz2MEVDno5GMCibdMTuBMyElzIlgxMna3K94XDIDQ==}
engines: {node: 20 || >=22}
+ minimatch@9.0.5:
+ resolution: {integrity: sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==}
+ engines: {node: '>=16 || 14 >=14.17'}
+
minipass@7.1.2:
resolution: {integrity: sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==}
engines: {node: '>=16 || 14 >=14.17'}
@@ -973,6 +1140,9 @@ packages:
ms@2.1.3:
resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==}
+ mz@2.7.0:
+ resolution: {integrity: sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==}
+
nanoid@3.3.7:
resolution: {integrity: sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==}
engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1}
@@ -987,6 +1157,25 @@ packages:
encoding:
optional: true
+ node-releases@2.0.18:
+ resolution: {integrity: sha512-d9VeXT4SJ7ZeOqGX6R5EM022wpL+eWPooLI+5UpWn2jCT1aosUQEhQP214x33Wkwx3JQMvIm+tIoVOdodFS40g==}
+
+ normalize-path@3.0.0:
+ resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==}
+ engines: {node: '>=0.10.0'}
+
+ normalize-range@0.1.2:
+ resolution: {integrity: sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==}
+ engines: {node: '>=0.10.0'}
+
+ object-assign@4.1.1:
+ resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==}
+ engines: {node: '>=0.10.0'}
+
+ object-hash@3.0.0:
+ resolution: {integrity: sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==}
+ engines: {node: '>= 6'}
+
os-tmpdir@1.0.2:
resolution: {integrity: sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==}
engines: {node: '>=0.10.0'}
@@ -1001,6 +1190,13 @@ packages:
resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==}
engines: {node: '>=8'}
+ path-parse@1.0.7:
+ resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==}
+
+ path-scurry@1.11.1:
+ resolution: {integrity: sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==}
+ engines: {node: '>=16 || 14 >=14.18'}
+
path-scurry@2.0.0:
resolution: {integrity: sha512-ypGJsmGtdXUOeM5u93TyeIEfEhM6s+ljAhrk5vAvSx8uyY/02OvrZnA0YNGUrPXfpJMgI1ODd3nwz8Npx4O4cg==}
engines: {node: 20 || >=22}
@@ -1008,12 +1204,61 @@ packages:
picocolors@1.1.1:
resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==}
+ picomatch@2.3.1:
+ resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==}
+ engines: {node: '>=8.6'}
+
+ pify@2.3.0:
+ resolution: {integrity: sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==}
+ engines: {node: '>=0.10.0'}
+
+ pirates@4.0.6:
+ resolution: {integrity: sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==}
+ engines: {node: '>= 6'}
+
possible-typed-array-names@1.0.0:
resolution: {integrity: sha512-d7Uw+eZoloe0EHDIYoe+bQ5WXnGMOpmiZFTuMWCwpjzzkL2nTjcKiAk4hh8TjnGye2TwWOk3UXucZ+3rbmBa8Q==}
engines: {node: '>= 0.4'}
- postcss@8.4.47:
- resolution: {integrity: sha512-56rxCq7G/XfB4EkXq9Egn5GCqugWvDFjafDOThIdMBsI15iqPqR5r15TfSr1YPYeEI19YeaXMCbY6u88Y76GLQ==}
+ postcss-import@15.1.0:
+ resolution: {integrity: sha512-hpr+J05B2FVYUAXHeK1YyI267J/dDDhMU6B6civm8hSY1jYJnBXxzKDKDswzJmtLHryrjhnDjqqp/49t8FALew==}
+ engines: {node: '>=14.0.0'}
+ peerDependencies:
+ postcss: ^8.0.0
+
+ postcss-js@4.0.1:
+ resolution: {integrity: sha512-dDLF8pEO191hJMtlHFPRa8xsizHaM82MLfNkUHdUtVEV3tgTp5oj+8qbEqYM57SLfc74KSbw//4SeJma2LRVIw==}
+ engines: {node: ^12 || ^14 || >= 16}
+ peerDependencies:
+ postcss: ^8.4.21
+
+ postcss-load-config@4.0.2:
+ resolution: {integrity: sha512-bSVhyJGL00wMVoPUzAVAnbEoWyqRxkjv64tUl427SKnPrENtq6hJwUojroMz2VB+Q1edmi4IfrAPpami5VVgMQ==}
+ engines: {node: '>= 14'}
+ peerDependencies:
+ postcss: '>=8.0.9'
+ ts-node: '>=9.0.0'
+ peerDependenciesMeta:
+ postcss:
+ optional: true
+ ts-node:
+ optional: true
+
+ postcss-nested@6.2.0:
+ resolution: {integrity: sha512-HQbt28KulC5AJzG+cZtj9kvKB93CFCdLvog1WFLf1D+xmMvPGlBstkpTEZfK5+AN9hfJocyBFCNiqyS48bpgzQ==}
+ engines: {node: '>=12.0'}
+ peerDependencies:
+ postcss: ^8.2.14
+
+ postcss-selector-parser@6.1.2:
+ resolution: {integrity: sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg==}
+ engines: {node: '>=4'}
+
+ postcss-value-parser@4.2.0:
+ resolution: {integrity: sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==}
+
+ postcss@8.4.49:
+ resolution: {integrity: sha512-OCVPnIObs4N29kxTjzLfUryOkvZEq+pf8jTF0lg8E7uETuWHA+v7j3c/xJmiqpX450191LlmZfUKkXxkTry7nA==}
engines: {node: ^10 || ^12 || >=14}
process-nextick-args@2.0.1:
@@ -1022,22 +1267,43 @@ packages:
proxy-from-env@1.1.0:
resolution: {integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==}
+ queue-microtask@1.2.3:
+ resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==}
+
+ read-cache@1.0.0:
+ resolution: {integrity: sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA==}
+
readable-stream@2.3.8:
resolution: {integrity: sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==}
+ readdirp@3.6.0:
+ resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==}
+ engines: {node: '>=8.10.0'}
+
readdirp@4.0.2:
resolution: {integrity: sha512-yDMz9g+VaZkqBYS/ozoBJwaBhTbZo3UNYQHNRw1D3UFQB8oHB4uS/tAODO+ZLjGWmUbKnIlOWO+aaIiAxrUWHA==}
engines: {node: '>= 14.16.0'}
+ resolve@1.22.8:
+ resolution: {integrity: sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==}
+ hasBin: true
+
retry@0.13.1:
resolution: {integrity: sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg==}
engines: {node: '>= 4'}
+ reusify@1.0.4:
+ resolution: {integrity: sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==}
+ engines: {iojs: '>=1.0.0', node: '>=0.10.0'}
+
rollup@4.24.3:
resolution: {integrity: sha512-HBW896xR5HGmoksbi3JBDtmVzWiPAYqp7wip50hjQ67JbDz61nyoMPdqu1DvVW9asYb2M65Z20ZHsyJCMqMyDg==}
engines: {node: '>=18.0.0', npm: '>=8.0.0'}
hasBin: true
+ run-parallel@1.2.0:
+ resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==}
+
sade@1.8.1:
resolution: {integrity: sha512-xal3CZX1Xlo/k4ApwCFrHVACi9fBqJ7V+mwhBsuf/1IOKbBy098Fex+Wa/5QMubw09pSZ/u8EY8PWgevJsXp1A==}
engines: {node: '>=6'}
@@ -1103,6 +1369,15 @@ packages:
resolution: {integrity: sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==}
engines: {node: '>=12'}
+ sucrase@3.35.0:
+ resolution: {integrity: sha512-8EbVDiu9iN/nESwxeSxDKe0dunta1GOlHufmSSXxMD2z2/tMZpDMpvXQGsc+ajGo8y2uYUmixaSRUc/QPoQ0GA==}
+ engines: {node: '>=16 || 14 >=14.17'}
+ hasBin: true
+
+ supports-preserve-symlinks-flag@1.0.0:
+ resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==}
+ engines: {node: '>= 0.4'}
+
svelte-check@4.0.5:
resolution: {integrity: sha512-icBTBZ3ibBaywbXUat3cK6hB5Du+Kq9Z8CRuyLmm64XIe2/r+lQcbuBx/IQgsbrC+kT2jQ0weVpZSSRIPwB6jQ==}
engines: {node: '>= 18.0.0'}
@@ -1115,6 +1390,18 @@ packages:
resolution: {integrity: sha512-bYS/DpkqXk0j5UZgiNXrEjZYPRZ4Ncd87w4KUSbcZGyojA0+i/Ls9OGUjETHmdLe8RcQ0G8SX/T0PypPpAA/ew==}
engines: {node: '>=18'}
+ tailwindcss@3.4.16:
+ resolution: {integrity: sha512-TI4Cyx7gDiZ6r44ewaJmt0o6BrMCT5aK5e0rmJ/G9Xq3w7CX/5VXl/zIPEJZFUK5VEqwByyhqNPycPlvcK4ZNw==}
+ engines: {node: '>=14.0.0'}
+ hasBin: true
+
+ thenify-all@1.6.0:
+ resolution: {integrity: sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==}
+ engines: {node: '>=0.8'}
+
+ thenify@3.3.1:
+ resolution: {integrity: sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==}
+
tiny-glob@0.2.9:
resolution: {integrity: sha512-g/55ssRPUjShh+xkfx9UPDXqhckHEsHr4Vd9zX55oSdGZc/MD0m3sferOkwWtp98bv+kcVfEHtRJgBVJzelrzg==}
@@ -1122,6 +1409,10 @@ packages:
resolution: {integrity: sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==}
engines: {node: '>=0.6.0'}
+ to-regex-range@5.0.1:
+ resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==}
+ engines: {node: '>=8.0'}
+
totalist@3.0.1:
resolution: {integrity: sha512-sf4i37nQ2LBx4m3wB74y+ubopq6W/dIzXg0FDGjsYnZHVa1Da8FH853wlL2gtUhg+xJXjfk3kUZS3BRoQeoQBQ==}
engines: {node: '>=6'}
@@ -1129,6 +1420,9 @@ packages:
tr46@0.0.3:
resolution: {integrity: sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==}
+ ts-interface-checker@0.1.13:
+ resolution: {integrity: sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==}
+
tslib@1.14.1:
resolution: {integrity: sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==}
@@ -1156,6 +1450,12 @@ packages:
resolution: {integrity: sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==}
engines: {node: '>= 10.0.0'}
+ update-browserslist-db@1.1.1:
+ resolution: {integrity: sha512-R8UzCaa9Az+38REPiJ1tXlImTJXlVfgHZsglwBD/k6nj76ctsH1E3q4doGrukiLQd3sGQYu56r5+lo5r94l29A==}
+ hasBin: true
+ peerDependencies:
+ browserslist: '>= 4.21.0'
+
util-deprecate@1.0.2:
resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==}
@@ -1336,6 +1636,11 @@ packages:
utf-8-validate:
optional: true
+ yaml@2.6.1:
+ resolution: {integrity: sha512-7r0XPzioN/Q9kXBro/XPnA6kznR73DHq+GXh5ON7ZozRO6aMjbmiBuKste2wslTFkC5d1dw0GooOCepZXJ2SAg==}
+ engines: {node: '>= 14'}
+ hasBin: true
+
zimmerframe@1.1.2:
resolution: {integrity: sha512-rAbqEGa8ovJy4pyBxZM70hg4pE6gDgaQ0Sl9M3enG3I0d6H4XSAM3GeNGLKnsBpuijUow064sf7ww1nutC5/3w==}
@@ -1348,6 +1653,8 @@ snapshots:
'@adraffy/ens-normalize@1.11.0': {}
+ '@alloc/quick-lru@5.2.0': {}
+
'@ampproject/remapping@2.3.0':
dependencies:
'@jridgewell/gen-mapping': 0.3.5
@@ -1640,6 +1947,18 @@ snapshots:
'@noble/hashes@1.4.0': {}
+ '@nodelib/fs.scandir@2.1.5':
+ dependencies:
+ '@nodelib/fs.stat': 2.0.5
+ run-parallel: 1.2.0
+
+ '@nodelib/fs.stat@2.0.5': {}
+
+ '@nodelib/fs.walk@1.2.8':
+ dependencies:
+ '@nodelib/fs.scandir': 2.1.5
+ fastq: 1.17.1
+
'@openzeppelin/defender-sdk-account-client@1.15.2':
dependencies:
'@openzeppelin/defender-sdk-base-client': 1.15.2
@@ -1812,6 +2131,9 @@ snapshots:
- web3-core
- web3-utils
+ '@pkgjs/parseargs@0.11.0':
+ optional: true
+
'@polka/url@1.0.0-next.28': {}
'@popperjs/core@2.11.8': {}
@@ -2009,6 +2331,15 @@ snapshots:
ansi-styles@6.2.1: {}
+ any-promise@1.3.0: {}
+
+ anymatch@3.1.3:
+ dependencies:
+ normalize-path: 3.0.0
+ picomatch: 2.3.1
+
+ arg@5.0.2: {}
+
aria-query@5.3.2: {}
async-retry@1.3.3:
@@ -2017,6 +2348,16 @@ snapshots:
asynckit@0.4.0: {}
+ autoprefixer@10.4.20(postcss@8.4.49):
+ dependencies:
+ browserslist: 4.24.2
+ caniuse-lite: 1.0.30001686
+ fraction.js: 4.3.7
+ normalize-range: 0.1.2
+ picocolors: 1.1.1
+ postcss: 8.4.49
+ postcss-value-parser: 4.2.0
+
available-typed-arrays@1.0.7:
dependencies:
possible-typed-array-names: 1.0.0
@@ -2037,6 +2378,8 @@ snapshots:
bech32@1.1.4: {}
+ binary-extensions@2.3.0: {}
+
bn.js@4.12.0: {}
bn.js@5.2.1: {}
@@ -2049,8 +2392,19 @@ snapshots:
dependencies:
balanced-match: 1.0.2
+ braces@3.0.3:
+ dependencies:
+ fill-range: 7.1.1
+
brorand@1.1.0: {}
+ browserslist@4.24.2:
+ dependencies:
+ caniuse-lite: 1.0.30001686
+ electron-to-chromium: 1.5.68
+ node-releases: 2.0.18
+ update-browserslist-db: 1.1.1(browserslist@4.24.2)
+
buffer@4.9.2:
dependencies:
base64-js: 1.5.1
@@ -2065,6 +2419,22 @@ snapshots:
get-intrinsic: 1.2.4
set-function-length: 1.2.2
+ camelcase-css@2.0.1: {}
+
+ caniuse-lite@1.0.30001686: {}
+
+ chokidar@3.6.0:
+ dependencies:
+ anymatch: 3.1.3
+ braces: 3.0.3
+ glob-parent: 5.1.2
+ is-binary-path: 2.1.0
+ is-glob: 4.0.3
+ normalize-path: 3.0.0
+ readdirp: 3.6.0
+ optionalDependencies:
+ fsevents: 2.3.3
+
chokidar@4.0.1:
dependencies:
readdirp: 4.0.2
@@ -2081,6 +2451,8 @@ snapshots:
command-exists@1.2.9: {}
+ commander@4.1.1: {}
+
commander@8.3.0: {}
cookie@0.6.0: {}
@@ -2101,6 +2473,8 @@ snapshots:
shebang-command: 2.0.0
which: 2.0.2
+ cssesc@3.0.0: {}
+
debug@4.3.7:
dependencies:
ms: 2.1.3
@@ -2117,10 +2491,16 @@ snapshots:
devalue@5.1.1: {}
+ didyoumean@1.2.2: {}
+
+ dlv@1.1.3: {}
+
dotenv@16.4.5: {}
eastasianwidth@0.2.0: {}
+ electron-to-chromium@1.5.68: {}
+
elliptic@6.5.4:
dependencies:
bn.js: 4.12.0
@@ -2167,6 +2547,8 @@ snapshots:
'@esbuild/win32-ia32': 0.21.5
'@esbuild/win32-x64': 0.21.5
+ escalade@3.2.0: {}
+
esm-env@1.1.4: {}
esrap@1.2.2:
@@ -2200,8 +2582,24 @@ snapshots:
fast-base64-decode@1.0.0: {}
+ fast-glob@3.3.2:
+ dependencies:
+ '@nodelib/fs.stat': 2.0.5
+ '@nodelib/fs.walk': 1.2.8
+ glob-parent: 5.1.2
+ merge2: 1.4.1
+ micromatch: 4.0.8
+
+ fastq@1.17.1:
+ dependencies:
+ reusify: 1.0.4
+
fdir@6.4.2: {}
+ fill-range@7.1.1:
+ dependencies:
+ to-regex-range: 5.0.1
+
follow-redirects@1.15.9: {}
for-each@0.3.3:
@@ -2219,6 +2617,8 @@ snapshots:
combined-stream: 1.0.8
mime-types: 2.1.35
+ fraction.js@4.3.7: {}
+
fs-extra@11.2.0:
dependencies:
graceful-fs: 4.2.11
@@ -2238,6 +2638,23 @@ snapshots:
has-symbols: 1.0.3
hasown: 2.0.2
+ glob-parent@5.1.2:
+ dependencies:
+ is-glob: 4.0.3
+
+ glob-parent@6.0.2:
+ dependencies:
+ is-glob: 4.0.3
+
+ glob@10.4.5:
+ dependencies:
+ foreground-child: 3.3.0
+ jackspeak: 3.4.3
+ minimatch: 9.0.5
+ minipass: 7.1.2
+ package-json-from-dist: 1.0.1
+ path-scurry: 1.11.1
+
glob@11.0.0:
dependencies:
foreground-child: 3.3.0
@@ -2297,14 +2714,30 @@ snapshots:
call-bind: 1.0.7
has-tostringtag: 1.0.2
+ is-binary-path@2.1.0:
+ dependencies:
+ binary-extensions: 2.3.0
+
is-callable@1.2.7: {}
+ is-core-module@2.15.1:
+ dependencies:
+ hasown: 2.0.2
+
+ is-extglob@2.1.1: {}
+
is-fullwidth-code-point@3.0.0: {}
is-generator-function@1.0.10:
dependencies:
has-tostringtag: 1.0.2
+ is-glob@4.0.3:
+ dependencies:
+ is-extglob: 2.1.1
+
+ is-number@7.0.0: {}
+
is-reference@3.0.2:
dependencies:
'@types/estree': 1.0.6
@@ -2328,10 +2761,18 @@ snapshots:
dependencies:
ws: 8.18.0
+ jackspeak@3.4.3:
+ dependencies:
+ '@isaacs/cliui': 8.0.2
+ optionalDependencies:
+ '@pkgjs/parseargs': 0.11.0
+
jackspeak@4.0.2:
dependencies:
'@isaacs/cliui': 8.0.2
+ jiti@1.21.6: {}
+
js-cookie@2.2.1: {}
js-sha3@0.8.0: {}
@@ -2355,10 +2796,16 @@ snapshots:
dependencies:
immediate: 3.0.6
+ lilconfig@3.1.3: {}
+
+ lines-and-columns@1.2.4: {}
+
locate-character@3.0.0: {}
lodash@4.17.21: {}
+ lru-cache@10.4.3: {}
+
lru-cache@11.0.2: {}
magic-string@0.30.12:
@@ -2367,6 +2814,13 @@ snapshots:
memorystream@0.3.1: {}
+ merge2@1.4.1: {}
+
+ micromatch@4.0.8:
+ dependencies:
+ braces: 3.0.3
+ picomatch: 2.3.1
+
mime-db@1.52.0: {}
mime-types@2.1.35:
@@ -2381,6 +2835,10 @@ snapshots:
dependencies:
brace-expansion: 2.0.1
+ minimatch@9.0.5:
+ dependencies:
+ brace-expansion: 2.0.1
+
minipass@7.1.2: {}
mri@1.2.0: {}
@@ -2389,12 +2847,28 @@ snapshots:
ms@2.1.3: {}
+ mz@2.7.0:
+ dependencies:
+ any-promise: 1.3.0
+ object-assign: 4.1.1
+ thenify-all: 1.6.0
+
nanoid@3.3.7: {}
node-fetch@2.7.0:
dependencies:
whatwg-url: 5.0.0
+ node-releases@2.0.18: {}
+
+ normalize-path@3.0.0: {}
+
+ normalize-range@0.1.2: {}
+
+ object-assign@4.1.1: {}
+
+ object-hash@3.0.0: {}
+
os-tmpdir@1.0.2: {}
package-json-from-dist@1.0.1: {}
@@ -2403,6 +2877,13 @@ snapshots:
path-key@3.1.1: {}
+ path-parse@1.0.7: {}
+
+ path-scurry@1.11.1:
+ dependencies:
+ lru-cache: 10.4.3
+ minipass: 7.1.2
+
path-scurry@2.0.0:
dependencies:
lru-cache: 11.0.2
@@ -2410,9 +2891,46 @@ snapshots:
picocolors@1.1.1: {}
+ picomatch@2.3.1: {}
+
+ pify@2.3.0: {}
+
+ pirates@4.0.6: {}
+
possible-typed-array-names@1.0.0: {}
- postcss@8.4.47:
+ postcss-import@15.1.0(postcss@8.4.49):
+ dependencies:
+ postcss: 8.4.49
+ postcss-value-parser: 4.2.0
+ read-cache: 1.0.0
+ resolve: 1.22.8
+
+ postcss-js@4.0.1(postcss@8.4.49):
+ dependencies:
+ camelcase-css: 2.0.1
+ postcss: 8.4.49
+
+ postcss-load-config@4.0.2(postcss@8.4.49):
+ dependencies:
+ lilconfig: 3.1.3
+ yaml: 2.6.1
+ optionalDependencies:
+ postcss: 8.4.49
+
+ postcss-nested@6.2.0(postcss@8.4.49):
+ dependencies:
+ postcss: 8.4.49
+ postcss-selector-parser: 6.1.2
+
+ postcss-selector-parser@6.1.2:
+ dependencies:
+ cssesc: 3.0.0
+ util-deprecate: 1.0.2
+
+ postcss-value-parser@4.2.0: {}
+
+ postcss@8.4.49:
dependencies:
nanoid: 3.3.7
picocolors: 1.1.1
@@ -2422,6 +2940,12 @@ snapshots:
proxy-from-env@1.1.0: {}
+ queue-microtask@1.2.3: {}
+
+ read-cache@1.0.0:
+ dependencies:
+ pify: 2.3.0
+
readable-stream@2.3.8:
dependencies:
core-util-is: 1.0.3
@@ -2432,10 +2956,22 @@ snapshots:
string_decoder: 1.1.1
util-deprecate: 1.0.2
+ readdirp@3.6.0:
+ dependencies:
+ picomatch: 2.3.1
+
readdirp@4.0.2: {}
+ resolve@1.22.8:
+ dependencies:
+ is-core-module: 2.15.1
+ path-parse: 1.0.7
+ supports-preserve-symlinks-flag: 1.0.0
+
retry@0.13.1: {}
+ reusify@1.0.4: {}
+
rollup@4.24.3:
dependencies:
'@types/estree': 1.0.6
@@ -2460,6 +2996,10 @@ snapshots:
'@rollup/rollup-win32-x64-msvc': 4.24.3
fsevents: 2.3.3
+ run-parallel@1.2.0:
+ dependencies:
+ queue-microtask: 1.2.3
+
sade@1.8.1:
dependencies:
mri: 1.2.0
@@ -2533,6 +3073,18 @@ snapshots:
dependencies:
ansi-regex: 6.1.0
+ sucrase@3.35.0:
+ dependencies:
+ '@jridgewell/gen-mapping': 0.3.5
+ commander: 4.1.1
+ glob: 10.4.5
+ lines-and-columns: 1.2.4
+ mz: 2.7.0
+ pirates: 4.0.6
+ ts-interface-checker: 0.1.13
+
+ supports-preserve-symlinks-flag@1.0.0: {}
+
svelte-check@4.0.5(svelte@5.1.6)(typescript@5.6.3):
dependencies:
'@jridgewell/trace-mapping': 0.3.25
@@ -2561,6 +3113,41 @@ snapshots:
magic-string: 0.30.12
zimmerframe: 1.1.2
+ tailwindcss@3.4.16:
+ dependencies:
+ '@alloc/quick-lru': 5.2.0
+ arg: 5.0.2
+ chokidar: 3.6.0
+ didyoumean: 1.2.2
+ dlv: 1.1.3
+ fast-glob: 3.3.2
+ glob-parent: 6.0.2
+ is-glob: 4.0.3
+ jiti: 1.21.6
+ lilconfig: 3.1.3
+ micromatch: 4.0.8
+ normalize-path: 3.0.0
+ object-hash: 3.0.0
+ picocolors: 1.1.1
+ postcss: 8.4.49
+ postcss-import: 15.1.0(postcss@8.4.49)
+ postcss-js: 4.0.1(postcss@8.4.49)
+ postcss-load-config: 4.0.2(postcss@8.4.49)
+ postcss-nested: 6.2.0(postcss@8.4.49)
+ postcss-selector-parser: 6.1.2
+ resolve: 1.22.8
+ sucrase: 3.35.0
+ transitivePeerDependencies:
+ - ts-node
+
+ thenify-all@1.6.0:
+ dependencies:
+ thenify: 3.3.1
+
+ thenify@3.3.1:
+ dependencies:
+ any-promise: 1.3.0
+
tiny-glob@0.2.9:
dependencies:
globalyzer: 0.1.0
@@ -2570,10 +3157,16 @@ snapshots:
dependencies:
os-tmpdir: 1.0.2
+ to-regex-range@5.0.1:
+ dependencies:
+ is-number: 7.0.0
+
totalist@3.0.1: {}
tr46@0.0.3: {}
+ ts-interface-checker@0.1.13: {}
+
tslib@1.14.1: {}
tslib@2.0.1: {}
@@ -2590,6 +3183,12 @@ snapshots:
universalify@2.0.1: {}
+ update-browserslist-db@1.1.1(browserslist@4.24.2):
+ dependencies:
+ browserslist: 4.24.2
+ escalade: 3.2.0
+ picocolors: 1.1.1
+
util-deprecate@1.0.2: {}
util@0.12.5:
@@ -2603,7 +3202,7 @@ snapshots:
vite@5.4.10(@types/node@22.9.0):
dependencies:
esbuild: 0.21.5
- postcss: 8.4.47
+ postcss: 8.4.49
rollup: 4.24.3
optionalDependencies:
'@types/node': 22.9.0
@@ -2875,6 +3474,8 @@ snapshots:
ws@8.18.0: {}
+ yaml@2.6.1: {}
+
zimmerframe@1.1.2: {}
zod@3.23.8: {}
diff --git a/postcss.config.js b/postcss.config.js
new file mode 100644
index 0000000..2e7af2b
--- /dev/null
+++ b/postcss.config.js
@@ -0,0 +1,6 @@
+export default {
+ plugins: {
+ tailwindcss: {},
+ autoprefixer: {},
+ },
+}
diff --git a/src/lib/wizard/components/Configuration.svelte b/src/lib/wizard/components/Configuration.svelte
new file mode 100644
index 0000000..dde46f8
--- /dev/null
+++ b/src/lib/wizard/components/Configuration.svelte
@@ -0,0 +1,53 @@
+
+
+
+
+
+ API Key
+
+
+
Get API Key
+
+
+
+
Secret
+
+
+
Authenticate
+
diff --git a/src/lib/wizard/components/Configure.svelte b/src/lib/wizard/components/Configure.svelte
deleted file mode 100644
index e9eb6b9..0000000
--- a/src/lib/wizard/components/Configure.svelte
+++ /dev/null
@@ -1,27 +0,0 @@
-
-
-
- Contract to compile: {getMainContractName(wizardState.sources)}
-
-
- Compile
-
-
diff --git a/src/lib/wizard/components/Network.svelte b/src/lib/wizard/components/Network.svelte
new file mode 100644
index 0000000..7ef1db9
--- /dev/null
+++ b/src/lib/wizard/components/Network.svelte
@@ -0,0 +1,19 @@
+
+
+
\ No newline at end of file
diff --git a/src/lib/wizard/components/shared/Dropdown.svelte b/src/lib/wizard/components/shared/Dropdown.svelte
new file mode 100644
index 0000000..aad5e0a
--- /dev/null
+++ b/src/lib/wizard/components/shared/Dropdown.svelte
@@ -0,0 +1,61 @@
+
+
+
+
+ {#each Object.entries(groupedItems) as [group, items]}
+ {#if group !== 'default'}
+ {group}
+ {/if}
+
+ {#each items as item}
+ onSelect(item)}>{item.label}
+ {/each}
+ {/each}
+
+
+
+
+
diff --git a/src/lib/wizard/state.svelte.ts b/src/lib/wizard/state.svelte.ts
index 26de299..cce2541 100644
--- a/src/lib/wizard/state.svelte.ts
+++ b/src/lib/wizard/state.svelte.ts
@@ -1,5 +1,7 @@
import type { ContractSources } from "../models/solc";
-export const wizardState = $state<{ sources: ContractSources | undefined }>({
+export const wizardState = $state<{ sources: ContractSources | undefined, apiKey: string, apiSecret: string }>({
sources: undefined,
+ apiKey: '',
+ apiSecret: '',
});
diff --git a/src/routes/+page.svelte b/src/routes/+page.svelte
index 9703914..3775497 100644
--- a/src/routes/+page.svelte
+++ b/src/routes/+page.svelte
@@ -1,5 +1,4 @@
-
-
+
+
+ toggleStep(0)} class="flex items-center justify-between w-full p-4 font-medium rtl:text-right text-gray-800 rounded-t-xl gap-3" >
+ Configuration
+
+
+
+
+
+ toggleStep(1)} class="flex items-center justify-between w-full p-4 font-medium rtl:text-right text-gray-800 rounded-t-xl gap-3">
+ Network
+
+
+
+
+
+ toggleStep(2)} class="flex items-center justify-between w-full p-4 font-medium rtl:text-right text-gray-800 rounded-t-xl gap-3">
+ Approval Process
+
+
+
+
+
+ Select approval process
+
+
+
diff --git a/src/wizard-app.css b/src/wizard-app.css
new file mode 100644
index 0000000..bd6213e
--- /dev/null
+++ b/src/wizard-app.css
@@ -0,0 +1,3 @@
+@tailwind base;
+@tailwind components;
+@tailwind utilities;
\ No newline at end of file
diff --git a/tailwind.config.js b/tailwind.config.js
new file mode 100644
index 0000000..13207cc
--- /dev/null
+++ b/tailwind.config.js
@@ -0,0 +1,9 @@
+/** @type {import('tailwindcss').Config} */
+export default {
+ content: ['./src/**/*.{html,js,svelte,ts}'],
+ theme: {
+ extend: {},
+ },
+ plugins: [],
+}
+
From 09ae740ec69f5cbf4c89c1e74f028105b40ef09b Mon Sep 17 00:00:00 2001
From: Marcos
Date: Wed, 4 Dec 2024 18:36:37 -0300
Subject: [PATCH 11/34] authenticate + add support to global state
---
src/lib/remix/compiler.ts | 2 +-
.../remix/components/ApprovalProcess.svelte | 2 +-
src/lib/remix/components/Deploy.svelte | 2 +-
src/lib/remix/components/Network.svelte | 2 +-
src/lib/remix/components/Setup.svelte | 2 +-
src/lib/{remix => }/state/state.svelte.ts | 0
.../wizard/components/Configuration.svelte | 67 ++++++++++++++++---
src/lib/wizard/components/Network.svelte | 59 ++++++++++++----
.../wizard/components/shared/Dropdown.svelte | 18 +++--
src/lib/wizard/state.svelte.ts | 7 --
src/routes/remix.svelte | 2 +-
11 files changed, 123 insertions(+), 40 deletions(-)
rename src/lib/{remix => }/state/state.svelte.ts (100%)
delete mode 100644 src/lib/wizard/state.svelte.ts
diff --git a/src/lib/remix/compiler.ts b/src/lib/remix/compiler.ts
index efeff24..ab3233d 100644
--- a/src/lib/remix/compiler.ts
+++ b/src/lib/remix/compiler.ts
@@ -1,4 +1,4 @@
-import { globalState } from "$lib/remix/state/state.svelte";
+import { globalState } from "$lib/state/state.svelte";
import type { PluginClient } from "@remixproject/plugin"
import type { CompilationFileSources, CompilationResult, lastCompilationResult } from "@remixproject/plugin-api";
diff --git a/src/lib/remix/components/ApprovalProcess.svelte b/src/lib/remix/components/ApprovalProcess.svelte
index 4c3e836..7edc6fd 100644
--- a/src/lib/remix/components/ApprovalProcess.svelte
+++ b/src/lib/remix/components/ApprovalProcess.svelte
@@ -1,5 +1,5 @@
@@ -44,10 +76,25 @@
Get API Key
-
+
Secret
-
+
+
+
+ {#if loading}
+
+ {/if}
+ {#if !loading}
+ Authenticate
+ {/if}
+
+
+ {#if successMessage}
+ {successMessage}
+ {/if}
- Authenticate
+ {#if errorMessage}
+ {errorMessage}
+ {/if}
diff --git a/src/lib/wizard/components/Network.svelte b/src/lib/wizard/components/Network.svelte
index 7ef1db9..845eb78 100644
--- a/src/lib/wizard/components/Network.svelte
+++ b/src/lib/wizard/components/Network.svelte
@@ -1,19 +1,54 @@
-
\ No newline at end of file
+ on:select={(e) => onNetworkSelect(e.detail)}
+ defaultItem={globalState.form.network ? networkToDropdownItem(globalState.form.network) : undefined}
+/>
diff --git a/src/lib/wizard/components/shared/Dropdown.svelte b/src/lib/wizard/components/shared/Dropdown.svelte
index aad5e0a..a0a6891 100644
--- a/src/lib/wizard/components/shared/Dropdown.svelte
+++ b/src/lib/wizard/components/shared/Dropdown.svelte
@@ -35,15 +35,23 @@
+ {placeholder}
{#each Object.entries(groupedItems) as [group, items]}
{#if group !== 'default'}
- {group}
+
+ {#each items.sort((a, b) => a.label.localeCompare(b.label)) as item}
+ onSelect(item)}>{item.label}
+ {/each}
+
+ {:else}
+ {#each items.sort((a, b) => a.label.localeCompare(b.label)) as item}
+ onSelect(item)}>{item.label}
+ {/each}
{/if}
-
- {#each items as item}
- onSelect(item)}>{item.label}
- {/each}
{/each}
+ {#if items.length === 0}
+ {emptyLabel ?? "No items available"}
+ {/if}
diff --git a/src/lib/wizard/state.svelte.ts b/src/lib/wizard/state.svelte.ts
deleted file mode 100644
index cce2541..0000000
--- a/src/lib/wizard/state.svelte.ts
+++ /dev/null
@@ -1,7 +0,0 @@
-import type { ContractSources } from "../models/solc";
-
-export const wizardState = $state<{ sources: ContractSources | undefined, apiKey: string, apiSecret: string }>({
- sources: undefined,
- apiKey: '',
- apiSecret: '',
-});
diff --git a/src/routes/remix.svelte b/src/routes/remix.svelte
index 6e704fc..74996e5 100644
--- a/src/routes/remix.svelte
+++ b/src/routes/remix.svelte
@@ -1,7 +1,7 @@
+
+
+ onRadioChange(e)}
+ checked
+ />
+
+ Use existing Approval Process
+
+
+ {#key globalState.form.approvalProcessSelected}
+ onSelectApprovalProcess(e.detail)}
+ disabled={radioSelected !== "existing"}
+ defaultItem={globalState.form.approvalProcessSelected
+ ? {
+ label: toDisplayName(globalState.form.approvalProcessSelected),
+ value: globalState.form.approvalProcessSelected,
+ }
+ : undefined}
+ emptyLabel="No Approval Processes Available"
+ />
+ {/key}
+
+
+
+ onRadioChange(e)}
+ title={disableCreation ? "Deploy Environment already exists" : undefined}
+ disabled={disableCreation}
+ />
+
+ Approve using injected provider
+
+
diff --git a/src/lib/wizard/components/Configuration.svelte b/src/lib/wizard/components/Configuration.svelte
index 23a3709..b722866 100644
--- a/src/lib/wizard/components/Configuration.svelte
+++ b/src/lib/wizard/components/Configuration.svelte
@@ -21,10 +21,11 @@
let loading = $state(false);
let successMessage = $state(undefined);
let errorMessage = $state(undefined);
- let apiKey = "";
- let apiSecret = "";
+ let apiKey = $state("");
+ let apiSecret = $state("");
function handleGetApiKey() {
+ // TODO: Implement
}
async function authenticate() {
diff --git a/src/lib/wizard/index.ts b/src/lib/wizard/index.ts
index dcac451..78d5b6b 100644
--- a/src/lib/wizard/index.ts
+++ b/src/lib/wizard/index.ts
@@ -1,5 +1,5 @@
import type { ContractSources } from "../models/solc";
-import { wizardState } from "./state.svelte";
+import { globalState } from "$lib/state/state.svelte";
export interface DefenderDeployMessage {
kind: 'oz-wizard-defender-deploy';
@@ -14,7 +14,7 @@ export const initWizardPlugin = () => {
function listenToContracts() {
window.addEventListener('message', function (e: MessageEvent) {
if (e.data.kind === 'oz-wizard-defender-deploy') {
- wizardState.sources = e.data.sources;
+ globalState.contract = { source: e.data.sources } ;
}
});
}
diff --git a/src/routes/wizard.svelte b/src/routes/wizard.svelte
index 500c278..fb78965 100644
--- a/src/routes/wizard.svelte
+++ b/src/routes/wizard.svelte
@@ -5,6 +5,8 @@
import { onMount } from "svelte";
import Configuration from "$lib/wizard/components/Configuration.svelte";
import Network from "$lib/wizard/components/Network.svelte";
+ import { wait } from "$lib/utils/helpers";
+ import ApprovalProcess from "$lib/wizard/components/ApprovalProcess.svelte";
let currentStep = $state(0);
function toggleStep(step: number) {
@@ -34,7 +36,7 @@
@@ -45,7 +47,7 @@
- Select approval process
+
From bbaf2a810bf3d02b3e4626564c64d696356f017c Mon Sep 17 00:00:00 2001
From: Marcos
Date: Fri, 6 Dec 2024 13:10:50 -0300
Subject: [PATCH 13/34] extract contract name from sources
---
src/lib/wizard/components/Configuration.svelte | 6 ------
src/lib/wizard/index.ts | 11 ++++++++++-
2 files changed, 10 insertions(+), 7 deletions(-)
diff --git a/src/lib/wizard/components/Configuration.svelte b/src/lib/wizard/components/Configuration.svelte
index b722866..81fcd04 100644
--- a/src/lib/wizard/components/Configuration.svelte
+++ b/src/lib/wizard/components/Configuration.svelte
@@ -12,12 +12,6 @@
// compilationResult = await API.compile(buildCompilerInput(wizardState.sources));
// }
- // function getMainContractName(sources?: ContractSources) {
- // if (!sources) return '';
- // // The first name that is not a dependency
- // return Object.keys(sources).find(name => !name.startsWith('@'));
- // }
-
let loading = $state(false);
let successMessage = $state(undefined);
let errorMessage = $state(undefined);
diff --git a/src/lib/wizard/index.ts b/src/lib/wizard/index.ts
index 78d5b6b..5600865 100644
--- a/src/lib/wizard/index.ts
+++ b/src/lib/wizard/index.ts
@@ -14,7 +14,16 @@ export const initWizardPlugin = () => {
function listenToContracts() {
window.addEventListener('message', function (e: MessageEvent) {
if (e.data.kind === 'oz-wizard-defender-deploy') {
- globalState.contract = { source: e.data.sources } ;
+ globalState.contract = {
+ source: e.data.sources,
+ target: getMainContractName(e.data.sources)
+ } ;
}
});
}
+
+function getMainContractName(sources?: ContractSources) {
+ if (!sources) return '';
+ // The first name that is not a dependency
+ return Object.keys(sources).find(name => !name.startsWith('@'));
+}
From e3ecae1828021b4e4129b73269eb4b1583f4da74 Mon Sep 17 00:00:00 2001
From: Marcos
Date: Fri, 6 Dec 2024 15:11:14 -0300
Subject: [PATCH 14/34] update readme
---
README.md | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/README.md b/README.md
index a080e66..32b84d4 100644
--- a/README.md
+++ b/README.md
@@ -2,9 +2,9 @@
-# Deploy with Defender - Remix Plugin
+# Defender Deploy Plugin
-Remix plugin to deploy smart contracts using OpenZeppelin Defender. For documentation about usage please visit the [Defender Docs](https://docs.openzeppelin.com/defender/remix-plugin).
+Plugin to deploy smart contracts using OpenZeppelin Defender. For documentation about usage in Remix please visit the [Defender Docs](https://docs.openzeppelin.com/defender/remix-plugin).
## Getting Started
@@ -16,7 +16,7 @@ pnpm install
pnpm dev
```
-The interface is ugly, but don't worry! it's not meant to be used directly, it's used embedded in a Remix iframe instead, and adopts its styles.
+The interface is ugly, but don't worry! it's not meant to be used directly, it's used embedded in an iframe instead, and adopts the parent styles.
## Testing in Remix
From 24211f8e0a3100e14c0dbb9221a3e78e1d193fa5 Mon Sep 17 00:00:00 2001
From: Marcos
Date: Fri, 6 Dec 2024 15:50:02 -0300
Subject: [PATCH 15/34] extract some components + add deploy button at the top
level component
---
.../wizard/components/ApprovalProcess.svelte | 14 +---
.../wizard/components/Configuration.svelte | 32 ++-----
.../wizard/components/shared/Button.svelte | 17 ++++
src/lib/wizard/components/shared/Input.svelte | 14 ++++
src/routes/wizard.svelte | 84 ++++++++++++-------
5 files changed, 97 insertions(+), 64 deletions(-)
create mode 100644 src/lib/wizard/components/shared/Button.svelte
create mode 100644 src/lib/wizard/components/shared/Input.svelte
diff --git a/src/lib/wizard/components/ApprovalProcess.svelte b/src/lib/wizard/components/ApprovalProcess.svelte
index eaa273d..3d1e2e6 100644
--- a/src/lib/wizard/components/ApprovalProcess.svelte
+++ b/src/lib/wizard/components/ApprovalProcess.svelte
@@ -6,6 +6,9 @@
import type { DropdownItem, GlobalState } from "$lib/models/ui";
import type { Relayer } from "$lib/models/relayer";
import { getNetworkLiteral } from "$lib/models/network";
+ import Input from "./shared/Input.svelte";
+
+ let address = $state("");
function approvalProcessByNetworkAndComponent(ap: ApprovalProcess) {
const networkName = typeof globalState.form.network === 'string'
@@ -159,16 +162,7 @@
/>
{#if approvalProcessType === "EOA" || approvalProcessType === "Safe"}
- Address (required)
-
+
{:else if approvalProcessType === "Relayer"}
{#if disableRelayers}
diff --git a/src/lib/wizard/components/Configuration.svelte b/src/lib/wizard/components/Configuration.svelte
index 81fcd04..023f381 100644
--- a/src/lib/wizard/components/Configuration.svelte
+++ b/src/lib/wizard/components/Configuration.svelte
@@ -3,14 +3,8 @@
import type { AuthenticationResponse } from "$lib/models/auth";
import type { APIResponse } from "$lib/models/ui";
import { globalState } from "$lib/state/state.svelte";
-
- // import { buildCompilerInput, type ContractSources } from "$lib/models/solc";
- // let compilationResult: any;
-
- // async function compile() {
- // if (!wizardState.sources) return;
- // compilationResult = await API.compile(buildCompilerInput(wizardState.sources));
- // }
+ import Button from "./shared/Button.svelte";
+ import Input from "./shared/Input.svelte";
let loading = $state(false);
let successMessage = $state
(undefined);
@@ -24,9 +18,9 @@
async function authenticate() {
- loading = true;
+ loading = true;
- const result: APIResponse = await API.authenticate({ apiKey, apiSecret });
+ const result: APIResponse = await API.authenticate({ apiKey, apiSecret });
if (result.success) {
globalState.authenticated = true;
@@ -71,19 +65,11 @@ loading = false;
Get API Key
-
-
- Secret
-
-
-
- {#if loading}
-
- {/if}
- {#if !loading}
- Authenticate
- {/if}
-
+
+
+
+
+
{#if successMessage}
{successMessage}
diff --git a/src/lib/wizard/components/shared/Button.svelte b/src/lib/wizard/components/shared/Button.svelte
new file mode 100644
index 0000000..bc7b831
--- /dev/null
+++ b/src/lib/wizard/components/shared/Button.svelte
@@ -0,0 +1,17 @@
+
+
+
+ {#if loading}
+
+ {/if}
+ {#if !loading}
+ {label}
+ {/if}
+
\ No newline at end of file
diff --git a/src/lib/wizard/components/shared/Input.svelte b/src/lib/wizard/components/shared/Input.svelte
new file mode 100644
index 0000000..47cd051
--- /dev/null
+++ b/src/lib/wizard/components/shared/Input.svelte
@@ -0,0 +1,14 @@
+
+
+{#if label}
+ {label}
+{/if}
+
diff --git a/src/routes/wizard.svelte b/src/routes/wizard.svelte
index fb78965..28fa0d5 100644
--- a/src/routes/wizard.svelte
+++ b/src/routes/wizard.svelte
@@ -5,8 +5,25 @@
import { onMount } from "svelte";
import Configuration from "$lib/wizard/components/Configuration.svelte";
import Network from "$lib/wizard/components/Network.svelte";
- import { wait } from "$lib/utils/helpers";
- import ApprovalProcess from "$lib/wizard/components/ApprovalProcess.svelte";
+ import { wait } from "$lib/utils/helpers";
+ import ApprovalProcess from "$lib/wizard/components/ApprovalProcess.svelte";
+ import Button from "$lib/wizard/components/shared/Button.svelte";
+
+ let deploying = $state(false);
+
+ // import { buildCompilerInput, type ContractSources } from "$lib/models/solc";
+ // let compilationResult: any;
+
+ // async function compile() {
+ // if (!wizardState.sources) return;
+ // compilationResult = await API.compile(buildCompilerInput(wizardState.sources));
+ // }
+
+ const deploy = async () => {
+ deploying = true;
+ await wait(2000);
+ deploying = false;
+ };
let currentStep = $state(0);
function toggleStep(step: number) {
@@ -16,38 +33,43 @@
onMount(initWizardPlugin);
+
-
- toggleStep(0)} class="flex items-center justify-between w-full p-4 font-medium rtl:text-right text-gray-800 rounded-t-xl gap-3" >
- Configuration
-
-
-
-
-
-
+
+
+ toggleStep(0)} class="flex items-center justify-between w-full p-4 font-medium rtl:text-right text-gray-800 rounded-t-xl" >
+ Configuration
+
+
+
+
-
-
- toggleStep(1)} class="flex items-center justify-between w-full p-4 font-medium rtl:text-right text-gray-800 rounded-t-xl gap-3">
- Network
-
-
-
-
-
-
{}} />
+
+ toggleStep(1)} class="flex items-center justify-between w-full p-4 font-medium rtl:text-right text-gray-800 rounded-t-xl gap-3">
+ Network
+
+
+
+
-
-
- toggleStep(2)} class="flex items-center justify-between w-full p-4 font-medium rtl:text-right text-gray-800 rounded-t-xl gap-3">
- Approval Process
-
-
-
-
-
-
+
+ toggleStep(2)} class="flex items-center justify-between w-full p-4 font-medium rtl:text-right text-gray-800 rounded-t-xl gap-3">
+ Approval Process
+
+
+
+
+
+
From 45a05b264ff108e6dbb9fd8c21c8508b60dd89d5 Mon Sep 17 00:00:00 2001
From: Marcos
Date: Fri, 6 Dec 2024 16:26:16 -0300
Subject: [PATCH 16/34] reduce elements size
---
.../wizard/components/ApprovalProcess.svelte | 13 ++++---
.../wizard/components/Configuration.svelte | 2 +-
.../wizard/components/shared/Dropdown.svelte | 2 +-
src/lib/wizard/components/shared/Input.svelte | 7 ++--
src/routes/wizard.svelte | 38 +++++++++----------
5 files changed, 30 insertions(+), 32 deletions(-)
diff --git a/src/lib/wizard/components/ApprovalProcess.svelte b/src/lib/wizard/components/ApprovalProcess.svelte
index 3d1e2e6..e0af2f9 100644
--- a/src/lib/wizard/components/ApprovalProcess.svelte
+++ b/src/lib/wizard/components/ApprovalProcess.svelte
@@ -107,7 +107,7 @@
onclick={(e) => onRadioChange(e)}
checked
/>
-
+
Use existing Approval Process
@@ -134,7 +134,7 @@
title={disableCreation ? "Deploy Environment already exists" : undefined}
>
@@ -162,7 +162,9 @@
/>
{#if approvalProcessType === "EOA" || approvalProcessType === "Safe"}
-
+
+
+
{:else if approvalProcessType === "Relayer"}
{#if disableRelayers}
@@ -172,7 +174,6 @@
{:else}
- Relayer (required)
diff --git a/src/lib/wizard/components/Configuration.svelte b/src/lib/wizard/components/Configuration.svelte
index 023f381..4918cbb 100644
--- a/src/lib/wizard/components/Configuration.svelte
+++ b/src/lib/wizard/components/Configuration.svelte
@@ -60,7 +60,7 @@ loading = false;
- API Key
+ API Key
Get API Key
diff --git a/src/lib/wizard/components/shared/Dropdown.svelte b/src/lib/wizard/components/shared/Dropdown.svelte
index a0a6891..fff769f 100644
--- a/src/lib/wizard/components/shared/Dropdown.svelte
+++ b/src/lib/wizard/components/shared/Dropdown.svelte
@@ -34,7 +34,7 @@
-
+
{placeholder}
{#each Object.entries(groupedItems) as [group, items]}
{#if group !== 'default'}
diff --git a/src/lib/wizard/components/shared/Input.svelte b/src/lib/wizard/components/shared/Input.svelte
index 47cd051..02f1b9f 100644
--- a/src/lib/wizard/components/shared/Input.svelte
+++ b/src/lib/wizard/components/shared/Input.svelte
@@ -4,11 +4,12 @@
value: string;
placeholder: string;
type: 'text' | 'password';
+ disabled?: boolean;
};
- let { label, value, placeholder, type }: Props = $props();
+ let { label, value, placeholder, type, disabled }: Props = $props();
{#if label}
- {label}
+ {label}
{/if}
-
+
diff --git a/src/routes/wizard.svelte b/src/routes/wizard.svelte
index 28fa0d5..5216ab4 100644
--- a/src/routes/wizard.svelte
+++ b/src/routes/wizard.svelte
@@ -34,42 +34,38 @@
-
-
-
- toggleStep(0)} class="flex items-center justify-between w-full p-4 font-medium rtl:text-right text-gray-800 rounded-t-xl" >
- Configuration
-
-
-
+
+
+
toggleStep(0)} class="flex items-center justify-between w-full p-4 text-sm font-medium rtl:text-right text-gray-800 rounded-t-xl gap-3" >
+ Configuration
+
+
-
- toggleStep(1)} class="flex items-center justify-between w-full p-4 font-medium rtl:text-right text-gray-800 rounded-t-xl gap-3">
- Network
-
-
-
+
toggleStep(1)} class="flex items-center justify-between w-full p-4 text-sm font-medium rtl:text-right text-gray-800 rounded-t-xl gap-3">
+ Network
+
+
-
- toggleStep(2)} class="flex items-center justify-between w-full p-4 font-medium rtl:text-right text-gray-800 rounded-t-xl gap-3">
- Approval Process
-
-
-
+
toggleStep(2)} class="flex items-center justify-between w-full p-4 text-sm font-medium rtl:text-right text-gray-800 rounded-t-xl gap-3">
+ Approval Process
+
+
-
+
+
+
From 7918160a9f7f07e3b01799313b06aa0d006a2451 Mon Sep 17 00:00:00 2001
From: Marcos
Date: Fri, 6 Dec 2024 19:00:08 -0300
Subject: [PATCH 17/34] minor ui fixes + logic for compiling contracts
---
.../wizard/components/ApprovalProcess.svelte | 4 +-
.../wizard/components/Configuration.svelte | 115 +++++++++++-------
.../wizard/components/shared/Button.svelte | 5 +-
.../wizard/components/shared/Dropdown.svelte | 97 ++++++++++-----
src/lib/wizard/components/shared/Input.svelte | 12 +-
.../wizard/components/shared/Message.svelte | 22 ++++
src/lib/wizard/index.ts | 4 +-
src/routes/wizard.svelte | 73 ++++++++---
8 files changed, 230 insertions(+), 102 deletions(-)
create mode 100644 src/lib/wizard/components/shared/Message.svelte
diff --git a/src/lib/wizard/components/ApprovalProcess.svelte b/src/lib/wizard/components/ApprovalProcess.svelte
index e0af2f9..5a52e38 100644
--- a/src/lib/wizard/components/ApprovalProcess.svelte
+++ b/src/lib/wizard/components/ApprovalProcess.svelte
@@ -143,7 +143,7 @@
title={disableCreation ? "Deploy Environment already exists" : undefined}
/>
@@ -197,7 +197,7 @@
disabled={disableCreation}
/>
diff --git a/src/lib/wizard/components/Configuration.svelte b/src/lib/wizard/components/Configuration.svelte
index 4918cbb..087dbb6 100644
--- a/src/lib/wizard/components/Configuration.svelte
+++ b/src/lib/wizard/components/Configuration.svelte
@@ -5,77 +5,98 @@
import { globalState } from "$lib/state/state.svelte";
import Button from "./shared/Button.svelte";
import Input from "./shared/Input.svelte";
+ import Message from "./shared/Message.svelte";
let loading = $state(false);
let successMessage = $state(undefined);
let errorMessage = $state(undefined);
- let apiKey = $state("");
- let apiSecret = $state("");
+ let apiKey = $state(globalState.credentials?.apiKey ?? "");
+ let apiSecret = $state(globalState.credentials?.apiSecret ?? "");
function handleGetApiKey() {
- // TODO: Implement
+ window.open(
+ "https://defender.openzeppelin.com/#/settings/api-keys",
+ "_blank",
+ );
}
async function authenticate() {
-
- loading = true;
-
- const result: APIResponse = await API.authenticate({ apiKey, apiSecret });
-
-if (result.success) {
- globalState.authenticated = true;
- successMessage = "API Key Authenticated";
-} else {
- errorMessage = result.error ?? "Defender Authentication Failed";
-}
-
-if (result?.data?.credentials) {
- globalState.credentials = {
- apiKey: result?.data?.credentials.apiKey,
- apiSecret: result?.data?.credentials.apiSecret,
- };
-}
-
-if (result?.data?.permissions) {
- globalState.permissions = result?.data?.permissions;
-}
-
-if (result?.data?.networks) {
- globalState.networks = result?.data?.networks;
-}
-
-if (result?.data?.approvalProcesses) {
- globalState.approvalProcesses = result?.data?.approvalProcesses;
-}
-
-if (result?.data?.relayers) {
- globalState.relayers = result?.data?.relayers;
-}
-
-loading = false;
+ loading = true;
+ successMessage = undefined;
+ errorMessage = undefined;
+
+ const result: APIResponse = await API.authenticate({
+ apiKey,
+ apiSecret,
+ });
+
+ if (result.success) {
+ globalState.authenticated = true;
+ successMessage = "API Key Authenticated";
+ } else {
+ errorMessage = result.error ?? "Defender Authentication Failed";
+ }
+
+ if (result?.data?.credentials) {
+ globalState.credentials = {
+ apiKey: result?.data?.credentials.apiKey,
+ apiSecret: result?.data?.credentials.apiSecret,
+ };
+ }
+
+ if (result?.data?.permissions) {
+ globalState.permissions = result?.data?.permissions;
+ }
+
+ if (result?.data?.networks) {
+ globalState.networks = result?.data?.networks;
+ }
+
+ if (result?.data?.approvalProcesses) {
+ globalState.approvalProcesses = result?.data?.approvalProcesses;
+ }
+
+ if (result?.data?.relayers) {
+ globalState.relayers = result?.data?.relayers;
+ }
+
+ loading = false;
}
-
API Key
-
+
-
Get API Key
+
Get API Key
-
+
-
+
-
+
{#if successMessage}
-
{successMessage}
+
{/if}
{#if errorMessage}
-
{errorMessage}
+
{/if}
diff --git a/src/lib/wizard/components/shared/Button.svelte b/src/lib/wizard/components/shared/Button.svelte
index bc7b831..7bfaaf8 100644
--- a/src/lib/wizard/components/shared/Button.svelte
+++ b/src/lib/wizard/components/shared/Button.svelte
@@ -3,11 +3,12 @@
loading: boolean;
onClick: () => void;
label: string;
+ disabled?: boolean;
};
- const { loading, onClick, label }: Props = $props();
+ const { loading, onClick, label, disabled }: Props = $props();
-
+
{#if loading}
{/if}
diff --git a/src/lib/wizard/components/shared/Dropdown.svelte b/src/lib/wizard/components/shared/Dropdown.svelte
index fff769f..244f7da 100644
--- a/src/lib/wizard/components/shared/Dropdown.svelte
+++ b/src/lib/wizard/components/shared/Dropdown.svelte
@@ -2,6 +2,22 @@
import type { DropdownItem } from "$lib/models/ui";
import { createEventDispatcher } from "svelte";
+ function clickOutside(node: HTMLElement, handler: () => void) {
+ const handleClick = (event: MouseEvent) => {
+ if (!node.contains(event.target as Node)) {
+ handler();
+ }
+ };
+
+ document.addEventListener('click', handleClick, true);
+
+ return {
+ destroy() {
+ document.removeEventListener('click', handleClick, true);
+ }
+ };
+ }
+
type Props = {
placeholder: string;
items: DropdownItem[];
@@ -31,39 +47,58 @@
selected = item;
dispatch("select", item);
};
+ let isOpen = $state(false);
+
+ const toggleDropdown = () => {
+ if (!disabled) isOpen = !isOpen;
+ };
+
+ const handleSelect = (item: DropdownItem) => {
+ selected = item;
+ isOpen = false;
+ dispatch("select", item);
+ };
+
+ const handleClickOutside = () => {
+ isOpen = false;
+ };
-
-
- {placeholder}
- {#each Object.entries(groupedItems) as [group, items]}
- {#if group !== 'default'}
-
- {#each items.sort((a, b) => a.label.localeCompare(b.label)) as item}
- onSelect(item)}>{item.label}
- {/each}
-
- {:else}
+
+
+
+ {selected ? selected.label : placeholder}
+
+
+
+
+ {#if isOpen}
+
+ {#each Object.entries(groupedItems) as [group, items]}
+ {#if group !== 'default'}
+
{group}
+ {/if}
{#each items.sort((a, b) => a.label.localeCompare(b.label)) as item}
-
onSelect(item)}>{item.label}
+
handleSelect(item)}
+ >
+ {item.label}
+
{/each}
+ {/each}
+ {#if items.length === 0}
+
+ {emptyLabel ?? "No items available"}
+
{/if}
- {/each}
- {#if items.length === 0}
-
{emptyLabel ?? "No items available"}
- {/if}
-
-
-
-
-
+
+ {/if}
+
\ No newline at end of file
diff --git a/src/lib/wizard/components/shared/Input.svelte b/src/lib/wizard/components/shared/Input.svelte
index 02f1b9f..e40466d 100644
--- a/src/lib/wizard/components/shared/Input.svelte
+++ b/src/lib/wizard/components/shared/Input.svelte
@@ -6,10 +6,18 @@
type: 'text' | 'password';
disabled?: boolean;
};
- let { label, value, placeholder, type, disabled }: Props = $props();
+ let { label, value = $bindable(), placeholder, type, disabled }: Props = $props();
+
{#if label}
{label}
{/if}
-
+
diff --git a/src/lib/wizard/components/shared/Message.svelte b/src/lib/wizard/components/shared/Message.svelte
new file mode 100644
index 0000000..f66d51d
--- /dev/null
+++ b/src/lib/wizard/components/shared/Message.svelte
@@ -0,0 +1,22 @@
+
+
+{#if type === 'success'}
+
+{:else if type === 'error'}
+
+{/if}
\ No newline at end of file
diff --git a/src/lib/wizard/index.ts b/src/lib/wizard/index.ts
index 5600865..4d1c0e0 100644
--- a/src/lib/wizard/index.ts
+++ b/src/lib/wizard/index.ts
@@ -15,7 +15,9 @@ function listenToContracts() {
window.addEventListener('message', function (e: MessageEvent) {
if (e.data.kind === 'oz-wizard-defender-deploy') {
globalState.contract = {
- source: e.data.sources,
+ source: {
+ sources: e.data.sources,
+ },
target: getMainContractName(e.data.sources)
} ;
}
diff --git a/src/routes/wizard.svelte b/src/routes/wizard.svelte
index 5216ab4..cfdbd22 100644
--- a/src/routes/wizard.svelte
+++ b/src/routes/wizard.svelte
@@ -5,29 +5,62 @@
import { onMount } from "svelte";
import Configuration from "$lib/wizard/components/Configuration.svelte";
import Network from "$lib/wizard/components/Network.svelte";
- import { wait } from "$lib/utils/helpers";
import ApprovalProcess from "$lib/wizard/components/ApprovalProcess.svelte";
import Button from "$lib/wizard/components/shared/Button.svelte";
+ import { globalState } from "$lib/state/state.svelte";
+ import { API } from "$lib/api";
+ import { buildCompilerInput, type ContractSources } from "$lib/models/solc";
+ import Message from "$lib/wizard/components/shared/Message.svelte";
- let deploying = $state(false);
+ let busy = $state(false);
+ let successMessage = $state("");
+ let errorMessage = $state("");
+ let compilationResult = $state();
- // import { buildCompilerInput, type ContractSources } from "$lib/models/solc";
- // let compilationResult: any;
+ let currentStep = $state(0);
+ function toggleStep(step: number) {
+ currentStep = step;
+ }
+
+ const displayMessage = (message: string, type: "success" | "error") => {
+ successMessage = "";
+ errorMessage = "";
+ if (type === "success") {
+ successMessage = message;
+ } else {
+ errorMessage = message;
+ }
+ }
+ async function compile() {
+ const sources = globalState.contract?.source?.sources;
+ if (!sources) {
+ displayMessage("No source code found", "error");
+ return;
+ }
+
+ const res = await API.compile(buildCompilerInput(
+ globalState.contract!.source!.sources as ContractSources
+ ));
+
+ if (!res.success) {
+ displayMessage("Compilation failed", "error");
+ return;
+ }
+
+ displayMessage("Compilation successful", "success");
+ compilationResult = res.data;
+ }
- // async function compile() {
- // if (!wizardState.sources) return;
- // compilationResult = await API.compile(buildCompilerInput(wizardState.sources));
- // }
const deploy = async () => {
- deploying = true;
- await wait(2000);
- deploying = false;
+ // TODO: Implement deploy
};
- let currentStep = $state(0);
- function toggleStep(step: number) {
- currentStep = step;
+ async function compileAndDeploy() {
+ busy = true;
+ await compile();
+ await deploy();
+ busy = false;
}
onMount(initWizardPlugin);
@@ -45,7 +78,7 @@
- toggleStep(1)} class="flex items-center justify-between w-full p-4 text-sm font-medium rtl:text-right text-gray-800 rounded-t-xl gap-3">
+ toggleStep(1)} class="flex items-center justify-between w-full p-4 text-sm font-medium rtl:text-right text-gray-800 rounded-t-xl gap-3">
Network
@@ -54,7 +87,7 @@
{}} />
-
toggleStep(2)} class="flex items-center justify-between w-full p-4 text-sm font-medium rtl:text-right text-gray-800 rounded-t-xl gap-3">
+ toggleStep(2)} class="flex items-center justify-between w-full p-4 text-sm font-medium rtl:text-right text-gray-800 rounded-t-xl gap-3">
Approval Process
@@ -63,9 +96,15 @@
+ {#if compilationResult}
+ {JSON.stringify(compilationResult, null, 2)}
+ {/if}
+
-
+ {#if successMessage || errorMessage}
+
+ {/if}
From eff7e9265aa44bad3f1b0105cc39794043ad35fc Mon Sep 17 00:00:00 2001
From: Marcos
Date: Mon, 9 Dec 2024 13:35:51 -0300
Subject: [PATCH 18/34] implement deploy with existing approval process
---
src/lib/models/solc.ts | 8 ++++++
src/routes/deploy/+server.ts | 3 +-
src/routes/wizard.svelte | 53 ++++++++++++++++++++++++++++++++++--
3 files changed, 61 insertions(+), 3 deletions(-)
diff --git a/src/lib/models/solc.ts b/src/lib/models/solc.ts
index 3f635e2..995e23c 100644
--- a/src/lib/models/solc.ts
+++ b/src/lib/models/solc.ts
@@ -14,6 +14,10 @@ export type CompilerInput = {
*/
settings: {
outputSelection: Record>;
+ optimizer?: {
+ enabled: boolean,
+ runs: number,
+ },
};
};
@@ -26,6 +30,10 @@ export function buildCompilerInput(sources: ContractSources): CompilerInput {
sources,
language: 'Solidity',
settings: {
+ optimizer: {
+ enabled: true,
+ runs: 200,
+ },
outputSelection: {
'*': { '*': ['*'] }
}
diff --git a/src/routes/deploy/+server.ts b/src/routes/deploy/+server.ts
index 28029c7..0f4b36c 100644
--- a/src/routes/deploy/+server.ts
+++ b/src/routes/deploy/+server.ts
@@ -10,7 +10,8 @@ export async function POST({ request }: { request: Request }) {
const [deploymentResult, error] = await attempt(() => deployContract(credentials, deployment));
if (error) {
- return json({ success: false, error: error.msg });
+ const internalError = error.errorObject?.response?.data?.message;
+ return json({ success: false, error: internalError || error.msg });
}
return json({ success: true, data: { deployment: deploymentResult } });
diff --git a/src/routes/wizard.svelte b/src/routes/wizard.svelte
index cfdbd22..3b9f7dc 100644
--- a/src/routes/wizard.svelte
+++ b/src/routes/wizard.svelte
@@ -11,11 +11,22 @@
import { API } from "$lib/api";
import { buildCompilerInput, type ContractSources } from "$lib/models/solc";
import Message from "$lib/wizard/components/shared/Message.svelte";
+ import type { Artifact, DeployContractRequest } from "$lib/models/deploy";
+ import { getNetworkLiteral } from "$lib/models/network";
let busy = $state(false);
let successMessage = $state("");
let errorMessage = $state("");
- let compilationResult = $state();
+ let compilationResult = $state<{ output: Artifact['output'] }>();
+
+ let deploymentArtifact = $derived.by(() => {
+ if (!compilationResult || !globalState.contract?.target || !globalState.contract.source?.sources) return;
+
+ return {
+ input: buildCompilerInput(globalState.contract.source?.sources as ContractSources),
+ output: compilationResult.output
+ }
+ });
let currentStep = $state(0);
function toggleStep(step: number) {
@@ -53,7 +64,45 @@
const deploy = async () => {
- // TODO: Implement deploy
+ if (!globalState.form.network) {
+ displayMessage("No network selected", "error");
+ return;
+ }
+
+ if (!globalState.form.approvalProcessSelected) {
+ displayMessage("No approval process selected", "error");
+ return;
+ }
+
+ if (!globalState.contract?.target || !globalState.contract.source?.sources) {
+ displayMessage("No contract selected", "error");
+ return;
+ }
+
+ if (!deploymentArtifact) {
+ displayMessage("No artifact found", "error");
+ return;
+ }
+
+ const deployRequest: DeployContractRequest = {
+ artifactPayload: JSON.stringify(deploymentArtifact),
+ network: getNetworkLiteral(globalState.form.network),
+ // TODO: Implement approval process creation
+ approvalProcessId: globalState.form.approvalProcessSelected.approvalProcessId,
+ contractName: globalState.contract!.target,
+ contractPath: globalState.contract!.target,
+ verifySourceCode: true,
+ // TODO: Implement constructor arguments
+ constructorBytecode: '',
+ }
+
+ const res = await API.createDeployment(deployRequest);
+ if (!res.success) {
+ displayMessage(`Deployment failed: ${res.error}`, "error");
+ return;
+ }
+
+ displayMessage("Deployment successful", "success");
};
async function compileAndDeploy() {
From b7dd07e9aac1e352ef06f315f4b19654f05c5887 Mon Sep 17 00:00:00 2001
From: Marcos
Date: Mon, 9 Dec 2024 16:34:12 -0300
Subject: [PATCH 19/34] add deployment logic
---
src/lib/remix/components/Deploy.svelte | 2 +-
src/lib/utils/contracts.ts | 4 +-
.../wizard/components/ApprovalProcess.svelte | 4 +-
src/lib/wizard/components/shared/Input.svelte | 6 +-
src/routes/wizard.svelte | 225 ++++++++++++++++--
5 files changed, 217 insertions(+), 24 deletions(-)
diff --git a/src/lib/remix/components/Deploy.svelte b/src/lib/remix/components/Deploy.svelte
index 105c405..639c7f4 100644
--- a/src/lib/remix/components/Deploy.svelte
+++ b/src/lib/remix/components/Deploy.svelte
@@ -81,7 +81,7 @@
contractBytecode = getContractBytecode(
contractInfo.path,
contractInfo.name,
- globalState.contract.data
+ globalState.contract.data.contracts
);
}
});
diff --git a/src/lib/utils/contracts.ts b/src/lib/utils/contracts.ts
index 7882d88..821ba38 100644
--- a/src/lib/utils/contracts.ts
+++ b/src/lib/utils/contracts.ts
@@ -67,7 +67,7 @@ export function createArtifactPayload(
export function getContractBytecode(
path: string,
contractName: string,
- compilation: CompilationResult
+ contractSources: Record
): string {
- return compilation.contracts[path][contractName].evm.bytecode.object;
+ return contractSources[path][contractName].evm.bytecode.object;
}
diff --git a/src/lib/wizard/components/ApprovalProcess.svelte b/src/lib/wizard/components/ApprovalProcess.svelte
index 5a52e38..5450f97 100644
--- a/src/lib/wizard/components/ApprovalProcess.svelte
+++ b/src/lib/wizard/components/ApprovalProcess.svelte
@@ -8,7 +8,7 @@
import { getNetworkLiteral } from "$lib/models/network";
import Input from "./shared/Input.svelte";
- let address = $state("");
+ let address = $state(globalState.form.approvalProcessToCreate?.via || "");
function approvalProcessByNetworkAndComponent(ap: ApprovalProcess) {
const networkName = typeof globalState.form.network === 'string'
@@ -163,7 +163,7 @@
{#if approvalProcessType === "EOA" || approvalProcessType === "Safe"}
-
+
{:else if approvalProcessType === "Relayer"}
{#if disableRelayers}
diff --git a/src/lib/wizard/components/shared/Input.svelte b/src/lib/wizard/components/shared/Input.svelte
index e40466d..d0e72b6 100644
--- a/src/lib/wizard/components/shared/Input.svelte
+++ b/src/lib/wizard/components/shared/Input.svelte
@@ -1,12 +1,15 @@
@@ -19,5 +22,6 @@
bind:value={value}
placeholder={placeholder}
disabled={disabled}
+ onchange={onchange}
class="border text-xs border-gray-300 disabled:opacity-50 rounded-md p-2 w-full"
/>
diff --git a/src/routes/wizard.svelte b/src/routes/wizard.svelte
index 3b9f7dc..02794fe 100644
--- a/src/routes/wizard.svelte
+++ b/src/routes/wizard.svelte
@@ -5,20 +5,33 @@
import { onMount } from "svelte";
import Configuration from "$lib/wizard/components/Configuration.svelte";
import Network from "$lib/wizard/components/Network.svelte";
- import ApprovalProcess from "$lib/wizard/components/ApprovalProcess.svelte";
import Button from "$lib/wizard/components/shared/Button.svelte";
- import { globalState } from "$lib/state/state.svelte";
+ import { addAPToDropdown, globalState } from "$lib/state/state.svelte";
import { API } from "$lib/api";
import { buildCompilerInput, type ContractSources } from "$lib/models/solc";
import Message from "$lib/wizard/components/shared/Message.svelte";
- import type { Artifact, DeployContractRequest } from "$lib/models/deploy";
+ import type { Artifact, DeployContractRequest, UpdateDeploymentRequest } from "$lib/models/deploy";
import { getNetworkLiteral } from "$lib/models/network";
+ import { attempt } from "$lib/utils/attempt";
+ import { getContractBytecode } from "$lib/utils/contracts";
+ import { deployContract, switchToNetwork } from "$lib/ethereum";
+ import type { ApprovalProcess as ApprovalProcessType, CreateApprovalProcessRequest } from "$lib/models/approval-process";
+ import type { APIResponse } from "$lib/models/ui";
+ import { isDeploymentEnvironment, isSameNetwork } from "$lib/utils/helpers";
+ import ApprovalProcess from "$lib/wizard/components/ApprovalProcess.svelte";
+
+ interface DeploymentResult {
+ deploymentId?: string;
+ address: string;
+ hash: string;
+ sender?: string;
+ }
let busy = $state(false);
let successMessage = $state("");
let errorMessage = $state("");
let compilationResult = $state<{ output: Artifact['output'] }>();
-
+ let deploymentId = $state(undefined);
let deploymentArtifact = $derived.by(() => {
if (!compilationResult || !globalState.contract?.target || !globalState.contract.source?.sources) return;
@@ -28,6 +41,21 @@
}
});
+ let contractBytecode = $derived.by(() => {
+ if (!globalState.contract?.target || !compilationResult) return;
+
+ const name = globalState.contract.target;
+ const sources = compilationResult.output.contracts;
+
+ return getContractBytecode(name, name, sources);
+ });
+
+ let constructorBytecode = $derived.by(() => {
+ return "0x";
+ });
+
+ let deploymentResult = $state(undefined);
+
let currentStep = $state(0);
function toggleStep(step: number) {
currentStep = step;
@@ -62,15 +90,130 @@
compilationResult = res.data;
}
+ export async function handleInjectedProviderDeployment(bytecode: string) {
+ // Switch network if needed
+ const [, networkError] = await attempt(async () => switchToNetwork(globalState.form.network!));
+ if (networkError) {
+ throw new Error(`Error switching network: ${networkError.msg}`);
+ }
+
+ const [result, error] = await attempt(async () => deployContract(bytecode));
+ if (error) {
+ throw new Error(`Error deploying contract: ${error.msg}`);
+ }
+
+ if (!result) {
+ throw new Error("Deployment result not found");
+ }
+
+ displayMessage(`Contract deployed successfully, hash: ${result?.hash}`, "success");
+
+ return {
+ address: result.address,
+ hash: result.hash,
+ sender: result.sender
+ };
+ }
+
+ function findDeploymentEnvironment(via?: string, network?: string) {
+ if (!via || !network) return undefined;
+ return globalState.approvalProcesses.find((ap) =>
+ ap.network &&
+ isDeploymentEnvironment(ap) &&
+ isSameNetwork(ap.network, network) &&
+ ap.via?.toLocaleLowerCase() === via.toLocaleLowerCase()
+ );
+ }
+
+
+ async function getOrCreateApprovalProcess(): Promise {
+ const ap = globalState.form.approvalProcessToCreate;
+ if (!ap || !ap.via || !ap.viaType) {
+ displayMessage("Must select an approval process to create", "error");
+ return;
+ }
- const deploy = async () => {
if (!globalState.form.network) {
- displayMessage("No network selected", "error");
+ displayMessage("Must select a network", "error");
return;
}
- if (!globalState.form.approvalProcessSelected) {
- displayMessage("No approval process selected", "error");
+ const existing = findDeploymentEnvironment(ap.via, ap.network);
+ if (existing) {
+ return existing;
+ }
+
+ const apRequest: CreateApprovalProcessRequest = {
+ name: `Deploy From Remix - ${ap.viaType}`,
+ via: ap.via,
+ viaType: ap.viaType,
+ network: getNetworkLiteral(globalState.form.network),
+ relayerId: ap.relayerId,
+ component: ["deploy"],
+ };
+ const result: APIResponse<{ approvalProcess: ApprovalProcessType }> =
+ await API.createApprovalProcess(apRequest);
+
+ if (!result.success) {
+ displayMessage(`Approval process creation failed, error: ${JSON.stringify(result.error)}`, "error");
+ return;
+ }
+
+ displayMessage("Deployment Environment successfully created", "success");
+ if (!result.data) return;
+
+ addAPToDropdown(result.data.approvalProcess)
+ return result.data.approvalProcess;
+ }
+
+ export async function createDefenderDeployment(request: DeployContractRequest) {
+ const result: APIResponse<{ deployment: { deploymentId: string } }> =
+ await API.createDeployment(request);
+
+ if (!result.success || !result.data) {
+ throw new Error(`Contract deployment creation failed: ${JSON.stringify(result.error)}`);
+ }
+
+ return result.data.deployment.deploymentId;
+ }
+
+ export async function updateDeploymentStatus(
+ deploymentId: string,
+ address: string,
+ hash: string
+ ) {
+ const updateRequest: UpdateDeploymentRequest = {
+ deploymentId,
+ hash,
+ address,
+ };
+
+ const result = await API.updateDeployment(updateRequest);
+ if (!result.success) {
+ throw new Error(`Failed to update deployment status: ${JSON.stringify(result.error)}`);
+ }
+ }
+
+ // function listenForDeployment(deploymentId: string) {
+ // // polls the deployment status every 10 seconds
+ // const interval = 10000;
+ // timeout = setInterval(async () => {
+ // const result: APIResponse<{ address: string, hash: string }> = await API.getDeployment(deploymentId);
+ // if (result.success && result.data?.address) {
+ // deploymentResult = {
+ // address: result.data.address,
+ // hash: result.data.hash,
+ // };
+ // logDeploymentResult(deploymentResult);
+ // clearInterval(timeout);
+ // }
+ // }, interval);
+ // }
+
+
+ const deploy = async () => {
+ if (!globalState.form.network) {
+ displayMessage("No network selected", "error");
return;
}
@@ -84,24 +227,73 @@
return;
}
+ // contract deployment requires contract bytecode
+ // and constructor bytecode to be concatenated.
+ const bytecode = contractBytecode + constructorBytecode?.slice(2);
+
+ const shouldUseInjectedProvider = globalState.form.approvalType === "injected";
+ if (shouldUseInjectedProvider) {
+ const [result, error] = await attempt(async () =>
+ handleInjectedProviderDeployment(bytecode),
+ );
+ if (error) {
+ displayMessage(`Error deploying contract: ${error.msg}`, "error");
+ return;
+ }
+
+ deploymentResult = result;
+
+ // loads global state with EOA approval process to create
+ globalState.form.approvalProcessToCreate = {
+ viaType: "EOA",
+ via: deploymentResult?.sender,
+ network: getNetworkLiteral(globalState.form.network),
+ };
+ globalState.form.approvalProcessSelected = undefined;
+ }
+
+ const approvalProcess = globalState.form.approvalProcessSelected ?? await getOrCreateApprovalProcess();
+ if (!approvalProcess) {
+ displayMessage("No Approval Process selected", "error");
+ return;
+ };
+
const deployRequest: DeployContractRequest = {
- artifactPayload: JSON.stringify(deploymentArtifact),
network: getNetworkLiteral(globalState.form.network),
- // TODO: Implement approval process creation
- approvalProcessId: globalState.form.approvalProcessSelected.approvalProcessId,
+ approvalProcessId: approvalProcess.approvalProcessId,
contractName: globalState.contract!.target,
contractPath: globalState.contract!.target,
verifySourceCode: true,
- // TODO: Implement constructor arguments
+ licenseType: 'MIT',
+ artifactPayload: JSON.stringify(deploymentArtifact),
+ // TODO: Implement constructor arguments + salt
constructorBytecode: '',
+ salt: '',
}
- const res = await API.createDeployment(deployRequest);
- if (!res.success) {
- displayMessage(`Deployment failed: ${res.error}`, "error");
+ const [newDeploymentId, deployError] = await attempt(async () => createDefenderDeployment(deployRequest));
+ if (deployError || !newDeploymentId) {
+ displayMessage(`Deployment failed to create: ${deployError?.msg}`, "error");
return;
}
+ if (shouldUseInjectedProvider && deploymentResult) {
+ const [, updateError] = await attempt(async () => updateDeploymentStatus(
+ newDeploymentId,
+ deploymentResult!.address,
+ deploymentResult!.hash
+ ));
+ if (updateError) {
+ displayMessage(`Error updating deployment status: ${updateError.msg}`, "error");
+ return;
+ }
+ } else {
+ // If we're not using an injected provider
+ // we need to listen for the deployment to be finished.
+ // listenForDeployment(newDeploymentId);
+ }
+
+ deploymentId = newDeploymentId;
displayMessage("Deployment successful", "success");
};
@@ -145,9 +337,6 @@
- {#if compilationResult}
- {JSON.stringify(compilationResult, null, 2)}
- {/if}
From beea07e40524c67daf6b6931622b5acf162d4ea5 Mon Sep 17 00:00:00 2001
From: makiopen
Date: Tue, 10 Dec 2024 09:55:10 +0100
Subject: [PATCH 20/34] styling change for headers
---
src/routes/wizard.svelte | 17 ++++++++++++++---
1 file changed, 14 insertions(+), 3 deletions(-)
diff --git a/src/routes/wizard.svelte b/src/routes/wizard.svelte
index 02794fe..cc2e8af 100644
--- a/src/routes/wizard.svelte
+++ b/src/routes/wizard.svelte
@@ -311,7 +311,7 @@
toggleStep(0)} class="flex items-center justify-between w-full p-4 text-sm font-medium rtl:text-right text-gray-800 rounded-t-xl gap-3" >
- Configuration
+ Configuration
@@ -320,7 +320,7 @@
toggleStep(1)} class="flex items-center justify-between w-full p-4 text-sm font-medium rtl:text-right text-gray-800 rounded-t-xl gap-3">
- Network
+ Network
@@ -329,7 +329,7 @@
toggleStep(2)} class="flex items-center justify-between w-full p-4 text-sm font-medium rtl:text-right text-gray-800 rounded-t-xl gap-3">
- Approval Process
+ Approval Process
@@ -346,3 +346,14 @@
{/if}
+
\ No newline at end of file
From b84125fd38ef3ae55ffb45bd1c559e16cac5f23e Mon Sep 17 00:00:00 2001
From: Marcos
Date: Tue, 10 Dec 2024 09:26:51 -0300
Subject: [PATCH 21/34] add view deployment button + improve messages
---
.../wizard/components/ApprovalProcess.svelte | 8 +++-----
src/lib/wizard/components/shared/Button.svelte | 17 ++++++++++++++---
src/lib/wizard/components/shared/Message.svelte | 11 +++++++----
src/routes/wizard.svelte | 17 +++++++++++++++--
4 files changed, 39 insertions(+), 14 deletions(-)
diff --git a/src/lib/wizard/components/ApprovalProcess.svelte b/src/lib/wizard/components/ApprovalProcess.svelte
index 5450f97..1319a68 100644
--- a/src/lib/wizard/components/ApprovalProcess.svelte
+++ b/src/lib/wizard/components/ApprovalProcess.svelte
@@ -7,6 +7,7 @@
import type { Relayer } from "$lib/models/relayer";
import { getNetworkLiteral } from "$lib/models/network";
import Input from "./shared/Input.svelte";
+ import Message from "./shared/Message.svelte";
let address = $state(globalState.form.approvalProcessToCreate?.via || "");
@@ -167,11 +168,8 @@
{:else if approvalProcessType === "Relayer"}
{#if disableRelayers}
-
-
-
- API Key not allowed to manage Relayers
-
+
+
{:else}
type Props = {
- loading: boolean;
+ loading?: boolean;
onClick: () => void;
label: string;
disabled?: boolean;
+ type?: 'primary' | 'secondary';
};
- const { loading, onClick, label, disabled }: Props = $props();
+ const { loading, onClick, label, disabled, type }: Props = $props();
+
+ let buttonClass = $derived.by(() => {
+ if (loading) {
+ return 'bg-gray-400 text-white text-sm rounded-md p-2 mt-2';
+ }
+ if (type === 'secondary') {
+ return 'bg-transparent text-gray-800 text-sm border border-gray-800 rounded-md p-2 mt-2';
+ }
+ return 'bg-blue-600 text-white text-sm rounded-md p-2 mt-2';
+ });
-
+
{#if loading}
{/if}
diff --git a/src/lib/wizard/components/shared/Message.svelte b/src/lib/wizard/components/shared/Message.svelte
index f66d51d..3b6ba05 100644
--- a/src/lib/wizard/components/shared/Message.svelte
+++ b/src/lib/wizard/components/shared/Message.svelte
@@ -1,12 +1,10 @@
{#if type === 'success'}
@@ -19,4 +17,9 @@
{message}
-{/if}
\ No newline at end of file
+{:else if type === 'warn'}
+
+{/if}
diff --git a/src/routes/wizard.svelte b/src/routes/wizard.svelte
index 02794fe..af51ffe 100644
--- a/src/routes/wizard.svelte
+++ b/src/routes/wizard.svelte
@@ -11,7 +11,7 @@
import { buildCompilerInput, type ContractSources } from "$lib/models/solc";
import Message from "$lib/wizard/components/shared/Message.svelte";
import type { Artifact, DeployContractRequest, UpdateDeploymentRequest } from "$lib/models/deploy";
- import { getNetworkLiteral } from "$lib/models/network";
+ import { getNetworkLiteral, isProductionNetwork } from "$lib/models/network";
import { attempt } from "$lib/utils/attempt";
import { getContractBytecode } from "$lib/utils/contracts";
import { deployContract, switchToNetwork } from "$lib/ethereum";
@@ -61,6 +61,15 @@
currentStep = step;
}
+ const deploymentUrl = $derived(
+ deploymentId && globalState.form.network
+ ? `https://defender.openzeppelin.com/#/deploy/environment/${
+ isProductionNetwork(globalState.form.network) ? 'production' : 'test'
+ }?deploymentId=${deploymentId}`
+ : undefined
+ );
+
+
const displayMessage = (message: string, type: "success" | "error") => {
successMessage = "";
errorMessage = "";
@@ -294,7 +303,7 @@
}
deploymentId = newDeploymentId;
- displayMessage("Deployment successful", "success");
+ displayMessage("Deployment successfuly created in Defender", "success");
};
async function compileAndDeploy() {
@@ -343,6 +352,10 @@
{#if successMessage || errorMessage}
+
+ {#if deploymentUrl}
+ window.open(deploymentUrl, "_blank")} type="secondary" />
+ {/if}
{/if}
From ff851ded0be25e208fe7a95cbe40abab8e56071c Mon Sep 17 00:00:00 2001
From: makiopen
Date: Tue, 10 Dec 2024 13:28:05 +0100
Subject: [PATCH 22/34] basic authenticate validation plus styling changes
---
.../wizard/components/ApprovalProcess.svelte | 21 +++++++++++--------
.../wizard/components/Configuration.svelte | 4 ++--
.../wizard/components/shared/Button.svelte | 4 ++--
.../wizard/components/shared/Dropdown.svelte | 8 +++----
src/lib/wizard/components/shared/Input.svelte | 4 ++--
5 files changed, 22 insertions(+), 19 deletions(-)
diff --git a/src/lib/wizard/components/ApprovalProcess.svelte b/src/lib/wizard/components/ApprovalProcess.svelte
index 5450f97..37c4ebc 100644
--- a/src/lib/wizard/components/ApprovalProcess.svelte
+++ b/src/lib/wizard/components/ApprovalProcess.svelte
@@ -98,7 +98,8 @@
);
-
From 0adbba5848405e00163c4a139289da3f71ced258 Mon Sep 17 00:00:00 2001
From: Marcos
Date: Tue, 10 Dec 2024 16:28:50 -0300
Subject: [PATCH 24/34] add support to deterministic deployments
---
src/lib/utils/helpers.ts | 6 +++
src/lib/wizard/components/Deploy.svelte | 53 +++++++++++++++++--
.../wizard/components/shared/Message.svelte | 8 ++-
src/routes/wizard.svelte | 6 +--
4 files changed, 64 insertions(+), 9 deletions(-)
diff --git a/src/lib/utils/helpers.ts b/src/lib/utils/helpers.ts
index d32442a..4c0c918 100644
--- a/src/lib/utils/helpers.ts
+++ b/src/lib/utils/helpers.ts
@@ -14,3 +14,9 @@ export const isSameNetwork = (a: string | TenantNetworkResponse, b: string | Ten
export const isDeploymentEnvironment = (approvalProcess: ApprovalProcess) => {
return approvalProcess.component?.includes('deploy');
}
+
+export const isMultisig = (viaType?: ApprovalProcess['viaType']) => {
+ if (!viaType) return false;
+ const multisigTypes = ['Safe', 'Multisig', 'Gnosis Safe', 'Gnosis Multisig'];
+ return multisigTypes.includes(viaType);
+}
\ No newline at end of file
diff --git a/src/lib/wizard/components/Deploy.svelte b/src/lib/wizard/components/Deploy.svelte
index 9713e24..74501e2 100644
--- a/src/lib/wizard/components/Deploy.svelte
+++ b/src/lib/wizard/components/Deploy.svelte
@@ -9,11 +9,11 @@
import { addAPToDropdown, findDeploymentEnvironment, globalState } from "$lib/state/state.svelte";
import { attempt } from "$lib/utils/attempt";
import { encodeConstructorArgs, getConstructorInputsWizard, getContractBytecode } from "$lib/utils/contracts";
+ import { isMultisig } from "$lib/utils/helpers";
import Button from "./shared/Button.svelte";
import Input from "./shared/Input.svelte";
import Message from "./shared/Message.svelte";
-
let inputsWithValue = $state>({});
let busy = $state(false);
let successMessage = $state("");
@@ -22,6 +22,8 @@
let compilationResult = $state<{ output: Artifact['output'] }>();
let deploymentId = $state(undefined);
let deploymentResult = $state(undefined);
+ let isDeterministic = $state(false);
+ let salt: string = $state("");
let contractBytecode = $derived.by(() => {
if (!globalState.contract?.target || !compilationResult) return;
@@ -46,6 +48,12 @@
return getConstructorInputsWizard(globalState.contract?.target, compilationResult.output.contracts);
});
+ let enforceDeterministic = $derived.by(() => {
+ const selectedMultisig = globalState.form.approvalType === 'existing' && isMultisig(globalState.form.approvalProcessSelected?.viaType);
+ const toCreateMultisig = globalState.form.approvalType === 'new' && isMultisig(globalState.form.approvalProcessToCreate?.viaType);
+ return selectedMultisig || toCreateMultisig;
+ });
+
const deploymentUrl = $derived(
deploymentId && globalState.form.network
? `https://defender.openzeppelin.com/#/deploy/environment/${
@@ -82,7 +90,7 @@
compilationResult = res.data;
}
- const displayMessage = (message: string, type: "success" | "error") => {
+ function displayMessage(message: string, type: "success" | "error") {
successMessage = "";
errorMessage = "";
if (type === "success") {
@@ -92,6 +100,11 @@
}
}
+ function handleSaltChanged(event: Event) {
+ const target = event.target as HTMLInputElement;
+ salt = target.value;
+ }
+
export async function handleInjectedProviderDeployment(bytecode: string) {
// Switch network if needed
const [, networkError] = await attempt(async () => switchToNetwork(globalState.form.network!));
@@ -201,6 +214,9 @@
return;
}
+ errorMessage = "";
+ successMessage = "";
+
const [constructorBytecode, constructorError] = await encodeConstructorArgs(inputs, inputsWithValue);
if (constructorError) {
displayMessage(`Error encoding constructor arguments: ${constructorError.msg}`, "error");
@@ -246,9 +262,8 @@
verifySourceCode: true,
licenseType: 'MIT',
artifactPayload: JSON.stringify(deploymentArtifact),
- // TODO: Implement constructor arguments + salt
- constructorBytecode: '',
- salt: '',
+ constructorBytecode,
+ salt,
}
const [newDeploymentId, deployError] = await attempt(async () => createDefenderDeployment(deployRequest));
@@ -286,6 +301,32 @@
+
+ (isDeterministic = !isDeterministic)}
+ disabled={enforceDeterministic}
+ >
+
+ Deterministic
+
+ {#if enforceDeterministic}
+
+ {/if}
+
+
+ {#if isDeterministic || enforceDeterministic}
+
+ {/if}
+
{#if compilationError}
{/if}
@@ -295,6 +336,8 @@
{#each inputs as input}
{/each}
+ {:else}
+
{/if}
diff --git a/src/lib/wizard/components/shared/Message.svelte b/src/lib/wizard/components/shared/Message.svelte
index 3b6ba05..42734d0 100644
--- a/src/lib/wizard/components/shared/Message.svelte
+++ b/src/lib/wizard/components/shared/Message.svelte
@@ -1,7 +1,7 @@
+
+ {#if displayUpgradeableWarning}
+
+ {/if}
+
0}
Constructor Arguments
{#each inputs as input}
-
+
{/each}
{:else}
diff --git a/src/lib/wizard/components/shared/Message.svelte b/src/lib/wizard/components/shared/Message.svelte
index 42734d0..521e6b5 100644
--- a/src/lib/wizard/components/shared/Message.svelte
+++ b/src/lib/wizard/components/shared/Message.svelte
@@ -10,22 +10,22 @@
{#if type === 'success'}
-
{message}
+
{@html message}
{:else if type === 'error'}
-
{message}
+
{@html message}
{:else if type === 'warn'}
-
{message}
+
{@html message}
{:else if type === 'info'}
-
{message}
+
{@html message}
{/if}
diff --git a/src/lib/wizard/index.ts b/src/lib/wizard/index.ts
index 4d1c0e0..890be70 100644
--- a/src/lib/wizard/index.ts
+++ b/src/lib/wizard/index.ts
@@ -14,12 +14,12 @@ export const initWizardPlugin = () => {
function listenToContracts() {
window.addEventListener('message', function (e: MessageEvent
) {
if (e.data.kind === 'oz-wizard-defender-deploy') {
- globalState.contract = {
+ globalState.contract = {
source: {
sources: e.data.sources,
},
target: getMainContractName(e.data.sources)
- } ;
+ };
}
});
}
From 8c938a87f8d095d66e25842e3beac87895dbbd56 Mon Sep 17 00:00:00 2001
From: makiopen
Date: Wed, 11 Dec 2024 14:48:18 +0100
Subject: [PATCH 27/34] style fixes for parameters
---
.../wizard/components/ApprovalProcess.svelte | 20 +++++------
src/lib/wizard/components/Deploy.svelte | 36 ++++++++++---------
.../wizard/components/shared/Button.svelte | 2 +-
src/routes/wizard.svelte | 8 ++---
4 files changed, 34 insertions(+), 32 deletions(-)
diff --git a/src/lib/wizard/components/ApprovalProcess.svelte b/src/lib/wizard/components/ApprovalProcess.svelte
index 023ea0b..b93e049 100644
--- a/src/lib/wizard/components/ApprovalProcess.svelte
+++ b/src/lib/wizard/components/ApprovalProcess.svelte
@@ -136,20 +136,20 @@
class="form-check mt-3 flex flex-col gap-2"
title={disableCreation ? "Deploy Environment already exists" : undefined}
>
- onRadioChange(e)}
- disabled={disableCreation}
- title={disableCreation ? "Deploy Environment already exists" : undefined}
- />
+
+ > onRadioChange(e)}
+ disabled={disableCreation}
+ title={disableCreation ? "Deploy Environment already exists" : undefined}
+/>
Create new Approval Process
diff --git a/src/lib/wizard/components/Deploy.svelte b/src/lib/wizard/components/Deploy.svelte
index f2b7b34..1ee82c1 100644
--- a/src/lib/wizard/components/Deploy.svelte
+++ b/src/lib/wizard/components/Deploy.svelte
@@ -309,21 +309,30 @@
-
+
{#if displayUpgradeableWarning}
{/if}
-
+ {#if inputs.length > 0}
+
Constructor Arguments
+ {#each inputs as input}
+
+ {/each}
+{:else}
+
+{/if}
+
+
(isDeterministic = !isDeterministic)}
- disabled={enforceDeterministic}
- >
-
+ type="checkbox"
+ id="isDeterministic"
+ checked={isDeterministic || enforceDeterministic}
+ onchange={() => (isDeterministic = !isDeterministic)}
+ disabled={enforceDeterministic}
+ >
+
Deterministic
@@ -342,14 +351,7 @@
{/if}
- {#if inputs.length > 0}
-
Constructor Arguments
- {#each inputs as input}
-
- {/each}
- {:else}
-
- {/if}
+
diff --git a/src/lib/wizard/components/shared/Button.svelte b/src/lib/wizard/components/shared/Button.svelte
index 2978756..93d6ac2 100644
--- a/src/lib/wizard/components/shared/Button.svelte
+++ b/src/lib/wizard/components/shared/Button.svelte
@@ -15,7 +15,7 @@
if (type === 'secondary') {
return 'bg-transparent text-gray-800 text-sm border border-gray-800 rounded-md p-2 mt-2';
}
- return 'bg-blue-600 text-white text-sm rounded-md p-2 mt-2';
+ return 'bg-indigo-600 text-white text-sm rounded-md p-2 mt-2';
});
diff --git a/src/routes/wizard.svelte b/src/routes/wizard.svelte
index 7a1bd18..1ba981c 100644
--- a/src/routes/wizard.svelte
+++ b/src/routes/wizard.svelte
@@ -35,7 +35,7 @@
class:cursor-not-allowed={!globalState.authenticated}
class:text-gray-300={!globalState.authenticated}
>
-
Network
+
Network
@@ -65,7 +65,7 @@
class:cursor-not-allowed={!globalState.authenticated}
class:text-gray-300={!globalState.authenticated}
>
-
Deploy
+
Deploy
@@ -76,13 +76,13 @@
\ No newline at end of file
From 05573a7c4503b1d018ceb26a96c0ba62c69d429e Mon Sep 17 00:00:00 2001
From: Marcos
Date: Wed, 11 Dec 2024 15:35:54 -0300
Subject: [PATCH 28/34] update readme
---
README.md | 43 ++++++++++++++++++++++++++++++++++++++++---
1 file changed, 40 insertions(+), 3 deletions(-)
diff --git a/README.md b/README.md
index 32b84d4..68139f1 100644
--- a/README.md
+++ b/README.md
@@ -4,7 +4,10 @@
# Defender Deploy Plugin
-Plugin to deploy smart contracts using OpenZeppelin Defender. For documentation about usage in Remix please visit the [Defender Docs](https://docs.openzeppelin.com/defender/remix-plugin).
+Plugin to deploy smart contracts using OpenZeppelin Defender. Currently supported in:
+
+- [Remix IDE](https://remix.ethereum.org/) - As a plugin listed in plugins directory, for more information please visit [our docs](https://docs.openzeppelin.com/defender/remix-plugin).
+- [Contracts Wizard](https://wizard.openzeppelin.com/) - Integrated in code editor, for more information please visit [our docs](https://docs.openzeppelin.com/defender/remix-plugin).
## Getting Started
@@ -16,7 +19,7 @@ pnpm install
pnpm dev
```
-The interface is ugly, but don't worry! it's not meant to be used directly, it's used embedded in an iframe instead, and adopts the parent styles.
+NOTE: This project is meant to be embedded in other UIs, just running the project won't be enough to see and debug it. You must embed the UI on an external iframe.
## Testing in Remix
@@ -31,4 +34,38 @@ Url: http://localhost:5173 # or live version https://defeder-remix-deploy.netlif
Type of connection: Iframe
Location in Remix: Side Panel
```
-5. You should see the plugin added to the sidebar (new icon with ? symbol).
\ No newline at end of file
+5. You should see the plugin added to the sidebar (new icon with ? symbol).
+
+## Testing in Contracts Wizard
+
+For testing in Contracts Wizard, you must also run the Contracts Wizard UI locally to point to your local plugin.
+
+1. Run Contracts Wizard locally.
+ a. Go to (https://github.com/OpenZeppelin/contracts-wizard)[Contracts Wizard Repo].
+ b. Clone the latest `master` branch and follow steps to setup the project.
+ c. Move to `pacakges/ui` and run it with `yarn dev`.
+2. In another terminal, run this project using `pnpm dev`, make sure the app is served in `http://localhost:5173`.
+3. Open Contracts Wizard local UI, generally in `http://localhost:8080`.
+4. Click on "Deploy with Defender" button, you should be able to see embedded the local plugin.
+
+## Development
+
+Many parts of codebase are shared across plugins (server side code, state definition, ethereum interactions, etc.), but UI components have a separated implementation to make them more flexible and prevent side-effects.
+
+We have some bootstrap logic to expose one UI or another depending on the parent iframe domain.
+
+### Remix
+The entrypoint for Remix plugin is `src/routes/remix.svelte`. Its components mainly use [bootstrap](https://getbootstrap.com/) for styling, Remix UI injects bootstrap dependency as a html tag when embedded.
+
+### Wizard
+The entrypoint for Contracts Wizard plugin is `src/routes/wizard.svelte`. Its components mainly use [tailwind CSS](https://tailwindcss.com/) for styling, this is mainly for convenience, since Contracts Wizard was made using this CSS framework.
+
+## Release
+
+The repo has a CI/CD connected to our netlify account, when we merge `main` to some of the release branches, a new version of the plugin is released to live. Branches:
+
+- Remix IDE Plugin - `release-remix`
+- Contracts Wizard Plugin - `release-wizard`
+
+> [!WARNING]
+> We use `main` branch as the single source of truth and it's the only branch allowed to be merged to release branches. It should be tested carefully before triggering a new release.
\ No newline at end of file
From 27780bfa2d097445a3985831467677222a25098b Mon Sep 17 00:00:00 2001
From: Marcos
Date: Wed, 11 Dec 2024 15:40:33 -0300
Subject: [PATCH 29/34] fix list sub items
---
README.md | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/README.md b/README.md
index 68139f1..e66809d 100644
--- a/README.md
+++ b/README.md
@@ -41,9 +41,9 @@ Location in Remix: Side Panel
For testing in Contracts Wizard, you must also run the Contracts Wizard UI locally to point to your local plugin.
1. Run Contracts Wizard locally.
- a. Go to (https://github.com/OpenZeppelin/contracts-wizard)[Contracts Wizard Repo].
- b. Clone the latest `master` branch and follow steps to setup the project.
- c. Move to `pacakges/ui` and run it with `yarn dev`.
+ - a. Go to (https://github.com/OpenZeppelin/contracts-wizard)[Contracts Wizard Repo].
+ - b. Clone the latest `master` branch and follow steps to setup the project.
+ - c. Move to `pacakges/ui` and run it with `yarn dev`.
2. In another terminal, run this project using `pnpm dev`, make sure the app is served in `http://localhost:5173`.
3. Open Contracts Wizard local UI, generally in `http://localhost:8080`.
4. Click on "Deploy with Defender" button, you should be able to see embedded the local plugin.
From 854b8a01ccbe3d8c827024a526550528e1e2682d Mon Sep 17 00:00:00 2001
From: Marcos Carlomagno
Date: Wed, 11 Dec 2024 21:21:20 -0300
Subject: [PATCH 30/34] Update README.md
Co-authored-by: Eric Lau
---
README.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/README.md b/README.md
index e66809d..dad5efa 100644
--- a/README.md
+++ b/README.md
@@ -41,7 +41,7 @@ Location in Remix: Side Panel
For testing in Contracts Wizard, you must also run the Contracts Wizard UI locally to point to your local plugin.
1. Run Contracts Wizard locally.
- - a. Go to (https://github.com/OpenZeppelin/contracts-wizard)[Contracts Wizard Repo].
+ - a. Go to [https://github.com/OpenZeppelin/contracts-wizard](Contracts Wizard Repo).
- b. Clone the latest `master` branch and follow steps to setup the project.
- c. Move to `pacakges/ui` and run it with `yarn dev`.
2. In another terminal, run this project using `pnpm dev`, make sure the app is served in `http://localhost:5173`.
From 01535fbe80e7723eb397893cfcf97a5d161db065 Mon Sep 17 00:00:00 2001
From: Marcos
Date: Thu, 12 Dec 2024 10:49:49 -0300
Subject: [PATCH 31/34] fix prevent adding salt when deterministic is un
checked
---
src/lib/remix/components/Deploy.svelte | 2 +-
src/lib/wizard/components/Deploy.svelte | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/lib/remix/components/Deploy.svelte b/src/lib/remix/components/Deploy.svelte
index 639c7f4..ea2a4b4 100644
--- a/src/lib/remix/components/Deploy.svelte
+++ b/src/lib/remix/components/Deploy.svelte
@@ -293,7 +293,7 @@
verifySourceCode: true,
artifactPayload,
constructorBytecode,
- salt,
+ salt: isDeterministic || enforceDeterministic ? salt : undefined,
};
const [newDeploymentId, deployError] = await attempt(async () => createDefenderDeployment(deployRequest));
if (deployError) {
diff --git a/src/lib/wizard/components/Deploy.svelte b/src/lib/wizard/components/Deploy.svelte
index 1ee82c1..2a8d12d 100644
--- a/src/lib/wizard/components/Deploy.svelte
+++ b/src/lib/wizard/components/Deploy.svelte
@@ -272,7 +272,7 @@
licenseType: 'MIT',
artifactPayload: JSON.stringify(deploymentArtifact),
constructorBytecode,
- salt,
+ salt: isDeterministic || enforceDeterministic ? salt : undefined,
}
const [newDeploymentId, deployError] = await attempt(async () => createDefenderDeployment(deployRequest));
From d43665fd69e78cf36eeb193b131bbc9f094af08a Mon Sep 17 00:00:00 2001
From: Marcos
Date: Thu, 12 Dec 2024 12:01:48 -0300
Subject: [PATCH 32/34] react to all types of assets and contract name changed
---
src/lib/models/deploy.ts | 10 +++++++
src/lib/wizard/components/Deploy.svelte | 35 ++++++++++++-------------
2 files changed, 27 insertions(+), 18 deletions(-)
diff --git a/src/lib/models/deploy.ts b/src/lib/models/deploy.ts
index c1e1296..ce0e2b2 100644
--- a/src/lib/models/deploy.ts
+++ b/src/lib/models/deploy.ts
@@ -78,3 +78,13 @@ export interface DeploymentResult {
hash: string;
sender?: string;
}
+
+export type ABITypeParameter = 'uint' | 'uint[]' | 'int' | 'int[]' | 'address' | 'address[]' | 'bool' | 'bool[]' | 'fixed' | 'fixed[]' | 'ufixed' | 'ufixed[]' | 'bytes' | 'bytes[]' | 'function' | 'function[]' | 'tuple' | 'tuple[]' | string;
+export interface ABIParameter {
+ /** The name of the parameter */
+ name: string;
+ /** The canonical type of the parameter */
+ type: ABITypeParameter;
+ /** Used for tuple types */
+ components?: ABIParameter[];
+}
\ No newline at end of file
diff --git a/src/lib/wizard/components/Deploy.svelte b/src/lib/wizard/components/Deploy.svelte
index 1ee82c1..dd212e8 100644
--- a/src/lib/wizard/components/Deploy.svelte
+++ b/src/lib/wizard/components/Deploy.svelte
@@ -2,7 +2,7 @@
import { API } from "$lib/api";
import { deployContract, switchToNetwork } from "$lib/ethereum";
import type { ApprovalProcess, CreateApprovalProcessRequest } from "$lib/models/approval-process";
- import type { Artifact, DeployContractRequest, DeploymentResult, UpdateDeploymentRequest } from "$lib/models/deploy";
+ import type { ABIParameter, Artifact, DeployContractRequest, DeploymentResult, UpdateDeploymentRequest } from "$lib/models/deploy";
import { getNetworkLiteral, isProductionNetwork } from "$lib/models/network";
import { buildCompilerInput, type ContractSources } from "$lib/models/solc";
import type { APIResponse } from "$lib/models/ui";
@@ -43,11 +43,6 @@
}
});
- let inputs = $derived.by(() => {
- if (!compilationResult) return [];
- return getConstructorInputsWizard(globalState.contract?.target, compilationResult.output.contracts);
- });
-
let displayUpgradeableWarning = $derived.by(() => {
return isUpgradeable(globalState.contract?.source?.sources as ContractSources);
});
@@ -66,6 +61,9 @@
: undefined
);
+
+ let inputs: ABIParameter[] = $state([]);
+
$effect(() => {
if (globalState.contract?.source?.sources) {
compile();
@@ -92,6 +90,10 @@
return;
}
compilationResult = res.data;
+
+ if (globalState.contract?.target && compilationResult) {
+ inputs = getConstructorInputsWizard(globalState.contract.target, compilationResult.output.contracts);
+ }
}
function displayMessage(message: string, type: "success" | "error") {
@@ -266,8 +268,8 @@
const deployRequest: DeployContractRequest = {
network: getNetworkLiteral(globalState.form.network),
approvalProcessId: approvalProcess.approvalProcessId,
- contractName: globalState.contract!.target,
- contractPath: globalState.contract!.target,
+ contractName: globalState.contract.target,
+ contractPath: globalState.contract.target,
verifySourceCode: true,
licenseType: 'MIT',
artifactPayload: JSON.stringify(deploymentArtifact),
@@ -310,19 +312,18 @@
-
{#if displayUpgradeableWarning}
{/if}
{#if inputs.length > 0}
-
Constructor Arguments
- {#each inputs as input}
-
- {/each}
-{:else}
-
-{/if}
+
Constructor Arguments
+ {#each inputs as input}
+
+ {/each}
+ {:else}
+
+ {/if}
{/if}
-
-
{#if successMessage || errorMessage}
From d150007710c3b0757803248d02e16811fc5161df Mon Sep 17 00:00:00 2001
From: Marcos
Date: Thu, 12 Dec 2024 12:04:00 -0300
Subject: [PATCH 33/34] fmt
---
src/lib/models/deploy.ts | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/lib/models/deploy.ts b/src/lib/models/deploy.ts
index ce0e2b2..e3867c5 100644
--- a/src/lib/models/deploy.ts
+++ b/src/lib/models/deploy.ts
@@ -87,4 +87,4 @@ export interface ABIParameter {
type: ABITypeParameter;
/** Used for tuple types */
components?: ABIParameter[];
-}
\ No newline at end of file
+}
From e6ff053a84432f83a3f64f9cbeba788bbbbad184 Mon Sep 17 00:00:00 2001
From: Marcos
Date: Thu, 12 Dec 2024 16:36:43 -0300
Subject: [PATCH 34/34] fix style in remix plugin
---
src/routes/remix.svelte | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/routes/remix.svelte b/src/routes/remix.svelte
index 74996e5..25aad36 100644
--- a/src/routes/remix.svelte
+++ b/src/routes/remix.svelte
@@ -112,7 +112,7 @@
{#if currentTab === index}
-
+
{#if index === 0} wait(1000).then(() => toggle(1))}/>{/if}
{#if index === 1} wait(1000).then(() => toggle(2))}/>{/if}