Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ node_modules
.netlify
/.svelte-kit
/build
src/lib/generated

# OS
.DS_Store
Expand All @@ -20,3 +21,5 @@ Thumbs.db
# Vite
vite.config.js.timestamp-*
vite.config.ts.timestamp-*

/.vscode/
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,8 @@ 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).
5. You should see the plugin added to the sidebar (new icon with ? symbol).
(Note: If accessing Remix through Brave browser, you might have to turn down Shields configuration for this website on the right of the search bar.)

## Testing in Contracts Wizard

Expand Down
15 changes: 9 additions & 6 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,12 @@
"version": "0.0.1",
"type": "module",
"scripts": {
"dev": "vite dev",
"build": "vite build",
"preview": "vite preview",
"check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json",
"check:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch"
"prepare": "node scripts/prepare.js",
"dev": "pnpm prepare && vite dev",
"build": "pnpm prepare && vite build",
"preview": "pnpm prepare && vite preview",
"check": "pnpm prepare && svelte-kit sync && svelte-check --tsconfig ./tsconfig.json",
"check:watch": "pnpm prepare && svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch"
},
"devDependencies": {
"@sveltejs/adapter-auto": "^3.0.0",
Expand All @@ -30,6 +31,8 @@
"@sveltejs/adapter-netlify": "^4.3.6",
"bootstrap": "^5.3.3",
"ethers": "^6.13.4",
"solc": "^0.8.28"
"solc": "^0.8.28",
"file-saver": "^2.0.5",
"superchain-registry": "github:ethereum-optimism/superchain-registry"
}
}
2,461 changes: 1,372 additions & 1,089 deletions pnpm-lock.yaml

Large diffs are not rendered by default.

33 changes: 33 additions & 0 deletions scripts/prepare.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
#!/usr/bin/env node

import { existsSync, mkdirSync, copyFileSync, writeFileSync } from 'fs';
import { createRequire } from 'module';

const GENERATED_DIR = 'src/lib/generated';

async function main() {
createDirs(GENERATED_DIR);

copySuperchainRegistry();
copySolcVersion();
}

main().catch(e => {
console.error(e);
process.exit(1);
});

function createDirs(dir) {
if (!existsSync(dir)) {
mkdirSync(dir, { recursive: true });
}
}

function copySuperchainRegistry() {
copyFileSync('node_modules/superchain-registry/chainList.json', `${GENERATED_DIR}/superchainRegistryChainList.json`);
}

function copySolcVersion() {
const { version } = createRequire(import.meta.url)('solc/package.json');
writeFileSync(`${GENERATED_DIR}/solcVersion.json`, JSON.stringify({ version }, null, 2));
}
24 changes: 22 additions & 2 deletions src/lib/models/approval-process.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import type { TenantNetworkResponse } from "./network";
import type { GlobalState } from "./ui";

/**
* Generic approval process model
Expand All @@ -17,12 +18,19 @@ export type ApprovalProcess = {
stackResourceId?: string;
}

export type ApprovalProcessToCreate = {
viaType: ApprovalProcessType;
via?: string;
relayerId?: string;
network?: string;
}

export type ComponentType = ('deploy' | 'upgrade')[];

/**
* Supported approval process creation types
*/
export const approvalProcessTypes = ['EOA', 'Safe', 'Relayer'];
export const approvalProcessTypes = ['EOA', 'Safe', 'Relayer'] as const;
export type ApprovalProcessType = typeof approvalProcessTypes[number];


Expand All @@ -31,11 +39,23 @@ export type ApprovalProcessType = typeof approvalProcessTypes[number];
* https://github.com/OpenZeppelin/defender-sdk/blob/main/packages/approval-process/src/models/approval-process.ts
*/
export interface CreateApprovalProcessRequest {
viaType: 'EOA' | 'Relayer' | 'Safe';
viaType: ApprovalProcessType;
name: string;
component?: ComponentType;
network: string;
via: string;
multisigSender?: string;
relayerId?: string;
}


export function approvalProcessByNetworkAndComponent(network: GlobalState["form"]["network"]) {
return (ap: ApprovalProcess) => {
const networkName =
typeof network === "string"
? network
: network?.name;

return ap.network === networkName && ap.component?.includes("deploy");
}
}
3 changes: 3 additions & 0 deletions src/lib/models/network.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ export const productionNetworks = new Set([
'moonriver',
'optimism',
'scroll',
'unichain',
'xdai',
'zksync'
]);
Expand Down Expand Up @@ -92,6 +93,7 @@ export const chainIds: { [key in string]: number } = {
'scroll-sepolia': 534351,
'sepolia': 11155111,
'sokol': 77,
'unichain': 130,
'unichain-sepolia': 1301,
'x-dfk-avax-chain': 53935,
'x-dfk-avax-chain-test': 335,
Expand Down Expand Up @@ -147,6 +149,7 @@ export const chainDisplayNames: { [key in string]: string } = {
'scroll-sepolia': 'Scroll Sepolia',
'sepolia': 'Sepolia',
'sokol': 'Sokol',
'unichain': 'Unichain',
'unichain-sepolia': 'Unichain Sepolia',
'x-dfk-avax-chain': 'Avalanche X-DFK',
'x-dfk-avax-chain-test': 'Avalanche X-DFK Testnet',
Expand Down
39 changes: 28 additions & 11 deletions src/lib/models/ui.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,18 @@
import type { CompilationFileSources, CompilationResult, SourceWithTarget } from "@remixproject/plugin-api";
import type { Relayer } from "./relayer";
import type { ApiKeyCapability, Credentials } from "./auth";
import type { ApprovalProcess } from "./approval-process";
import type { ApprovalProcess, ApprovalProcessToCreate } from "./approval-process";
import type { TenantNetworkResponse } from "./network";

export type DropdownItem = {
export type DropdownItem<TValue = any> = {
label: string;
value: any;
value: TValue;
group?: string;
}

type HTMLInputExtendedElement<TId = string, TValue = string, TName = string> = HTMLInputElement & { id: TId, name: TName, value: TValue, checked: boolean}
export type HTMLInputElementEvent<TId = string, TValue = string, TName = string> = Event & { currentTarget: HTMLInputExtendedElement<TId, TValue, TName> }

export type GlobalState = {
authenticated: boolean;
error?: string;
Expand All @@ -25,23 +28,37 @@ export type GlobalState = {
version?: string,
data?: CompilationResult | null,
enforceDeterministicReason?: string,
groupNetworksBy?: 'superchain',
}
form: {
network?: string | TenantNetworkResponse;
approvalProcessSelected?: ApprovalProcess;
approvalProcessToCreate?: {
viaType: 'EOA' | 'Safe' | 'Relayer';
via?: string;
relayerId?: string;
network?: string;
approvalProcessToCreate?: ApprovalProcessToCreate;
approvalType?: SelectedApprovalProcessType;
constructorArguments: {
values: Record<string, string | number | boolean>,
required: string[],
}
approvalType?: 'existing' | 'new' | 'injected';
deterministic: {
isSelected: boolean;
isEnforced: boolean;
salt?: string
};
completed?: boolean;
};
},
clearDeploymentStatus?: () => void;
};

export type APIResponse<T> = {
success: boolean;
error?: string;
data?: T;
}
}

const selectedApprovalProcessTypes = ['existing', 'new', 'injected'] as const;
export type SelectedApprovalProcessType = typeof selectedApprovalProcessTypes[number];

export const isSelectedApprovalProcessType = (selectedApprovalProcessType: string): selectedApprovalProcessType is SelectedApprovalProcessType => {
const expectedTypes: string[] = [...selectedApprovalProcessTypes];
return expectedTypes.includes(selectedApprovalProcessType);
};
17 changes: 8 additions & 9 deletions src/lib/remix/components/Deploy.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
import { onDestroy } from "svelte";

// Lib
import { addAPToDropdown, clearErrorBanner, globalState, setDeploymentCompleted, setErrorBanner } from "$lib/state/state.svelte";
import { updateSelectedApprovalProcessWithExisting, clearErrorBanner, globalState, setDeploymentCompleted, setErrorBanner } from "$lib/state/state.svelte";
import { log, logError, logSuccess, logWarning } from "$lib/remix/logger";
import { deployContract, switchToNetwork } from "$lib/ethereum";
import { API } from "$lib/api";
Expand All @@ -16,7 +16,7 @@
import { getNetworkLiteral, isProductionNetwork, type TenantNetworkResponse } from "$lib/models/network";
import type { ApprovalProcess, CreateApprovalProcessRequest} from "$lib/models/approval-process";
import type { DeployContractRequest, UpdateDeploymentRequest } from "$lib/models/deploy";
import type { APIResponse } from "$lib/models/ui";
import type { APIResponse, HTMLInputElementEvent } from "$lib/models/ui";

// Components
import Button from "./shared/Button.svelte";
Expand Down Expand Up @@ -150,7 +150,7 @@
logWarning("Warning: The created Deployment Environment has Deploy Approval Process configuration only, the Block Explorer API Key and Upgrade Approval Process are not set");
if (!result.data) return;

addAPToDropdown(result.data.approvalProcess)
updateSelectedApprovalProcessWithExisting(result.data.approvalProcess)
return result.data.approvalProcess;
}

Expand Down Expand Up @@ -333,14 +333,13 @@
deploying = false;
}

function handleInputChange(event: Event) {
const target = event.target as HTMLInputElement;
inputsWithValue[target.name] = target.value;
function handleInputChange(event: HTMLInputElementEvent) {
const { name, value } = event.currentTarget;
inputsWithValue[name] = value;
}

function handleSaltChanged(event: Event) {
const target = event.target as HTMLInputElement;
salt = target.value;
function handleSaltChanged(event: HTMLInputElementEvent) {
salt = event.currentTarget.value;
}

onDestroy(() => {
Expand Down
Loading