diff --git a/.gitignore b/.gitignore index a6afdb2..9dd774b 100644 --- a/.gitignore +++ b/.gitignore @@ -22,4 +22,4 @@ Thumbs.db vite.config.js.timestamp-* vite.config.ts.timestamp-* -/.vscode/ \ No newline at end of file +.vscode/ diff --git a/package.json b/package.json index 04c7e17..6248020 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "defender-remix-plugin-sveltekit", - "version": "0.0.1", + "private": true, "type": "module", "scripts": { "prepare": "node scripts/prepare.js", @@ -23,16 +23,18 @@ "vite": "^5.0.3" }, "dependencies": { - "@openzeppelin/defender-sdk": "^2.1.0", + "@openzeppelin/defender-sdk": "^2.4.0", "@remixproject/plugin": "^0.3.38", "@remixproject/plugin-api": "^0.3.38", "@remixproject/plugin-iframe": "^0.3.38", "@remixproject/plugin-utils": "^0.3.38", "@sveltejs/adapter-netlify": "^4.3.6", "bootstrap": "^5.3.3", + "dotenv": "^16.4.7", "ethers": "^6.13.4", "solc": "^0.8.28", "file-saver": "^2.0.5", "superchain-registry": "github:ethereum-optimism/superchain-registry" - } + }, + "version": "0.0.1" } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 7d6f382..2fe9010 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -9,8 +9,8 @@ importers: .: dependencies: '@openzeppelin/defender-sdk': - specifier: ^2.1.0 - version: 2.3.0(web3-core@4.7.1)(web3-utils@4.3.3)(web3@4.16.0(typescript@5.7.3)(zod@3.24.2)) + specifier: ^2.4.0 + version: 2.4.0(web3-core@4.7.1)(web3-utils@4.3.3)(web3@4.16.0(typescript@5.7.3)(zod@3.24.2)) '@remixproject/plugin': specifier: ^0.3.38 version: 0.3.38 @@ -29,6 +29,9 @@ importers: bootstrap: specifier: ^5.3.3 version: 5.3.3(@popperjs/core@2.11.8) + dotenv: + specifier: ^16.4.7 + version: 16.4.7 ethers: specifier: ^6.13.4 version: 6.13.5 @@ -619,55 +622,55 @@ packages: resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==} engines: {node: '>= 8'} - '@openzeppelin/defender-sdk-account-client@2.3.0': - resolution: {integrity: sha512-7cim3FFEh+/zGsc3HuB23rcONm61WvqgHZGn3WOK1+q5d8PECqvWPogwlTTzOICkDKOq9gQm/YuLUAttoDXHjA==} + '@openzeppelin/defender-sdk-account-client@2.4.0': + resolution: {integrity: sha512-ZAmcP1qYpYgSZVIMbZ/N8kr+bZRvk7fnV4mGhidqP0z0JoSwezYr8pWb17GdVUt3UPFZ91kfwN9xJTaPgCAhJQ==} - '@openzeppelin/defender-sdk-action-client@2.3.0': - resolution: {integrity: sha512-4pfeJ2mv93a7adUospDWdri+NDXx7qajCTREVfaw97rjbe/ymEQUFP3SP1m2K/btpzJTjjGpeXq7VcxTJdR4lA==} + '@openzeppelin/defender-sdk-action-client@2.4.0': + resolution: {integrity: sha512-nG8/UWw6i08lnxuHhRbzb9nK0++lICnoskhikCojXThXHh/K5HvcIwBYMUynb9awypfnp3zD+LA7ihwvZr9qtA==} hasBin: true - '@openzeppelin/defender-sdk-address-book-client@2.3.0': - resolution: {integrity: sha512-6g1c5XI5C6GMotmhIE6CGyWp+gYbVNdtsct7kefv5qdqKBuIYQPUHB8JIJigQ9SAJw5eeBOmKZVdbBYDm0va4A==} + '@openzeppelin/defender-sdk-address-book-client@2.4.0': + resolution: {integrity: sha512-8h8Qu54lHjL7xaLBcoyPeeJ6chKgYdEKUWxu7ZUHa/5CGW1F7RINjdsgIBWFz3HjdlAxd0hLjOHv3kUVstccDA==} - '@openzeppelin/defender-sdk-approval-process-client@2.3.0': - resolution: {integrity: sha512-9rlwRUeVBTMX8YTYVhZ4Wm4IE76lyypjh/3LYdzjXe6IHJs2AoIULQ5I1SIjiy06DYuOqIJ25BepC+ExtWXwFQ==} + '@openzeppelin/defender-sdk-approval-process-client@2.4.0': + resolution: {integrity: sha512-6nGuusBHl1ZTUlv/t0n+svdrd7LWfzGo16vs7+ig7GY97hiyu0QZVTXrZnp9NHHVB4aI553AKKnk3BYl3EcBtg==} - '@openzeppelin/defender-sdk-base-client@2.3.0': - resolution: {integrity: sha512-j/JyhYFONQiJmW7fvDqxjwhCjBsXvKxI5rUV9LF/47Ex0EnxQuypauptGi1ffegORh/U/Ya/5pqAZayMYeyu6w==} + '@openzeppelin/defender-sdk-base-client@2.4.0': + resolution: {integrity: sha512-oB18M3DNR/nREQhHLEXdcCsxv04DPbezBHzFz6APIez+MEpQQl2SwHYxA16vOyZ6A/zV0b8sFDqAjq0oogUMyA==} - '@openzeppelin/defender-sdk-deploy-client@2.3.0': - resolution: {integrity: sha512-A73HnkhNDamWaX7p4VrQZ1loBrchcRvoj1tU7CA8wSPCUn8JRJQKXIpELooEi1cUPga5A6tSBYz9UlCSsqSxKQ==} + '@openzeppelin/defender-sdk-deploy-client@2.4.0': + resolution: {integrity: sha512-7brIWq7uW6ejYuxdBE6kQnZJQSF4v8g9Jed4/leXtPFjCowhDtIldhcYUfI+UPcZnDKdbvxnxXVJM2AWyVTNtQ==} - '@openzeppelin/defender-sdk-key-value-store-client@2.3.0': - resolution: {integrity: sha512-ENwJ8LCLVZBN7lNIpWwiA8urvrdp6fq5Nx2/IQKSdF4irxqJP5+1yqNWh3+N+dwF5k+LL6vXEeVeJXw5/am/EQ==} + '@openzeppelin/defender-sdk-key-value-store-client@2.4.0': + resolution: {integrity: sha512-6wMr3w4X5LeR+3SIznwePt07adoLhrYlRBGcRyonfyKfJzTvdtd8iFKUxQrAxtvzQTcWNrf/C/sQ6dWIGNdcOg==} - '@openzeppelin/defender-sdk-monitor-client@2.3.0': - resolution: {integrity: sha512-dQIyemCp7LpdpqjU+8nvXLAbV9GelzEGoDxrHOve3LwdfcJ77Oyjr3mBjM/swnxJLQJwI1vBkEZta4VWwubgYQ==} + '@openzeppelin/defender-sdk-monitor-client@2.4.0': + resolution: {integrity: sha512-RYswhJF/zjEIOeiWPDviBBFJ0l7cJgvPDuoWs9PH6iJZfNOkOwbkEgR1MeAaWEvLxXiKkCxaLHXv1KugUjRQtA==} - '@openzeppelin/defender-sdk-network-client@2.3.0': - resolution: {integrity: sha512-VGBAd+XSYZ4HqYkQnWFDiolHWWmtE94bfP0ViQRRsKlTLgJQ/9VGVKDSafWIdFqSkIUMcJZNeUsvuNqHrzhctA==} + '@openzeppelin/defender-sdk-network-client@2.4.0': + resolution: {integrity: sha512-+19/J7NiW7EC8yN3DbqA290JBzbdu1/iHpz9lE5RJ5YTPv50eReou0v7vZSBhKRN10P7AKM3V263W1zoVGpVdA==} - '@openzeppelin/defender-sdk-notification-channel-client@2.3.0': - resolution: {integrity: sha512-pTDTrHmLtNoI6N+XDDBVO414X/FJQx6ILaZ15JuZ7rHdSe3eBXR1J7TsezPyTfPDKx/Sc+pv8mDcaCJe9PQDfA==} + '@openzeppelin/defender-sdk-notification-channel-client@2.4.0': + resolution: {integrity: sha512-LBhGmHtljiqH2Qjh3/U5uup1TW+z50M3WYgO6GLOcltlJ/ku7Zs3atibKP+xjm6tY5eZ2WK0ygnX9qHhyvCouA==} - '@openzeppelin/defender-sdk-proposal-client@2.3.0': - resolution: {integrity: sha512-oGfpzaiZba81wzenV/EaQC9pWJU+5SPwu08sUlQhR1SxkO7M1rjyZ2rwMVQTMKnwSG+r6uHVCMhS0voLIYXoQQ==} + '@openzeppelin/defender-sdk-proposal-client@2.4.0': + resolution: {integrity: sha512-I/5Z1FeRh33/IgqPPSe09lO6QattQsPWK6WQR+aysRYHjUDdpuJuWJkhNqp/4qo2Zb+0TmNloNGjnhf8NM3bBg==} - '@openzeppelin/defender-sdk-relay-client@2.3.0': - resolution: {integrity: sha512-8ckulCUOznDh7F15CUrO8eCzECKOnAsiXMxD0QJIoOLfOM83nNNQap5OmN+HG5v83b7YyUbLS08Smit2PUn5hQ==} + '@openzeppelin/defender-sdk-relay-client@2.4.0': + resolution: {integrity: sha512-DV1h3K00eeR66tMu76zhfWgKTxcZCXbOlyBYrlgG/02TH3gf4fqvttAcjFOt/nw949lZ0/q4NvZjFIvWCMYJJQ==} - '@openzeppelin/defender-sdk-relay-group-client@2.3.0': - resolution: {integrity: sha512-AacQ6XB/YmoPRTjhVYy4UEQp11srNX24yYg1B+g80yUtGnbjqd4lcl5WUTxTDaMSeM3xnJd0A5qoKshr5eA7Kw==} + '@openzeppelin/defender-sdk-relay-group-client@2.4.0': + resolution: {integrity: sha512-DniA8hXv43JA0x1HtQXPN5ROgsOsyxKNLFjUqkwa7IbHAKfZzEtMwIp116BZavrc/OZsUFY/Xh2q4en8J+8ACA==} - '@openzeppelin/defender-sdk-relay-signer-client@2.3.0': - resolution: {integrity: sha512-8TZlfguHfHcFHjfOw2tNyOIGzxCpEf4QyQwDSRa8/Mk6hAYBAQslvG+5KjE2g7mpgYuBesvzTz9jkzUe/2oi4A==} + '@openzeppelin/defender-sdk-relay-signer-client@2.4.0': + resolution: {integrity: sha512-sLs0EOFh/QbCJbP6mRbj3RytvgTHno7LXW+dqre0SRqeGVKNiVJ82yDjKPNzcwbMCfBaebQJiLe34vTGK+xLCA==} peerDependencies: web3: ^4.14.0 web3-core: ^4.7.0 web3-utils: ^4.3.2 - '@openzeppelin/defender-sdk@2.3.0': - resolution: {integrity: sha512-iWWFImUhe9yZtRACPnBXyZnM4oPg4rl4AIxYDDpipLIK6jD6JdPyu0eK09Aja4m90jX2UBrFY58PTk7swq/tcg==} + '@openzeppelin/defender-sdk@2.4.0': + resolution: {integrity: sha512-UK4+2Sll8xMFk7jkCq92cTnVtZwXpAqx0hTGUkJbi5B0uFCq9cyiVNw82z4aCVWj13pie8dVnYu0+JyJ1NCdyQ==} '@pkgjs/parseargs@0.11.0': resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==} @@ -2893,9 +2896,9 @@ snapshots: '@nodelib/fs.scandir': 2.1.5 fastq: 1.19.1 - '@openzeppelin/defender-sdk-account-client@2.3.0': + '@openzeppelin/defender-sdk-account-client@2.4.0': dependencies: - '@openzeppelin/defender-sdk-base-client': 2.3.0 + '@openzeppelin/defender-sdk-base-client': 2.4.0 axios: 1.8.1 lodash: 4.17.21 transitivePeerDependencies: @@ -2903,9 +2906,9 @@ snapshots: - debug - encoding - '@openzeppelin/defender-sdk-action-client@2.3.0': + '@openzeppelin/defender-sdk-action-client@2.4.0': dependencies: - '@openzeppelin/defender-sdk-base-client': 2.3.0 + '@openzeppelin/defender-sdk-base-client': 2.4.0 axios: 1.8.1 dotenv: 16.4.7 glob: 11.0.1 @@ -2916,18 +2919,18 @@ snapshots: - debug - encoding - '@openzeppelin/defender-sdk-address-book-client@2.3.0': + '@openzeppelin/defender-sdk-address-book-client@2.4.0': dependencies: - '@openzeppelin/defender-sdk-base-client': 2.3.0 + '@openzeppelin/defender-sdk-base-client': 2.4.0 dotenv: 16.4.7 lodash: 4.17.21 transitivePeerDependencies: - aws-crt - encoding - '@openzeppelin/defender-sdk-approval-process-client@2.3.0': + '@openzeppelin/defender-sdk-approval-process-client@2.4.0': dependencies: - '@openzeppelin/defender-sdk-base-client': 2.3.0 + '@openzeppelin/defender-sdk-base-client': 2.4.0 axios: 1.8.1 lodash: 4.17.21 transitivePeerDependencies: @@ -2935,7 +2938,7 @@ snapshots: - debug - encoding - '@openzeppelin/defender-sdk-base-client@2.3.0': + '@openzeppelin/defender-sdk-base-client@2.4.0': dependencies: '@aws-sdk/client-lambda': 3.750.0 amazon-cognito-identity-js: 6.3.12 @@ -2944,9 +2947,9 @@ snapshots: - aws-crt - encoding - '@openzeppelin/defender-sdk-deploy-client@2.3.0': + '@openzeppelin/defender-sdk-deploy-client@2.4.0': dependencies: - '@openzeppelin/defender-sdk-base-client': 2.3.0 + '@openzeppelin/defender-sdk-base-client': 2.4.0 axios: 1.8.1 lodash: 4.17.21 transitivePeerDependencies: @@ -2954,9 +2957,9 @@ snapshots: - debug - encoding - '@openzeppelin/defender-sdk-key-value-store-client@2.3.0': + '@openzeppelin/defender-sdk-key-value-store-client@2.4.0': dependencies: - '@openzeppelin/defender-sdk-base-client': 2.3.0 + '@openzeppelin/defender-sdk-base-client': 2.4.0 axios: 1.8.1 fs-extra: 11.3.0 lodash: 4.17.21 @@ -2965,9 +2968,9 @@ snapshots: - debug - encoding - '@openzeppelin/defender-sdk-monitor-client@2.3.0': + '@openzeppelin/defender-sdk-monitor-client@2.4.0': dependencies: - '@openzeppelin/defender-sdk-base-client': 2.3.0 + '@openzeppelin/defender-sdk-base-client': 2.4.0 axios: 1.8.1 ethers: 6.13.5 lodash: 4.17.21 @@ -2978,9 +2981,9 @@ snapshots: - encoding - utf-8-validate - '@openzeppelin/defender-sdk-network-client@2.3.0': + '@openzeppelin/defender-sdk-network-client@2.4.0': dependencies: - '@openzeppelin/defender-sdk-base-client': 2.3.0 + '@openzeppelin/defender-sdk-base-client': 2.4.0 axios: 1.8.1 lodash: 4.17.21 transitivePeerDependencies: @@ -2988,9 +2991,9 @@ snapshots: - debug - encoding - '@openzeppelin/defender-sdk-notification-channel-client@2.3.0': + '@openzeppelin/defender-sdk-notification-channel-client@2.4.0': dependencies: - '@openzeppelin/defender-sdk-base-client': 2.3.0 + '@openzeppelin/defender-sdk-base-client': 2.4.0 axios: 1.8.1 lodash: 4.17.21 transitivePeerDependencies: @@ -2998,9 +3001,9 @@ snapshots: - debug - encoding - '@openzeppelin/defender-sdk-proposal-client@2.3.0': + '@openzeppelin/defender-sdk-proposal-client@2.4.0': dependencies: - '@openzeppelin/defender-sdk-base-client': 2.3.0 + '@openzeppelin/defender-sdk-base-client': 2.4.0 axios: 1.8.1 ethers: 6.13.5 lodash: 4.17.21 @@ -3011,9 +3014,9 @@ snapshots: - encoding - utf-8-validate - '@openzeppelin/defender-sdk-relay-client@2.3.0': + '@openzeppelin/defender-sdk-relay-client@2.4.0': dependencies: - '@openzeppelin/defender-sdk-base-client': 2.3.0 + '@openzeppelin/defender-sdk-base-client': 2.4.0 axios: 1.8.1 lodash: 4.17.21 transitivePeerDependencies: @@ -3021,9 +3024,9 @@ snapshots: - debug - encoding - '@openzeppelin/defender-sdk-relay-group-client@2.3.0': + '@openzeppelin/defender-sdk-relay-group-client@2.4.0': dependencies: - '@openzeppelin/defender-sdk-base-client': 2.3.0 + '@openzeppelin/defender-sdk-base-client': 2.4.0 axios: 1.8.1 lodash: 4.17.21 transitivePeerDependencies: @@ -3031,7 +3034,7 @@ snapshots: - debug - encoding - '@openzeppelin/defender-sdk-relay-signer-client@2.3.0(web3-core@4.7.1)(web3-utils@4.3.3)(web3@4.16.0(typescript@5.7.3)(zod@3.24.2))': + '@openzeppelin/defender-sdk-relay-signer-client@2.4.0(web3-core@4.7.1)(web3-utils@4.3.3)(web3@4.16.0(typescript@5.7.3)(zod@3.24.2))': dependencies: '@ethersproject/bignumber': 5.8.0 '@ethersproject/bytes': 5.8.0 @@ -3040,7 +3043,7 @@ snapshots: '@ethersproject/properties': 5.8.0 '@ethersproject/providers': 5.8.0 '@ethersproject/strings': 5.8.0 - '@openzeppelin/defender-sdk-base-client': 2.3.0 + '@openzeppelin/defender-sdk-base-client': 2.4.0 amazon-cognito-identity-js: 6.3.12 axios: 1.8.1 ethers: 6.13.5 @@ -3055,22 +3058,22 @@ snapshots: - encoding - utf-8-validate - '@openzeppelin/defender-sdk@2.3.0(web3-core@4.7.1)(web3-utils@4.3.3)(web3@4.16.0(typescript@5.7.3)(zod@3.24.2))': - dependencies: - '@openzeppelin/defender-sdk-account-client': 2.3.0 - '@openzeppelin/defender-sdk-action-client': 2.3.0 - '@openzeppelin/defender-sdk-address-book-client': 2.3.0 - '@openzeppelin/defender-sdk-approval-process-client': 2.3.0 - '@openzeppelin/defender-sdk-base-client': 2.3.0 - '@openzeppelin/defender-sdk-deploy-client': 2.3.0 - '@openzeppelin/defender-sdk-key-value-store-client': 2.3.0 - '@openzeppelin/defender-sdk-monitor-client': 2.3.0 - '@openzeppelin/defender-sdk-network-client': 2.3.0 - '@openzeppelin/defender-sdk-notification-channel-client': 2.3.0 - '@openzeppelin/defender-sdk-proposal-client': 2.3.0 - '@openzeppelin/defender-sdk-relay-client': 2.3.0 - '@openzeppelin/defender-sdk-relay-group-client': 2.3.0 - '@openzeppelin/defender-sdk-relay-signer-client': 2.3.0(web3-core@4.7.1)(web3-utils@4.3.3)(web3@4.16.0(typescript@5.7.3)(zod@3.24.2)) + '@openzeppelin/defender-sdk@2.4.0(web3-core@4.7.1)(web3-utils@4.3.3)(web3@4.16.0(typescript@5.7.3)(zod@3.24.2))': + dependencies: + '@openzeppelin/defender-sdk-account-client': 2.4.0 + '@openzeppelin/defender-sdk-action-client': 2.4.0 + '@openzeppelin/defender-sdk-address-book-client': 2.4.0 + '@openzeppelin/defender-sdk-approval-process-client': 2.4.0 + '@openzeppelin/defender-sdk-base-client': 2.4.0 + '@openzeppelin/defender-sdk-deploy-client': 2.4.0 + '@openzeppelin/defender-sdk-key-value-store-client': 2.4.0 + '@openzeppelin/defender-sdk-monitor-client': 2.4.0 + '@openzeppelin/defender-sdk-network-client': 2.4.0 + '@openzeppelin/defender-sdk-notification-channel-client': 2.4.0 + '@openzeppelin/defender-sdk-proposal-client': 2.4.0 + '@openzeppelin/defender-sdk-relay-client': 2.4.0 + '@openzeppelin/defender-sdk-relay-group-client': 2.4.0 + '@openzeppelin/defender-sdk-relay-signer-client': 2.4.0(web3-core@4.7.1)(web3-utils@4.3.3)(web3@4.16.0(typescript@5.7.3)(zod@3.24.2)) transitivePeerDependencies: - aws-crt - bufferutil diff --git a/src/lib/api.ts b/src/lib/api.ts index 26180f0..05902c5 100644 --- a/src/lib/api.ts +++ b/src/lib/api.ts @@ -1,12 +1,13 @@ import type { CreateApprovalProcessRequest } from "./models/approval-process"; -import type { Credentials } from "./models/auth"; +import type { AuthenticationResponse, Credentials } from "./models/auth"; import type { DeployContractRequest, UpdateDeploymentRequest } from "./models/deploy"; import type { CompilerInput } from "./models/solc"; +import type { APIResponse } from "./models/ui"; class ApiClient { credentials: Credentials | null = null; - async authenticate(credentials: Credentials) { + async authenticate(credentials: Credentials): Promise> { const response = await fetch("/auth", { method: "POST", headers: { "Content-Type": "application/json" }, diff --git a/src/lib/defender/index.ts b/src/lib/defender/index.ts index 057bc64..653b897 100644 --- a/src/lib/defender/index.ts +++ b/src/lib/defender/index.ts @@ -17,8 +17,7 @@ const getClient = (credentials: Credentials) => { export const listApiKeyPermissions = async (credentials: Credentials) => { const client = getClient(credentials); - const capabilities = await client.account.listApiKeyCapabilities(); - return capabilities; + return await client.account.listApiKeyCapabilities(); } export const listNetworks = async (credentials: Credentials) => { @@ -33,8 +32,7 @@ export const listNetworks = async (credentials: Credentials) => { export const listApprovalProcesses = async (credentials: Credentials) => { const client = getClient(credentials); - const approvalProcesses = await client.approvalProcess.list(); - return approvalProcesses; + return await client.approvalProcess.list(); } export const listRelayers = async (credentials: Credentials) => { @@ -45,33 +43,30 @@ export const listRelayers = async (credentials: Credentials) => { export const createApprovalProcess = async (credentials: Credentials, approvalProcess: CreateApprovalProcessRequest) => { const client = getClient(credentials); - const response = await client.approvalProcess.create(approvalProcess as any); - return response; + return await client.approvalProcess.create(approvalProcess as any); } export const createRelayer = async (credentials: Credentials, relayer: CreateRelayerRequest) => { const client = getClient(credentials); - const response = await client.relay.create(relayer); - return response; + return await client.relay.create(relayer); } export const deployContract = async (credentials: Credentials, deployment: DeployContractRequest) => { const client = getClient(credentials); - const response = await client.deploy.deployContract(deployment); - return response; + return await client.deploy.deployContract(deployment); } export const updateDeployment = async (credentials: Credentials, updateReq: UpdateDeploymentRequest) => { const client = getClient(credentials); - const response = await client.deploy.updateDeployment(updateReq.deploymentId, { + return await client.deploy.updateDeployment(updateReq.deploymentId, { txHash: updateReq.hash, address: updateReq.address, }); - return response; } export const getDeployment = async (credentials: Credentials, deploymentId: string) => { const client = getClient(credentials); - const response = await client.deploy.getDeployedContract(deploymentId); - return response; + return await client.deploy.getDeployedContract(deploymentId); } + +export const listBlockExplorerKeys = async (credentials: Credentials) => await getClient(credentials).deploy.listBlockExplorerApiKeys() \ No newline at end of file diff --git a/src/lib/models/auth.ts b/src/lib/models/auth.ts index 5083b01..75f6d23 100644 --- a/src/lib/models/auth.ts +++ b/src/lib/models/auth.ts @@ -1,4 +1,6 @@ import type { ApprovalProcess } from "./approval-process"; +import type { BlockExplorerKey } from "./block-explorer-key"; +import type { TenantNetworkResponse } from "./network"; import type { Relayer } from "./relayer"; /** @@ -11,7 +13,8 @@ export type ApiKeyCapability = 'create-admin-proposals' | 'manage-relayers' | 'm export type AuthenticationResponse = { credentials: Credentials, permissions: ApiKeyCapability[], - networks: string[], + networks: (string | TenantNetworkResponse)[], approvalProcesses: ApprovalProcess[], - relayers: Relayer[] + relayers: Relayer[], + blockExplorerKeys: BlockExplorerKey[] }; diff --git a/src/lib/models/block-explorer-key.ts b/src/lib/models/block-explorer-key.ts new file mode 100644 index 0000000..f18fb34 --- /dev/null +++ b/src/lib/models/block-explorer-key.ts @@ -0,0 +1,9 @@ +/** + * Block Explorer Key models (simplified) + * https://github.com/OpenZeppelin/defender-sdk/blob/main/packages/deploy/src/models/block-explorer.ts + */ +export type BlockExplorerKey = { + blockExplorerApiKeyId: string; + network: string; + keyHash: string; +} \ No newline at end of file diff --git a/src/lib/models/ui.ts b/src/lib/models/ui.ts index 0507d3c..c815ab7 100644 --- a/src/lib/models/ui.ts +++ b/src/lib/models/ui.ts @@ -3,6 +3,7 @@ import type { Relayer } from "./relayer"; import type { ApiKeyCapability, Credentials } from "./auth"; import type { ApprovalProcess, ApprovalProcessToCreate } from "./approval-process"; import type { TenantNetworkResponse } from "./network"; +import type { BlockExplorerKey } from "./block-explorer-key"; export type DropdownItem = { label: string; @@ -19,9 +20,10 @@ export type GlobalState = { successMessage?: string; credentials: Credentials; permissions: ApiKeyCapability[]; - networks: string[] | TenantNetworkResponse[]; + networks: (string | TenantNetworkResponse)[]; approvalProcesses: ApprovalProcess[]; relayers: Relayer[]; + blockExplorerKeys: BlockExplorerKey[] contract?: { target?: string, source?: CompilationFileSources | null | SourceWithTarget, diff --git a/src/lib/state/state.svelte.ts b/src/lib/state/state.svelte.ts index d93bdaf..fcccaa8 100644 --- a/src/lib/state/state.svelte.ts +++ b/src/lib/state/state.svelte.ts @@ -40,6 +40,9 @@ export const globalState = $state({ // Relayers list for approval process creation relayers: [], + // Block Explorer keys to display warning to user + blockExplorerKeys: [], + contract: { // path of the contract target: undefined, diff --git a/src/lib/utils/contracts.ts b/src/lib/utils/contracts.ts index 78b0a9c..068a3a1 100644 --- a/src/lib/utils/contracts.ts +++ b/src/lib/utils/contracts.ts @@ -69,6 +69,7 @@ export function createArtifactPayload( sources: { [path]: { content: contractSources[path].content }, }, + language: "Solidity", settings: { optimizer: { enabled: true, diff --git a/src/lib/wizard/components/Configuration.svelte b/src/lib/wizard/components/Configuration.svelte index 986c018..c589130 100644 --- a/src/lib/wizard/components/Configuration.svelte +++ b/src/lib/wizard/components/Configuration.svelte @@ -25,7 +25,7 @@ successMessage = undefined; errorMessage = undefined; - const result: APIResponse = await API.authenticate({ + const result = await API.authenticate({ apiKey, apiSecret, }); @@ -60,6 +60,10 @@ globalState.relayers = result?.data?.relayers; } + if (result?.data?.blockExplorerKeys) { + globalState.blockExplorerKeys = result?.data?.blockExplorerKeys; + } + loading = false; } diff --git a/src/lib/wizard/components/Deploy.svelte b/src/lib/wizard/components/Deploy.svelte index 95da7d6..9812c6b 100644 --- a/src/lib/wizard/components/Deploy.svelte +++ b/src/lib/wizard/components/Deploy.svelte @@ -28,6 +28,8 @@ let deploymentResult = $state(undefined); let isCompiling = $state(false); + const hasSetUpBlockExplorerKeyForCurrentNetwork = $derived.by(() => globalState.blockExplorerKeys.some((key) => key.network === globalState.form.network)); + let deterministic = $derived.by(() => globalState.form.deterministic); // Set callback for clearing deployment status messages @@ -415,8 +417,12 @@
-

Ensure you have an Explorer API Key set in your Deploy Environment for the current network to allow the contract to be verified automatically.

-

Or download the for this contract to verify it manually on block explorers, using Solidity compiler version {solcVersion}.

+ {#if !hasSetUpBlockExplorerKeyForCurrentNetwork} +

Ensure you have an Explorer API Key set in your Deploy Environment for the current network to allow the contract to be verified automatically.

+ {:else} +

The contract will be verified automatically on the block explorer for this network.

+ {/if} +

Or you can download the for this contract to verify it manually on block explorers, using Solidity compiler version {solcVersion}.

diff --git a/src/routes/auth/+server.ts b/src/routes/auth/+server.ts index 3c25900..d9edcbf 100644 --- a/src/routes/auth/+server.ts +++ b/src/routes/auth/+server.ts @@ -1,7 +1,10 @@ -import { listApiKeyPermissions, listApprovalProcesses, listNetworks, listRelayers } from "$lib/defender"; +import { listApiKeyPermissions, listApprovalProcesses, listBlockExplorerKeys, listNetworks, listRelayers } from "$lib/defender"; import type { Relayer } from "$lib/models/relayer"; -import { attempt } from "$lib/utils/attempt"; import { json } from '@sveltejs/kit'; +import type { AuthenticationResponse } from "$lib/models/auth"; + +type ApiKeysPermissions = Awaited> +type ApiCredentials = { apiKey: string, apiSecret: string } const parseError = (error: string, component: string) => { // User-friednlier error when the api key is invalid @@ -11,62 +14,53 @@ const parseError = (error: string, component: string) => { return `Loading ${component}: ${error}`; } -export async function POST({ request }: { request: Request }) { - const { apiKey, apiSecret } = await request.json(); - - if (!apiKey || !apiSecret) { - return json({ success: false, error: 'Missing API key or API secret' }); - } - - // List API key permissions - const [permissions, permError] = await attempt( - () => listApiKeyPermissions({ apiKey, apiSecret }) - ); - if (permError) { - return json({ success: false, error: parseError(permError.msg, 'Permissions') }); +const awaitRequestOrFailWith = async (requestPromise: Promise, component: string) => { + try { + return await requestPromise + } catch(error) { + throw new Error(parseError((error as Error).message, component)) } +}; - if (!permissions?.includes('manage-deployments')) { - return json({ success: false, error: 'API Key is not allowed to deploy contracts' }); - } +export async function POST({ request }: { request: Request }): Promise { + try { + const { apiKey, apiSecret }: ApiCredentials = await request.json(); - // List netorks to preload network selection - const [networks, netError] = await attempt( - () => listNetworks({ apiKey, apiSecret }) - ); - if (netError) { - return json({ success: false, error: parseError(netError.msg, 'Networks') }); - } + if (!apiKey || !apiSecret) { + throw new Error('Missing API key or API secret') + } - // List approval processes to preload approval process selection - const [approvalProcesses, apError] = await attempt( - () => listApprovalProcesses({ apiKey, apiSecret }) - ); - if (apError) { - return json({ success: false, error: parseError(apError.msg, 'Approval Processes') }); - } + const [apiKeyPermissions, networks, approvalProcesses, blockExplorerKeys] = await Promise.all([ + awaitRequestOrFailWith( listApiKeyPermissions({ apiKey, apiSecret }), 'Permissions'), + awaitRequestOrFailWith( listNetworks({ apiKey, apiSecret }), 'Networks'), + awaitRequestOrFailWith( listApprovalProcesses({ apiKey, apiSecret }), 'Approval Processes'), + awaitRequestOrFailWith( listBlockExplorerKeys({ apiKey, apiSecret }), 'Block Explorer API Keys'), + ]); - let relayers: Relayer[] = []; - if (permissions?.includes('manage-relayers')) { - // List relayers to preload approval process creation selection. - const [relayersResult, relayError] = await attempt( - () => listRelayers({ apiKey, apiSecret }) - ); - if (relayError) { - return json({ success: false, error: parseError(relayError.msg, 'Relayers') }); + if (!apiKeyPermissions?.includes('manage-deployments')) { + throw new Error('API Key is not allowed to deploy contracts'); } - relayers = relayersResult ?? []; - } + const relayers: Relayer[] = + apiKeyPermissions?.includes('manage-relayers') ? + await awaitRequestOrFailWith(listRelayers({ apiKey, apiSecret }), 'Relayers') + : [] - return json({ - success: true, - data: { - permissions, + const authenticationResponse: AuthenticationResponse = { + permissions: apiKeyPermissions, + blockExplorerKeys, networks, approvalProcesses, relayers, credentials: { apiKey, apiSecret }, } - }); + + return json({ + success: true, + data: authenticationResponse + }); + + } catch(error){ + return json({ success: false, error: (error as Error).message }); + } } \ No newline at end of file diff --git a/src/routes/compiler/compiler.ts b/src/routes/compiler/compiler.ts index 5582bf6..0fa618e 100644 --- a/src/routes/compiler/compiler.ts +++ b/src/routes/compiler/compiler.ts @@ -1,20 +1,8 @@ import solc from 'solc'; - -import type { ContractSources } from "$lib/models/solc"; import type { CompilerInput } from "$lib/models/solc"; export class SolidityCompiler { - getContent(path: string, contents: ContractSources) { - if (contents[path]) { - return contents[path]; - } - return { error: 'File not found' }; - } - - compile(input: CompilerInput, contents?: ContractSources) { - 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; + compile(input: CompilerInput) { + return solc.compile(JSON.stringify(input)); } } diff --git a/vite.config.ts b/vite.config.ts index bbf8c7d..4bd997e 100644 --- a/vite.config.ts +++ b/vite.config.ts @@ -1,6 +1,23 @@ +import 'dotenv/config'; import { sveltekit } from '@sveltejs/kit/vite'; import { defineConfig } from 'vite'; -export default defineConfig({ - plugins: [sveltekit()] +const developmentEnvironmentVariables = [ + 'DEFENDER_POOL_ID', + 'DEFENDER_POOL_CLIENT_ID', + 'DEFENDER_API_URL', +]; + +export default defineConfig(({ mode }) => { + const defineVars: Record = {}; + + if (mode === "development") { + developmentEnvironmentVariables.forEach(env => { + defineVars[`process.env.${env}`] = JSON.stringify(process.env[env]); + }); + } + return { + plugins: [sveltekit()], + define: mode === "development" ? defineVars : undefined, + }; });