From 33129497be762b9ccde46270a0e4d212e84f664f Mon Sep 17 00:00:00 2001 From: maxx-GENIUS <340030598+maxx-GENIUS@users.noreply.github.com> Date: Fri, 6 Nov 2026 00:00:20 +0545 Subject: [PATCH] refactor(scripts): consolidate duplicate deploy scripts under workspace runner Consolidates duplicate deployment and testnet initialization scripts previously kept under contracts/contrib/scripts into the unified contracts/scripts deployment workflow. Updated documentation to point to contracts/scripts/deploy.sh. Closes #1656 --- contracts/contrib/README.md | 12 +++ contracts/contrib/scripts/.env.example | 16 ---- contracts/contrib/scripts/README.md | 104 ++------------------- contracts/contrib/scripts/deploy.sh | 97 ------------------- contracts/contrib/scripts/initialize.sh | 68 -------------- contracts/contrib/scripts/setup-testnet.sh | 69 -------------- 6 files changed, 18 insertions(+), 348 deletions(-) delete mode 100644 contracts/contrib/scripts/.env.example delete mode 100755 contracts/contrib/scripts/deploy.sh delete mode 100755 contracts/contrib/scripts/initialize.sh delete mode 100755 contracts/contrib/scripts/setup-testnet.sh diff --git a/contracts/contrib/README.md b/contracts/contrib/README.md index 754fff252..7a66c889a 100644 --- a/contracts/contrib/README.md +++ b/contracts/contrib/README.md @@ -248,3 +248,15 @@ cargo test -p contrib All tests live in [`src/tests/`](src/tests/); nothing outside it is compiled into test builds. + +## Deployment + +Deployment and initialization of `contrib` is handled via the unified workspace script: + +```sh +cd contracts +./scripts/deploy.sh --network testnet --source alice +``` + +See [`contracts/scripts/README.md`](../scripts/README.md) for full usage and configuration details. + diff --git a/contracts/contrib/scripts/.env.example b/contracts/contrib/scripts/.env.example deleted file mode 100644 index 6e927c53d..000000000 --- a/contracts/contrib/scripts/.env.example +++ /dev/null @@ -1,16 +0,0 @@ -# ─── Stellar Testnet Configuration ───────────────────────────────────────────── -# Admin account secret key (ed25519 prefixed with "S") -ADMIN_SECRET=S... - -# Stellar network passphrase -NETWORK_PASSPHRASE=Test SDF Network ; September 2015 - -# Soroban RPC endpoint -RPC_URL=https://soroban-testnet.stellar.org:443 - -# ─── Optional ────────────────────────────────────────────────────────────────── -# Network name used by the stellar CLI (--network argument) -NETWORK=testnet - -# Deployed contract ID (populated by deploy.sh, read by initialize.sh) -CONTRACT_ID= diff --git a/contracts/contrib/scripts/README.md b/contracts/contrib/scripts/README.md index 93ea98144..5817b9d83 100644 --- a/contracts/contrib/scripts/README.md +++ b/contracts/contrib/scripts/README.md @@ -1,104 +1,12 @@ -# Contrib Contract — Deploy & Initialize on Stellar Testnet +# Contrib Contract Deployment -## Prerequisites +Deployment and initialization of the `contrib` contract is consolidated into the canonical workspace deployment script. -| Tool | Version | Install | -|------|---------|---------| -| Rust | stable | `rustup default stable` | -| wasm32 target | — | `rustup target add wasm32-unknown-unknown` | -| stellar CLI | >= 22 | `cargo install stellar-cli` | -| curl | any | system package | - -## Environment Setup - -```bash -cd contracts/contrib/scripts - -# 1. Create your .env from the example -cp .env.example .env - -# 2. Fill in your admin secret key -# Generate a new keypair with: stellar keys generate -# Or use an existing one. -$EDITOR .env -``` - -The `.env` file requires three variables: - -| Variable | Description | Example | -|----------|-------------|---------| -| `ADMIN_SECRET` | Ed25519 secret key (starts with `S`) | `SBUV...` | -| `NETWORK_PASSPHRASE` | Stellar network identifier | `Test SDF Network ; September 2015` | -| `RPC_URL` | Soroban RPC endpoint | `https://soroban-testnet.stellar.org:443` | - -## Deploy Workflow - -Run the three scripts in order: - -### Step 1 — Fund the admin account - -```bash -./setup-testnet.sh -``` - -This calls [Friendbot](https://developers.stellar.org/docs/learn/fund-and-create-an-account#testnet) to credit 10,000 XLM to the admin account on Testnet. Safe to re-run (idempotent). - -### Step 2 — Compile & deploy the contract - -```bash -./deploy.sh -``` - -What it does: - -1. Compiles `contrib` to WASM via `cargo build --target wasm32-unknown-unknown --release` -2. Uploads the WASM and creates the contract instance via `stellar contract deploy` -3. Logs the **contract ID** to stdout -4. Persists the contract ID in `.env` as `CONTRACT_ID=...` - -### Step 3 — Initialize the contract - -```bash -./initialize.sh -``` - -What it does: - -1. Derives the admin public address from `ADMIN_SECRET` -2. Calls `initialize(admin)` on the deployed contract via `stellar contract invoke` -3. The contract sets the admin, marks the contract as unpaused, sets total count to 0, and authorizes the admin as a registrar - -### Verify +Please refer to [`contracts/scripts/README.md`](../../scripts/README.md) for the single documented workflow: ```bash -# Check the stored admin -stellar contract invoke \ - --id "$CONTRACT_ID" \ - --source-key "$ADMIN_SECRET" \ - --network-passphrase "$NETWORK_PASSPHRASE" \ - --rpc-url "$RPC_URL" \ - -- get_admin - -# Should print the admin's public address (G...) +cd contracts +./scripts/deploy.sh --network testnet --source alice ``` -## Redeploying - -To deploy a new instance after code changes: - -```bash -./deploy.sh # builds, deploys, saves new CONTRACT_ID to .env -./initialize.sh # initializes the new instance -``` - -> **Note:** `deploy.sh` always creates a **new** contract instance. The old contract ID remains on-chain but is no longer referenced in your `.env`. - -## Troubleshooting - -| Problem | Fix | -|---------|-----| -| `error: no such target: wasm32-unknown-unknown` | `rustup target add wasm32-unknown-unknown` | -| `stellar: command not found` | `cargo install stellar-cli` | -| `RESOURCE_EXHAUSTED` on deploy | Contract WASM too large; enable `opt-level = "z"` in `Cargo.toml` (already set) | -| `Already initialized` on invoke | Contract was already initialized. Deploy a new instance. | -| `Insufficient balance` | Run `./setup-testnet.sh` again or wait for Friendbot rate limit to reset. | +This single command handles building, optimizing, deploying, and cross-contract initialization for `contrib` and the other contracts in the AssetsUp suite. diff --git a/contracts/contrib/scripts/deploy.sh b/contracts/contrib/scripts/deploy.sh deleted file mode 100755 index e2581890a..000000000 --- a/contracts/contrib/scripts/deploy.sh +++ /dev/null @@ -1,97 +0,0 @@ -#!/usr/bin/env bash -# -# deploy.sh — Compile the contrib contract to WASM and deploy to Stellar Testnet -# -# Steps: -# 1. Build the contract with `cargo build --target wasm32-unknown-unknown --release` -# 2. Deploy the WASM to Testnet via `stellar contract deploy` -# 3. Log the contract ID and persist it to .env -# -# Prerequisites: -# - Rust toolchain with wasm32-unknown-unknown target -# - stellar CLI (>= 22) -# - .env file with ADMIN_SECRET, NETWORK_PASSPHRASE, RPC_URL -# -set -euo pipefail - -SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" -CONTRACT_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)" -WORKSPACE_ROOT="$(cd "$CONTRACT_ROOT/.." && pwd)" -ENV_FILE="${SCRIPT_DIR}/.env" - -# ── Colours ──────────────────────────────────────────────────────────────────── -GREEN='\033[0;32m'; YELLOW='\033[1;33m'; RED='\033[0;31m'; NC='\033[0m' -info() { echo -e "${GREEN}[INFO]${NC} $*"; } -warn() { echo -e "${YELLOW}[WARN]${NC} $*"; } -error() { echo -e "${RED}[ERROR]${NC} $*" >&2; exit 1; } - -# ── Load .env ────────────────────────────────────────────────────────────────── -if [[ ! -f "$ENV_FILE" ]]; then - error "$ENV_FILE not found. Copy .env.example → .env and fill in values." -fi - -set -a -# shellcheck source=/dev/null -source "$ENV_FILE" -set +a - -: "${ADMIN_SECRET:?ADMIN_SECRET must be set in $ENV_FILE}" -: "${NETWORK_PASSPHRASE:?NETWORK_PASSPHRASE must be set in $ENV_FILE}" -: "${RPC_URL:?RPC_URL must be set in $ENV_FILE}" - -# ── Step 1: Build WASM ──────────────────────────────────────────────────────── -info "Building contrib contract to WASM…" - -( - cd "$WORKSPACE_ROOT" - cargo build --package contrib --target wasm32-unknown-unknown --release -) - -WASM_PATH="${WORKSPACE_ROOT}/target/wasm32-unknown-unknown/release/contrib.wasm" - -if [[ ! -f "$WASM_PATH" ]]; then - error "WASM not found at $WASM_PATH — build may have failed." -fi - -WASM_SIZE="$(du -h "$WASM_PATH" | cut -f1)" -info "WASM built: $WASM_PATH ($WASM_SIZE)" - -# ── Step 2: Deploy to Testnet ───────────────────────────────────────────────── -info "Deploying contract to Stellar Testnet…" - -DEPLOY_OUTPUT="$( - stellar contract deploy \ - --wasm "$WASM_PATH" \ - --source-key "$ADMIN_SECRET" \ - --network-passphrase "$NETWORK_PASSPHRASE" \ - --rpc-url "$RPC_URL" \ - --ignore-checks -)" - -# stellar contract deploy prints the contract ID (e.g. C... or CA... ) -CONTRACT_ID="$(echo "$DEPLOY_OUTPUT" | tr -d '[:space:]')" - -if [[ -z "$CONTRACT_ID" ]]; then - error "Deployment output was empty. Check stellar CLI output above." -fi - -info "Contract deployed!" -info " Contract ID : $CONTRACT_ID" -info " RPC URL : $RPC_URL" - -# ── Step 3: Persist contract ID to .env ─────────────────────────────────────── -if grep -q "^CONTRACT_ID=" "$ENV_FILE"; then - sed -i.bak "s/^CONTRACT_ID=.*/CONTRACT_ID=${CONTRACT_ID}/" "$ENV_FILE" - rm -f "${ENV_FILE}.bak" -else - echo "" >> "$ENV_FILE" - echo "CONTRACT_ID=${CONTRACT_ID}" >> "$ENV_FILE" -fi - -info "Contract ID saved to $ENV_FILE" - -echo "" -echo "──────────────────────────────────────────────" -echo " Next step: initialize the contract" -echo " ./scripts/initialize.sh" -echo "──────────────────────────────────────────────" diff --git a/contracts/contrib/scripts/initialize.sh b/contracts/contrib/scripts/initialize.sh deleted file mode 100755 index 7b1f75a43..000000000 --- a/contracts/contrib/scripts/initialize.sh +++ /dev/null @@ -1,68 +0,0 @@ -#!/usr/bin/env bash -# -# initialize.sh — Call the initialize() function on the deployed contrib contract -# -# The contract's initialize(env, admin) sets the admin address and initial state. -# This script derives the admin public address from ADMIN_SECRET and invokes -# the function via `stellar contract invoke`. -# -set -euo pipefail - -SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" -ENV_FILE="${SCRIPT_DIR}/.env" - -# ── Colours ──────────────────────────────────────────────────────────────────── -GREEN='\033[0;32m'; YELLOW='\033[1;33m'; RED='\033[0;31m'; NC='\033[0m' -info() { echo -e "${GREEN}[INFO]${NC} $*"; } -warn() { echo -e "${YELLOW}[WARN]${NC} $*"; } -error() { echo -e "${RED}[ERROR]${NC} $*" >&2; exit 1; } - -# ── Load .env ────────────────────────────────────────────────────────────────── -if [[ ! -f "$ENV_FILE" ]]; then - error "$ENV_FILE not found. Copy .env.example → .env and fill in values." -fi - -set -a -# shellcheck source=/dev/null -source "$ENV_FILE" -set +a - -: "${ADMIN_SECRET:?ADMIN_SECRET must be set in $ENV_FILE}" -: "${NETWORK_PASSPHRASE:?NETWORK_PASSPHRASE must be set in $ENV_FILE}" -: "${RPC_URL:?RPC_URL must be set in $ENV_FILE}" -: "${CONTRACT_ID:?CONTRACT_ID must be set in $ENV_FILE (run deploy.sh first)}" - -# ── Derive admin address ────────────────────────────────────────────────────── -info "Deriving admin address from ADMIN_SECRET…" - -ADMIN_ADDRESS="$(stellar keys address --secret-key "$ADMIN_SECRET" 2>/dev/null || \ - echo "$ADMIN_SECRET" | stellar keys address 2>/dev/null || \ - printf '%s' "$ADMIN_SECRET" | stellar keys address)" - -if [[ -z "$ADMIN_ADDRESS" ]]; then - error "Could not derive admin address from ADMIN_SECRET." -fi - -info "Admin address: $ADMIN_ADDRESS" - -# ── Invoke initialize ───────────────────────────────────────────────────────── -info "Calling initialize(admin: $ADMIN_ADDRESS) on contract $CONTRACT_ID…" - -stellar contract invoke \ - --id "$CONTRACT_ID" \ - --source-key "$ADMIN_SECRET" \ - --network-passphrase "$NETWORK_PASSPHRASE" \ - --rpc-url "$RPC_URL" \ - -- \ - initialize \ - --admin "$ADMIN_ADDRESS" - -info "Contract initialized successfully!" -info "" -info "You can verify by calling get_admin:" -info " stellar contract invoke \\" -info " --id $CONTRACT_ID \\" -info " --source-key \"\$ADMIN_SECRET\" \\" -info " --network-passphrase \"\$NETWORK_PASSPHRASE\" \\" -info " --rpc-url \"\$RPC_URL\" \\" -info " -- get_admin" diff --git a/contracts/contrib/scripts/setup-testnet.sh b/contracts/contrib/scripts/setup-testnet.sh deleted file mode 100755 index 024accb0b..000000000 --- a/contracts/contrib/scripts/setup-testnet.sh +++ /dev/null @@ -1,69 +0,0 @@ -#!/usr/bin/env bash -# -# setup-testnet.sh — Fund the admin account on Stellar Testnet via Friendbot -# -# Usage: -# ./setup-testnet.sh # reads ADMIN_SECRET from .env -# ./setup-testnet.sh # fund an arbitrary address -# -set -euo pipefail - -SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" -ENV_FILE="${SCRIPT_DIR}/.env" - -# ── Load .env ────────────────────────────────────────────────────────────────── -if [[ ! -f "$ENV_FILE" ]]; then - echo "ERROR: $ENV_FILE not found. Copy .env.example and fill in values." >&2 - exit 1 -fi - -set -a -# shellcheck source=/dev/null -source "$ENV_FILE" -set +a - -# ── Derive public key from secret ───────────────────────────────────────────── -if [[ -n "${1:-}" ]]; then - ADMIN_PUBLIC="$1" -else - if [[ -z "${ADMIN_SECRET:-}" ]]; then - echo "ERROR: ADMIN_SECRET is not set in $ENV_FILE" >&2 - exit 1 - fi - - ADMIN_PUBLIC="$(stellar keys address --secret-key "$ADMIN_SECRET" 2>/dev/null || \ - echo "$ADMIN_SECRET" | stellar keys address 2>/dev/null || \ - printf '%s' "$ADMIN_SECRET" | stellar keys address)" - - if [[ -z "$ADMIN_PUBLIC" ]]; then - echo "ERROR: Could not derive public key from ADMIN_SECRET" >&2 - exit 1 - fi -fi - -echo "Funding account: $ADMIN_PUBLIC" - -# ── Call Friendbot ───────────────────────────────────────────────────────────── -RESPONSE=$(curl -sS "https://friendbot.stellar.org/?addr=${ADMIN_PUBLIC}") || { - echo "ERROR: Failed to reach Friendbot" >&2 - exit 1 -} - -# Friendbot returns the transaction envelope on success or JSON error -if echo "$RESPONSE" | grep -q '"hash"'; then - echo "Account funded successfully!" - echo " Address : $ADMIN_PUBLIC" - echo " Tx hash : $(echo "$RESPONSE" | grep -o '"hash":"[^"]*"' | cut -d'"' -f4)" -else - # Already funded accounts return a friendly message - if echo "$RESPONSE" | grep -qi "already"; then - echo "Account already funded: $ADMIN_PUBLIC" - else - echo "WARNING: Unexpected Friendbot response:" >&2 - echo "$RESPONSE" >&2 - fi -fi - -echo "" -echo "Verify on Testnet explorer:" -echo " https://stellar.expert/explorer/testnet/account/$ADMIN_PUBLIC"