Skip to content
Closed
Show file tree
Hide file tree
Changes from 6 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
186 changes: 186 additions & 0 deletions .github/workflows/deploy-dawn-mainnet.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,186 @@
name: "Deploy Dawn Mainnet Contracts"

permissions:
contents: read

on:
workflow_dispatch:
inputs:
fund_amount:
description: "Amount of ETH to fund the paymaster (e.g., 0.1)"
required: false
default: "0"
deploy_bundler:
description: "Deploy bundler service"
type: boolean
required: false
default: false
deploy_auth_server:
description: "Deploy auth server"
type: boolean
required: false
default: false

env:
HUSKY: 0
CI: true

jobs:
deploy-contracts:
permissions:
contents: write
runs-on: ubuntu-latest
outputs:
contracts: ${{ steps.deploy.outputs.contracts }}
steps:
- uses: actions/checkout@v4
with:
submodules: recursive

- name: Setup pnpm
uses: pnpm/action-setup@v4
with:
version: 9.11.0

- name: Use Node.js
uses: actions/setup-node@v4
with:
node-version: lts/Iron
cache: "pnpm"

- name: Install dependencies
run: pnpm install -r --frozen-lockfile

- name: Install contract dependencies
run: pnpm install -r --frozen-lockfile
working-directory: packages/contracts

- name: Build contracts
run: pnpm build
working-directory: packages/contracts

- name: Deploy contracts to Dawn Mainnet
id: deploy
env:
WALLET_PRIVATE_KEY: ${{ secrets.DAWN_MAINNET_DEPLOYER_PRIVATE_KEY }}
KEY_REGISTRY_OWNER_PRIVATE_KEY: ${{ secrets.DAWN_MAINNET_KEY_REGISTRY_OWNER_PRIVATE_KEY }}
run: |
# Deploy all contracts
pnpm hardhat deploy \
--network dawnMainnet \
--file ../auth-server/stores/dawn-mainnet.json \
--fund ${{ github.event.inputs.fund_amount }} \
--keyregistryowner $KEY_REGISTRY_OWNER_PRIVATE_KEY

# Read the deployed contracts
echo "contracts=$(cat ../auth-server/stores/dawn-mainnet.json)" >> $GITHUB_OUTPUT
working-directory: packages/contracts

- name: Initialize OIDC Key Registry with Google keys
env:
WALLET_PRIVATE_KEY: ${{ secrets.DAWN_MAINNET_KEY_REGISTRY_OWNER_PRIVATE_KEY }}
run: |
pnpm hardhat run scripts/add-google-keys.ts --network dawnMainnet
working-directory: packages/contracts

- name: Verify deployment
env:
WALLET_PRIVATE_KEY: ${{ secrets.DAWN_MAINNET_DEPLOYER_PRIVATE_KEY }}
run: |
node verify-dawn-deployment.js
working-directory: packages/contracts

- name: Upload deployment artifacts
uses: actions/upload-artifact@v4
with:
name: dawn-mainnet-deployment
path: packages/auth-server/stores/dawn-mainnet.json
retention-days: 90

- name: Comment deployment info on commit
uses: actions/github-script@v7
with:
script: |
const contracts = JSON.parse('${{ steps.deploy.outputs.contracts }}');
const comment = `
## 🚀 Dawn Mainnet Deployment Complete

**Network:** Dawn Mainnet (Chain ID: 30715)
**RPC URL:** https://zksync-os-mainnet-dawn.zksync.io
**Block Explorer:** https://zksync-os-mainnet-dawn.staging-scan-v2.zksync.dev

### Deployed Contracts

| Contract | Address |
|----------|---------|
| Factory | \`${contracts.accountFactory}\` |
| WebAuthn Validator | \`${contracts.passkey}\` |
| Session Validator | \`${contracts.session}\` |
| Beacon | \`${contracts.beacon}\` |
| Guardian Recovery | \`${contracts.recovery}\` |
| OIDC Recovery | \`${contracts.recoveryOidc}\` |
| OIDC Key Registry | \`${contracts.oidcKeyRegistry}\` |
| Paymaster | \`${contracts.accountPaymaster}\` |

### Next Steps
1. Add these addresses to \`packages/auth-server/stores/client.ts\`
2. Update bundler configuration if deploying bundler service
3. Deploy auth-server if needed
4. Test account creation and transactions
`;

github.rest.repos.createCommitComment({
owner: context.repo.owner,
repo: context.repo.repo,
commit_sha: context.sha,
body: comment
});

deploy-bundler:
needs: deploy-contracts
if: ${{ github.event.inputs.deploy_bundler == 'true' }}
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4

- name: Deploy Bundler Service
run: |
echo "Bundler deployment would happen here"
# TODO: Add bundler deployment steps when ready

deploy-auth-server:
needs: deploy-contracts
if: ${{ github.event.inputs.deploy_auth_server == 'true' }}
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4

- name: Setup pnpm
uses: pnpm/action-setup@v4
with:
version: 9.11.0

- name: Use Node.js
uses: actions/setup-node@v4
with:
node-version: lts/Iron
cache: "pnpm"

- name: Download deployment artifacts
uses: actions/download-artifact@v4
with:
name: dawn-mainnet-deployment
path: packages/auth-server/stores/

- name: Install dependencies
run: pnpm install -r --frozen-lockfile

- name: Build auth server
run: pnpm nx build auth-server
env:
NUXT_PUBLIC_CHAIN_ID: 30715

- name: Deploy to Firebase (or other hosting)
run: |
echo "Auth server deployment would happen here"
# TODO: Configure Firebase or other hosting for Dawn Mainnet
1 change: 1 addition & 0 deletions cspell-config/cspell-misc.txt
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ ethereum
sepolia
foundryup
unpermitted
gwei

// auth-server
oidc
Expand Down
14 changes: 1 addition & 13 deletions packages/auth-server/app.vue
Original file line number Diff line number Diff line change
Expand Up @@ -5,19 +5,7 @@
</template>

<script lang="ts" setup>
import { createAppKit } from "@reown/appkit/vue";

const { defaultChain } = useClientStore();
const { metadata, projectId, wagmiAdapter } = useAppKit();

createAppKit({
adapters: [wagmiAdapter],
networks: [defaultChain],
projectId,
metadata,
});

// BigInt polyfill
// BigInt polyfill for JSON serialization
// eslint-disable-next-line @typescript-eslint/no-explicit-any
(BigInt.prototype as any).toJSON = function () {
return this.toString();
Expand Down
8 changes: 6 additions & 2 deletions packages/auth-server/composables/useAppKit.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,15 @@ export const useAppKit = () => {
const { defaultChain } = useClientStore();

const projectId = runtimeConfig.public.appKitProjectId;

// Use fallback for SSR/build time when window is not available
const origin = typeof window !== "undefined" ? window.location.origin : "https://auth.zksync.dev";

const metadata = {
name: "ZKsync SSO Auth Server",
description: "ZKsync SSO Auth Server",
url: window.location.origin,
icons: [new URL("/icon-512.png", window.location.origin).toString()],
url: origin,
icons: [new URL("/icon-512.png", origin).toString()],
};

const wagmiAdapter = new WagmiAdapter({
Expand Down
55 changes: 55 additions & 0 deletions packages/auth-server/plugins/appkit.client.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
import { createAppKit } from "@reown/appkit/vue";

export default defineNuxtPlugin(async () => {
const { defaultChain } = useClientStore();

// Dynamic import to ensure browser globals are available
const { WagmiAdapter } = await import("@reown/appkit-adapter-wagmi");
const runtimeConfig = useRuntimeConfig();

const projectId = runtimeConfig.public.appKitProjectId;
const origin = window.location.origin;

const metadata = {
name: "ZKsync SSO Auth Server",
description: "ZKsync SSO Auth Server",
url: origin,
icons: [new URL("/icon-512.png", origin).toString()],
};

// Create plain chain object to avoid Viem Proxy issues
const plainChain = {
id: defaultChain.id,
name: defaultChain.name,
nativeCurrency: {
name: defaultChain.nativeCurrency.name,
symbol: defaultChain.nativeCurrency.symbol,
decimals: defaultChain.nativeCurrency.decimals,
},
rpcUrls: {
default: {
http: [...defaultChain.rpcUrls.default.http],
},
},
blockExplorers: defaultChain.blockExplorers
? {
default: {
name: defaultChain.blockExplorers.default.name,
url: defaultChain.blockExplorers.default.url,
},
}
: undefined,
};

const wagmiAdapter = new WagmiAdapter({
networks: [plainChain],
projectId,
});

createAppKit({
adapters: [wagmiAdapter],
networks: [plainChain],
projectId,
metadata,
});
});
38 changes: 37 additions & 1 deletion packages/auth-server/stores/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,17 +42,40 @@ const zksyncOsLocal = defineChain({
},
});

export const supportedChains = [localhost, zksyncOsTestnet, zksyncOsLocal];
const dawnMainnet = defineChain({
id: 30715,
name: "Dawn Mainnet",
nativeCurrency: {
name: "Ether",
symbol: "ETH",
decimals: 18,
},
rpcUrls: {
default: {
http: ["https://zksync-os-mainnet-dawn.zksync.io"],
},
},
blockExplorers: {
default: {
name: "Dawn Mainnet Explorer",
url: "https://zksync-os-mainnet-dawn.staging-scan-v2.zksync.dev",
},
},
});

export const supportedChains = [localhost, zksyncOsTestnet, zksyncOsLocal, dawnMainnet];
export type SupportedChainId = (typeof supportedChains)[number]["id"];
export const blockExplorerUrlByChain: Record<SupportedChainId, string> = {
[localhost.id]: "http://localhost:3010",
[zksyncOsTestnet.id]: "https://zksync-os-testnet-alpha.staging-scan-v2.zksync.dev",
[zksyncOsLocal.id]: "",
[dawnMainnet.id]: "https://zksync-os-mainnet-dawn.staging-scan-v2.zksync.dev",
};
export const blockExplorerApiByChain: Record<SupportedChainId, string> = {
[localhost.id]: "http://localhost:3020",
[zksyncOsTestnet.id]: "https://block-explorer-api.zksync-os-testnet-alpha.zksync.dev/api",
[zksyncOsLocal.id]: "",
[dawnMainnet.id]: "https://block-explorer-api.zksync-os-mainnet-dawn.zksync.io",
};

type ChainContracts = {
Expand All @@ -79,6 +102,16 @@ export const contractsByChain: Record<SupportedChainId, ChainContracts> = {
bundlerUrl: "https://bundler-api.stage-sso.zksync.dev",
beacon: "0x1D779D791B55a093dE60da664C3F301a87f96C62",
},
[dawnMainnet.id]: {
eoaValidator: "0xe7f1725E7734CE288F8367e1Bb143E90bb3F0512",
webauthnValidator: "0x5FC8d32690cc91D4c39d9d3abcBD16989F875707",
sessionValidator: "0xCf7Ed3AccA5a467e9e704C703E8D87F634fB0Fc9",
factory: "0xB7f8BC63BbcaD18155201308C8f3540b07f84F5e",
bundlerUrl: "https://bundler-api.dawn-mainnet.zksync.io", // Update with actual bundler URL when available
beacon: "0x8A791620dd6260079BF849Dc5567aDC3F2FdC318",
guardianExecutor: "0xa513E6E4b8f2a923D98304ec87F64353C4D5C853",
accountPaymaster: "0x959922bE3CAee4b8Cd9a407cc3ac1C251C2007B1", // MockPaymaster
},
};

export const chainParameters: Record<SupportedChainId, { blockTime: number }> = {
Expand All @@ -91,6 +124,9 @@ export const chainParameters: Record<SupportedChainId, { blockTime: number }> =
[zksyncOsTestnet.id]: {
blockTime: 1,
},
[dawnMainnet.id]: {
blockTime: 1,
},
};

export const useClientStore = defineStore("client", () => {
Expand Down
10 changes: 10 additions & 0 deletions packages/auth-server/stores/dawn-mainnet.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"eoaValidator": "0xe7f1725E7734CE288F8367e1Bb143E90bb3F0512",
"sessionValidator": "0xCf7Ed3AccA5a467e9e704C703E8D87F634fB0Fc9",
"webauthnValidator": "0x5FC8d32690cc91D4c39d9d3abcBD16989F875707",
"guardianExecutor": "0xa513E6E4b8f2a923D98304ec87F64353C4D5C853",
"accountImplementation": "0x2279B7A0a67DB372996a5FaB50D91eAA73d2eBe6",
"beacon": "0x8A791620dd6260079BF849Dc5567aDC3F2FdC318",
"factory": "0xB7f8BC63BbcaD18155201308C8f3540b07f84F5e",
"entryPoint": "0x9A9f2CCfdE556A7E9Ff0848998Aa4a0CFD8863AE"
}
Loading
Loading