Skip to content
Draft
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: 2 additions & 1 deletion devnet/0-all.sh
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,5 @@ set -e
./3-op-init.sh
./4-op-start-service.sh
./5-run-op-succinct.sh
./6-run-kailua.sh
./6-run-kailua.sh
./7-run-railgain.sh
140 changes: 140 additions & 0 deletions devnet/7-run-railgain.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
#!/bin/bash
set -e

PWD_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
RAILGUN_DIR="$PWD_DIR/railgun"
RAILGUN_ENV_FILE="$RAILGUN_DIR/.env.railgun"

# Load environment variables
source .env

# Load RAILGUN internal configuration (if exists)
if [ -f "$RAILGUN_ENV_FILE" ]; then
source "$RAILGUN_ENV_FILE"
fi

sed_inplace() {
if [[ "$OSTYPE" == "darwin"* ]]; then
sed -i '' "$@"
else
sed -i "$@"
fi
}

if [ "$RAILGUN_ENABLE" != "true" ]; then
echo "⏭️ Skipping RAILGUN (RAILGUN_ENABLE=$RAILGUN_ENABLE)"
exit 0
fi

if [ ! -f "$RAILGUN_ENV_FILE" ]; then
cp "$RAILGUN_DIR/example.env.railgun" "$RAILGUN_ENV_FILE"
fi

echo "📜 Step 1/3: Deploying RAILGUN Contracts (Docker)"

RAILGUN_CONTRACT_IMAGE_TAG="${RAILGUN_CONTRACT_IMAGE_TAG:-railgun-contract:latest}"

# Deploy contracts using Docker
echo "📜 Deploying RAILGUN smart contracts using Docker..."
echo " ℹ️ Network: xlayer-devnet"
echo " ℹ️ RPC: $L2_RPC_URL"
echo " ℹ️ Chain ID: $CHAIN_ID"

TEMP_DEPLOY_LOG="/tmp/railgun-deploy-$$.log"

docker run --rm \
-e RPC_URL="${L2_RPC_URL/localhost/host.docker.internal}" \
-e CHAIN_ID="$CHAIN_ID" \
-e DEPLOYER_PRIVATE_KEY="$OP_PROPOSER_PRIVATE_KEY" \
--add-host=host.docker.internal:host-gateway \
"$RAILGUN_CONTRACT_IMAGE_TAG" \
deploy:test --network xlayer-devnet 2>&1 | tee "$TEMP_DEPLOY_LOG"

DEPLOY_STATUS=${PIPESTATUS[0]}
DEPLOY_OUTPUT=$(cat "$TEMP_DEPLOY_LOG")

if [ $DEPLOY_STATUS -ne 0 ]; then
echo " ❌ Contract deployment failed"
rm -f "$TEMP_DEPLOY_LOG" 2>/dev/null
exit 1
fi
echo " ✅ Contracts deployed successfully"

echo "🔍 Extracting contract addresses..."
PROXY_ADDR=$(echo "$DEPLOY_OUTPUT" | grep -A 20 "DEPLOY CONFIG:" | grep "proxy:" | sed -n "s/.*proxy: '\([^']*\)'.*/\1/p" | head -1)
RELAY_ADAPT_ADDR=$(echo "$DEPLOY_OUTPUT" | grep -A 20 "DEPLOY CONFIG:" | grep "relayAdapt:" | sed -n "s/.*relayAdapt: '\([^']*\)'.*/\1/p" | head -1)
POSEIDON_T4_ADDR=$(echo "$DEPLOY_OUTPUT" | grep -A 20 "DEPLOY CONFIG:" | grep "poseidonT4:" | sed -n "s/.*poseidonT4: '\([^']*\)'.*/\1/p" | head -1)

if [ -n "$PROXY_ADDR" ] && [ "$PROXY_ADDR" != "null" ]; then
echo " ✅ Found RailgunSmartWallet (proxy): $PROXY_ADDR"
export RAILGUN_SMART_WALLET_ADDRESS="$PROXY_ADDR"
sed_inplace "s|^RAILGUN_SMART_WALLET_ADDRESS=.*|RAILGUN_SMART_WALLET_ADDRESS=$RAILGUN_SMART_WALLET_ADDRESS|" "$RAILGUN_ENV_FILE"
fi

if [ -n "$RELAY_ADAPT_ADDR" ] && [ "$RELAY_ADAPT_ADDR" != "null" ]; then
echo " ✅ Found RelayAdapt: $RELAY_ADAPT_ADDR"
export RAILGUN_RELAY_ADAPT_ADDRESS="$RELAY_ADAPT_ADDR"
sed_inplace "s|^RAILGUN_RELAY_ADAPT_ADDRESS=.*|RAILGUN_RELAY_ADAPT_ADDRESS=$RELAY_ADAPT_ADDR|" "$RAILGUN_ENV_FILE"
fi

if [ -n "$POSEIDON_T4_ADDR" ] && [ "$POSEIDON_T4_ADDR" != "null" ]; then
echo " ✅ Found PoseidonT4: $POSEIDON_T4_ADDR"
export RAILGUN_POSEIDONT4_ADDRESS="$POSEIDON_T4_ADDR"
sed_inplace "s|^RAILGUN_POSEIDONT4_ADDRESS=.*|RAILGUN_POSEIDONT4_ADDRESS=$POSEIDON_T4_ADDR|" "$RAILGUN_ENV_FILE"
fi

echo "🔍 Verifying contract deployment..."

VERIFICATION_RESPONSE=$(curl -s -X POST \
-H "Content-Type: application/json" \
--data "{\"jsonrpc\":\"2.0\",\"method\":\"eth_getCode\",\"params\":[\"$RAILGUN_SMART_WALLET_ADDRESS\",\"latest\"],\"id\":1}" \
"$L2_RPC_URL" 2>/dev/null)

if echo "$VERIFICATION_RESPONSE" | grep -q '"result":"0x"'; then
echo " ❌ Contract not found at address: $RAILGUN_SMART_WALLET_ADDRESS"
exit 1
else
echo " ✅ Contract verified on L2"
fi

echo "🔍 Getting deployment block height..."

BLOCK_RESPONSE=$(curl -s -X POST \
-H "Content-Type: application/json" \
--data '{"jsonrpc":"2.0","method":"eth_blockNumber","params":[],"id":1}' \
"$L2_RPC_URL" 2>/dev/null)

DEPLOY_BLOCK=$(echo "$BLOCK_RESPONSE" | grep -o '"result":"0x[^"]*"' | cut -d'"' -f4)
DEPLOY_BLOCK_DEC=$((16#${DEPLOY_BLOCK#0x}))

if [ -n "$DEPLOY_BLOCK_DEC" ]; then
echo " ✅ Deployment block: $DEPLOY_BLOCK_DEC"
export RAILGUN_DEPLOY_BLOCK="$DEPLOY_BLOCK_DEC"

# Save to railgun/.env.railgun
if grep -q "^RAILGUN_DEPLOY_BLOCK=" "$RAILGUN_ENV_FILE"; then
sed_inplace "s|^RAILGUN_DEPLOY_BLOCK=.*|RAILGUN_DEPLOY_BLOCK=$RAILGUN_DEPLOY_BLOCK|" "$RAILGUN_ENV_FILE"
else
echo "RAILGUN_DEPLOY_BLOCK=$RAILGUN_DEPLOY_BLOCK" >> "$RAILGUN_ENV_FILE"
fi
else
echo " ⚠️ Could not determine deployment block, using 0"
export RAILGUN_DEPLOY_BLOCK="0"
fi

rm -f "$TEMP_DEPLOY_LOG" 2>/dev/null
echo "✅ Contract deployment completed"

echo "🪙 Step 2/3: Deploying Test ERC20 Token"
./scripts/deploy-test-token.sh || {
echo "❌ Failed to deploy test token"
exit 1
}

echo "🧪 Step 3/3: Run Wallet Tests"
./scripts/run-railgun-wallet.sh || {
echo "❌ Wallet test failed"
exit 1
}

echo "🎉 Complete Railgun Flow Finished Successfully!"
13 changes: 13 additions & 0 deletions devnet/example.env
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,19 @@ KAILUA_LOCAL_DIRECTORY=
SKIP_KAILUA_BUILD=true
KAILUA_IMAGE_TAG=kailua:latest

# ==============================================================================
# RAILGUN Privacy System Configuration
# ==============================================================================
RAILGUN_ENABLE=false
# from: https://github.com/Railgun-Privacy/contract.git
RAILGUN_CONTRACT_DIR=
RAILGUN_CONTRACT_IMAGE_TAG=railgun-contract:latest
SKIP_RAILGUN_CONTRACT_BUILD=true
# from: https://github.com/ethereum/kohaku.git
RAILGUN_KOHAKU_LOCAL_DIRECTORY=
RAILGUN_SDK_IMAGE_TAG=railgun-sdk:latest
SKIP_RAILGUN_SDK_BUILD=true

# ==============================================================================
# Build Configuration
# ==============================================================================
Expand Down
35 changes: 35 additions & 0 deletions devnet/init.sh
Original file line number Diff line number Diff line change
Expand Up @@ -152,3 +152,38 @@ else
build_and_tag_image "kailua" "$KAILUA_IMAGE_TAG" "$KAILUA_LOCAL_DIRECTORY" "Dockerfile.local"
fi
fi

# Build RAILGUN SDK Test image
if [ "$SKIP_RAILGUN_SDK_BUILD" = "true" ]; then
echo "⏭️ Skipping railgun SDK build"
else
if [ -z "$RAILGUN_KOHAKU_LOCAL_DIRECTORY" ]; then
echo "❌ Please set RAILGUN_KOHAKU_LOCAL_DIRECTORY in .env"
exit 1
fi
echo "🔨 Building railgun SDK image"
docker build -t "${RAILGUN_SDK_IMAGE_TAG:-railgun-sdk:latest}" \
-f "$PWD_DIR/railgun/Dockerfile.sdk" \
--build-context kohaku="$RAILGUN_KOHAKU_LOCAL_DIRECTORY" \
--progress=plain \
"$PWD_DIR/railgun"
echo "✅ Built: ${RAILGUN_SDK_IMAGE_TAG:-railgun-sdk:latest}"
fi

# Build RAILGUN Contract Deploy image
if [ "$SKIP_RAILGUN_CONTRACT_BUILD" = "true" ]; then
echo "⏭️ Skipping railgun contract build"
else
if [ -z "$RAILGUN_CONTRACT_DIR" ]; then
echo "❌ Please set RAILGUN_CONTRACT_DIR in .env"
exit 1
fi

echo "🔨 Building railgun contract image"
docker build -t "${RAILGUN_CONTRACT_IMAGE_TAG:-railgun-contract:latest}" \
-f "$PWD_DIR/railgun/Dockerfile.contract" \
--build-context contract="$RAILGUN_CONTRACT_DIR" \
--progress=plain \
"$PWD_DIR/railgun"
echo "✅ Built: ${RAILGUN_CONTRACT_IMAGE_TAG:-railgun-contract:latest}"
fi
75 changes: 75 additions & 0 deletions devnet/railgun/Dockerfile.contract
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
FROM node:18-alpine AS builder

WORKDIR /build

# Install build dependencies
RUN apk add --no-cache python3 make g++

# Copy contract source from build context
COPY --from=contract . /build/contract

WORKDIR /build/contract

# Modification 1: Add xlayer-devnet network to hardhat.config.ts
RUN sed -i '/^};$/i\
networks: {\
"xlayer-devnet": {\
url: process.env.RPC_URL || "http://localhost:8123",\
chainId: parseInt(process.env.CHAIN_ID || "195"),\
accounts: process.env.DEPLOYER_PRIVATE_KEY ? [process.env.DEPLOYER_PRIVATE_KEY] : [],\
gasPrice: 1000000000,\
},\
},' hardhat.config.ts

# Modification 2: Add logVerify for PoseidonT3
RUN sed -i '/const poseidonT3 = await PoseidonT3\.deploy();/a\
await logVerify('\''PoseidonT3'\'', poseidonT3, []);' \
tasks/deploy/test.ts

# Modification 3: Add logVerify for PoseidonT4
RUN sed -i '/const poseidonT4 = await PoseidonT4\.deploy();/a\
await logVerify('\''PoseidonT4'\'', poseidonT4, []);' \
tasks/deploy/test.ts

# Modification 4: Add poseidon addresses to deployment output
RUN sed -i '/implementation: implementation\.address,/a\
poseidonT3: poseidonT3.address,\
poseidonT4: poseidonT4.address,' \
tasks/deploy/test.ts

# Verify modifications were applied
RUN echo "✅ Checking modifications..." && \
grep -q "xlayer-devnet" hardhat.config.ts && \
echo " ✓ hardhat.config.ts modified" && \
grep -q "logVerify.*PoseidonT3" tasks/deploy/test.ts && \
echo " ✓ PoseidonT3 logVerify added" && \
grep -q "logVerify.*PoseidonT4" tasks/deploy/test.ts && \
echo " ✓ PoseidonT4 logVerify added" && \
grep -q "poseidonT3: poseidonT3.address" tasks/deploy/test.ts && \
echo " ✓ Poseidon addresses added to output" || \
(echo "❌ Modifications failed" && exit 1)

RUN if [ -f yarn.lock ]; then \
echo "📦 Installing with yarn..." && \
yarn install --frozen-lockfile --network-timeout 300000; \
else \
echo "📦 Installing with npm..." && \
npm install; \
fi

FROM node:18-alpine

WORKDIR /app

# Copy built contract with modifications
COPY --from=builder /build/contract /app

# Set default environment variables
ENV NETWORK=xlayer-devnet
ENV RPC_URL=http://host.docker.internal:8123
ENV CHAIN_ID=195

# Entrypoint: run hardhat deploy
ENTRYPOINT ["npx", "hardhat"]
CMD ["deploy:test", "--network", "xlayer-devnet"]

69 changes: 69 additions & 0 deletions devnet/railgun/Dockerfile.sdk
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
# Stage 1: Build Kohaku from external source
FROM node:22-alpine AS kohaku-builder

WORKDIR /build

# Install build dependencies
RUN apk add --no-cache python3 make g++

# Install pnpm
RUN npm install -g pnpm

# Copy Kohaku source (from build context)
COPY --from=kohaku . /build/kohaku

WORKDIR /build/kohaku

# Modify circuit-artifacts URL in railgun package
RUN cd packages/railgun && \
sed -i 's|https://npm.railgun.org/railgun-community-circuit-artifacts-0.0.1.tgz|https://ipfs-lb.com/ipfs/QmPvs6Lws1MS4CTMAQ6P3WfyFpWFKGu7o6cSbWCu3vgXLW/railgun-circuit-test-artifacts-0.0.1.tgz|g' package.json

# Install and build with network retries
RUN pnpm install --no-frozen-lockfile \
--fetch-retries=5 \
--fetch-retry-mintimeout=20000 \
--fetch-retry-maxtimeout=120000 && \
pnpm -r build || true

# Verify railgun package was built
RUN test -f packages/railgun/dist/index.d.ts || (echo "❌ Railgun build failed" && exit 1)

# Pack the railgun package
RUN cd packages/railgun && \
pnpm pack && \
mv *.tgz /build/kohaku-railgun.tgz

# ============================================================================
# Stage 2: Runtime image
# ============================================================================
FROM node:22-alpine

WORKDIR /app

# Install pnpm
RUN npm install -g pnpm

# Copy built Kohaku package from builder
COPY --from=kohaku-builder /build/kohaku-railgun.tgz ./kohaku-railgun.tgz

# Copy application files
COPY package.json ./
COPY test-kohaku.ts ./

# Install test dependencies (using local kohaku package)
# Note: Need devDependencies (tsx, typescript) to run tests
RUN pnpm install --no-frozen-lockfile

# Cleanup
RUN rm -f kohaku-railgun.tgz

# Set default environment variables
ENV CHAIN_ID=195
ENV RPC_URL=http://host.docker.internal:8123

# Health check
HEALTHCHECK --interval=30s --timeout=10s --start-period=5s --retries=3 \
CMD node -e "console.log('OK')" || exit 1

ENTRYPOINT ["pnpm", "test:kohaku"]

6 changes: 6 additions & 0 deletions devnet/railgun/example.env.railgun
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# auto-generated
RAILGUN_SMART_WALLET_ADDRESS=
RAILGUN_RELAY_ADAPT_ADDRESS=
RAILGUN_POSEIDONT4_ADDRESS=
RAILGUN_TEST_TOKEN_ADDRESS=
RAILGUN_DEPLOY_BLOCK=
24 changes: 24 additions & 0 deletions devnet/railgun/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
{
"name": "railgun-devnet-test",
"version": "1.0.0",
"description": "RAILGUN DevNet Integration Test (Kohaku SDK)",
"main": "test-kohaku.ts",
"scripts": {
"test": "tsx test-kohaku.ts",
"test:kohaku": "tsx test-kohaku.ts"
},
"dependencies": {
"@kohaku-eth/railgun": "file:./kohaku-railgun.tgz",
"ethers": "^6.10.0",
"snarkjs": "^0.7.5",
"@railgun-community/circuit-artifacts": "https://ipfs-lb.com/ipfs/QmPvs6Lws1MS4CTMAQ6P3WfyFpWFKGu7o6cSbWCu3vgXLW/railgun-circuit-test-artifacts-0.0.1.tgz"
},
"devDependencies": {
"@types/node": "^20.0.0",
"tsx": "^4.7.0",
"typescript": "^5.3.0"
},
"engines": {
"node": ">=14.0.0"
}
}
Loading