Skip to content

Commit 97cac45

Browse files
committed
sdk, infinity scrool and initialization scripts
1 parent 61b652f commit 97cac45

9 files changed

Lines changed: 696 additions & 98 deletions

File tree

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
# ─── Stellar Testnet Configuration ─────────────────────────────────────────────
2+
# Admin account secret key (ed25519 prefixed with "S")
3+
ADMIN_SECRET=S...
4+
5+
# Stellar network passphrase
6+
NETWORK_PASSPHRASE=Test SDF Network ; September 2015
7+
8+
# Soroban RPC endpoint
9+
RPC_URL=https://soroban-testnet.stellar.org:443
10+
11+
# ─── Optional ──────────────────────────────────────────────────────────────────
12+
# Network name used by the stellar CLI (--network argument)
13+
NETWORK=testnet
14+
15+
# Deployed contract ID (populated by deploy.sh, read by initialize.sh)
16+
CONTRACT_ID=
Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
# Contrib Contract — Deploy & Initialize on Stellar Testnet
2+
3+
## Prerequisites
4+
5+
| Tool | Version | Install |
6+
|------|---------|---------|
7+
| Rust | stable | `rustup default stable` |
8+
| wasm32 target || `rustup target add wasm32-unknown-unknown` |
9+
| stellar CLI | >= 22 | `cargo install stellar-cli` |
10+
| curl | any | system package |
11+
12+
## Environment Setup
13+
14+
```bash
15+
cd contracts/contrib/scripts
16+
17+
# 1. Create your .env from the example
18+
cp .env.example .env
19+
20+
# 2. Fill in your admin secret key
21+
# Generate a new keypair with: stellar keys generate
22+
# Or use an existing one.
23+
$EDITOR .env
24+
```
25+
26+
The `.env` file requires three variables:
27+
28+
| Variable | Description | Example |
29+
|----------|-------------|---------|
30+
| `ADMIN_SECRET` | Ed25519 secret key (starts with `S`) | `SBUV...` |
31+
| `NETWORK_PASSPHRASE` | Stellar network identifier | `Test SDF Network ; September 2015` |
32+
| `RPC_URL` | Soroban RPC endpoint | `https://soroban-testnet.stellar.org:443` |
33+
34+
## Deploy Workflow
35+
36+
Run the three scripts in order:
37+
38+
### Step 1 — Fund the admin account
39+
40+
```bash
41+
./setup-testnet.sh
42+
```
43+
44+
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).
45+
46+
### Step 2 — Compile & deploy the contract
47+
48+
```bash
49+
./deploy.sh
50+
```
51+
52+
What it does:
53+
54+
1. Compiles `contrib` to WASM via `cargo build --target wasm32-unknown-unknown --release`
55+
2. Uploads the WASM and creates the contract instance via `stellar contract deploy`
56+
3. Logs the **contract ID** to stdout
57+
4. Persists the contract ID in `.env` as `CONTRACT_ID=...`
58+
59+
### Step 3 — Initialize the contract
60+
61+
```bash
62+
./initialize.sh
63+
```
64+
65+
What it does:
66+
67+
1. Derives the admin public address from `ADMIN_SECRET`
68+
2. Calls `initialize(admin)` on the deployed contract via `stellar contract invoke`
69+
3. The contract sets the admin, marks the contract as unpaused, sets total count to 0, and authorizes the admin as a registrar
70+
71+
### Verify
72+
73+
```bash
74+
# Check the stored admin
75+
stellar contract invoke \
76+
--id "$CONTRACT_ID" \
77+
--source-key "$ADMIN_SECRET" \
78+
--network-passphrase "$NETWORK_PASSPHRASE" \
79+
--rpc-url "$RPC_URL" \
80+
-- get_admin
81+
82+
# Should print the admin's public address (G...)
83+
```
84+
85+
## Redeploying
86+
87+
To deploy a new instance after code changes:
88+
89+
```bash
90+
./deploy.sh # builds, deploys, saves new CONTRACT_ID to .env
91+
./initialize.sh # initializes the new instance
92+
```
93+
94+
> **Note:** `deploy.sh` always creates a **new** contract instance. The old contract ID remains on-chain but is no longer referenced in your `.env`.
95+
96+
## Troubleshooting
97+
98+
| Problem | Fix |
99+
|---------|-----|
100+
| `error: no such target: wasm32-unknown-unknown` | `rustup target add wasm32-unknown-unknown` |
101+
| `stellar: command not found` | `cargo install stellar-cli` |
102+
| `RESOURCE_EXHAUSTED` on deploy | Contract WASM too large; enable `opt-level = "z"` in `Cargo.toml` (already set) |
103+
| `Already initialized` on invoke | Contract was already initialized. Deploy a new instance. |
104+
| `Insufficient balance` | Run `./setup-testnet.sh` again or wait for Friendbot rate limit to reset. |
Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
#!/usr/bin/env bash
2+
#
3+
# deploy.sh — Compile the contrib contract to WASM and deploy to Stellar Testnet
4+
#
5+
# Steps:
6+
# 1. Build the contract with `cargo build --target wasm32-unknown-unknown --release`
7+
# 2. Deploy the WASM to Testnet via `stellar contract deploy`
8+
# 3. Log the contract ID and persist it to .env
9+
#
10+
# Prerequisites:
11+
# - Rust toolchain with wasm32-unknown-unknown target
12+
# - stellar CLI (>= 22)
13+
# - .env file with ADMIN_SECRET, NETWORK_PASSPHRASE, RPC_URL
14+
#
15+
set -euo pipefail
16+
17+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
18+
CONTRACT_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
19+
WORKSPACE_ROOT="$(cd "$CONTRACT_ROOT/.." && pwd)"
20+
ENV_FILE="${SCRIPT_DIR}/.env"
21+
22+
# ── Colours ────────────────────────────────────────────────────────────────────
23+
GREEN='\033[0;32m'; YELLOW='\033[1;33m'; RED='\033[0;31m'; NC='\033[0m'
24+
info() { echo -e "${GREEN}[INFO]${NC} $*"; }
25+
warn() { echo -e "${YELLOW}[WARN]${NC} $*"; }
26+
error() { echo -e "${RED}[ERROR]${NC} $*" >&2; exit 1; }
27+
28+
# ── Load .env ──────────────────────────────────────────────────────────────────
29+
if [[ ! -f "$ENV_FILE" ]]; then
30+
error "$ENV_FILE not found. Copy .env.example → .env and fill in values."
31+
fi
32+
33+
set -a
34+
# shellcheck source=/dev/null
35+
source "$ENV_FILE"
36+
set +a
37+
38+
: "${ADMIN_SECRET:?ADMIN_SECRET must be set in $ENV_FILE}"
39+
: "${NETWORK_PASSPHRASE:?NETWORK_PASSPHRASE must be set in $ENV_FILE}"
40+
: "${RPC_URL:?RPC_URL must be set in $ENV_FILE}"
41+
42+
# ── Step 1: Build WASM ────────────────────────────────────────────────────────
43+
info "Building contrib contract to WASM…"
44+
45+
(
46+
cd "$WORKSPACE_ROOT"
47+
cargo build --package contrib --target wasm32-unknown-unknown --release
48+
)
49+
50+
WASM_PATH="${WORKSPACE_ROOT}/target/wasm32-unknown-unknown/release/contrib.wasm"
51+
52+
if [[ ! -f "$WASM_PATH" ]]; then
53+
error "WASM not found at $WASM_PATH — build may have failed."
54+
fi
55+
56+
WASM_SIZE="$(du -h "$WASM_PATH" | cut -f1)"
57+
info "WASM built: $WASM_PATH ($WASM_SIZE)"
58+
59+
# ── Step 2: Deploy to Testnet ─────────────────────────────────────────────────
60+
info "Deploying contract to Stellar Testnet…"
61+
62+
DEPLOY_OUTPUT="$(
63+
stellar contract deploy \
64+
--wasm "$WASM_PATH" \
65+
--source-key "$ADMIN_SECRET" \
66+
--network-passphrase "$NETWORK_PASSPHRASE" \
67+
--rpc-url "$RPC_URL" \
68+
--ignore-checks
69+
)"
70+
71+
# stellar contract deploy prints the contract ID (e.g. C... or CA... )
72+
CONTRACT_ID="$(echo "$DEPLOY_OUTPUT" | tr -d '[:space:]')"
73+
74+
if [[ -z "$CONTRACT_ID" ]]; then
75+
error "Deployment output was empty. Check stellar CLI output above."
76+
fi
77+
78+
info "Contract deployed!"
79+
info " Contract ID : $CONTRACT_ID"
80+
info " RPC URL : $RPC_URL"
81+
82+
# ── Step 3: Persist contract ID to .env ───────────────────────────────────────
83+
if grep -q "^CONTRACT_ID=" "$ENV_FILE"; then
84+
sed -i.bak "s/^CONTRACT_ID=.*/CONTRACT_ID=${CONTRACT_ID}/" "$ENV_FILE"
85+
rm -f "${ENV_FILE}.bak"
86+
else
87+
echo "" >> "$ENV_FILE"
88+
echo "CONTRACT_ID=${CONTRACT_ID}" >> "$ENV_FILE"
89+
fi
90+
91+
info "Contract ID saved to $ENV_FILE"
92+
93+
echo ""
94+
echo "──────────────────────────────────────────────"
95+
echo " Next step: initialize the contract"
96+
echo " ./scripts/initialize.sh"
97+
echo "──────────────────────────────────────────────"
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
#!/usr/bin/env bash
2+
#
3+
# initialize.sh — Call the initialize() function on the deployed contrib contract
4+
#
5+
# The contract's initialize(env, admin) sets the admin address and initial state.
6+
# This script derives the admin public address from ADMIN_SECRET and invokes
7+
# the function via `stellar contract invoke`.
8+
#
9+
set -euo pipefail
10+
11+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
12+
ENV_FILE="${SCRIPT_DIR}/.env"
13+
14+
# ── Colours ────────────────────────────────────────────────────────────────────
15+
GREEN='\033[0;32m'; YELLOW='\033[1;33m'; RED='\033[0;31m'; NC='\033[0m'
16+
info() { echo -e "${GREEN}[INFO]${NC} $*"; }
17+
warn() { echo -e "${YELLOW}[WARN]${NC} $*"; }
18+
error() { echo -e "${RED}[ERROR]${NC} $*" >&2; exit 1; }
19+
20+
# ── Load .env ──────────────────────────────────────────────────────────────────
21+
if [[ ! -f "$ENV_FILE" ]]; then
22+
error "$ENV_FILE not found. Copy .env.example → .env and fill in values."
23+
fi
24+
25+
set -a
26+
# shellcheck source=/dev/null
27+
source "$ENV_FILE"
28+
set +a
29+
30+
: "${ADMIN_SECRET:?ADMIN_SECRET must be set in $ENV_FILE}"
31+
: "${NETWORK_PASSPHRASE:?NETWORK_PASSPHRASE must be set in $ENV_FILE}"
32+
: "${RPC_URL:?RPC_URL must be set in $ENV_FILE}"
33+
: "${CONTRACT_ID:?CONTRACT_ID must be set in $ENV_FILE (run deploy.sh first)}"
34+
35+
# ── Derive admin address ──────────────────────────────────────────────────────
36+
info "Deriving admin address from ADMIN_SECRET…"
37+
38+
ADMIN_ADDRESS="$(stellar keys address --secret-key "$ADMIN_SECRET" 2>/dev/null || \
39+
echo "$ADMIN_SECRET" | stellar keys address 2>/dev/null || \
40+
printf '%s' "$ADMIN_SECRET" | stellar keys address)"
41+
42+
if [[ -z "$ADMIN_ADDRESS" ]]; then
43+
error "Could not derive admin address from ADMIN_SECRET."
44+
fi
45+
46+
info "Admin address: $ADMIN_ADDRESS"
47+
48+
# ── Invoke initialize ─────────────────────────────────────────────────────────
49+
info "Calling initialize(admin: $ADMIN_ADDRESS) on contract $CONTRACT_ID"
50+
51+
stellar contract invoke \
52+
--id "$CONTRACT_ID" \
53+
--source-key "$ADMIN_SECRET" \
54+
--network-passphrase "$NETWORK_PASSPHRASE" \
55+
--rpc-url "$RPC_URL" \
56+
-- \
57+
initialize \
58+
--admin "$ADMIN_ADDRESS"
59+
60+
info "Contract initialized successfully!"
61+
info ""
62+
info "You can verify by calling get_admin:"
63+
info " stellar contract invoke \\"
64+
info " --id $CONTRACT_ID \\"
65+
info " --source-key \"\$ADMIN_SECRET\" \\"
66+
info " --network-passphrase \"\$NETWORK_PASSPHRASE\" \\"
67+
info " --rpc-url \"\$RPC_URL\" \\"
68+
info " -- get_admin"
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
#!/usr/bin/env bash
2+
#
3+
# setup-testnet.sh — Fund the admin account on Stellar Testnet via Friendbot
4+
#
5+
# Usage:
6+
# ./setup-testnet.sh # reads ADMIN_SECRET from .env
7+
# ./setup-testnet.sh <pubkey> # fund an arbitrary address
8+
#
9+
set -euo pipefail
10+
11+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
12+
ENV_FILE="${SCRIPT_DIR}/.env"
13+
14+
# ── Load .env ──────────────────────────────────────────────────────────────────
15+
if [[ ! -f "$ENV_FILE" ]]; then
16+
echo "ERROR: $ENV_FILE not found. Copy .env.example and fill in values." >&2
17+
exit 1
18+
fi
19+
20+
set -a
21+
# shellcheck source=/dev/null
22+
source "$ENV_FILE"
23+
set +a
24+
25+
# ── Derive public key from secret ─────────────────────────────────────────────
26+
if [[ -n "${1:-}" ]]; then
27+
ADMIN_PUBLIC="$1"
28+
else
29+
if [[ -z "${ADMIN_SECRET:-}" ]]; then
30+
echo "ERROR: ADMIN_SECRET is not set in $ENV_FILE" >&2
31+
exit 1
32+
fi
33+
34+
ADMIN_PUBLIC="$(stellar keys address --secret-key "$ADMIN_SECRET" 2>/dev/null || \
35+
echo "$ADMIN_SECRET" | stellar keys address 2>/dev/null || \
36+
printf '%s' "$ADMIN_SECRET" | stellar keys address)"
37+
38+
if [[ -z "$ADMIN_PUBLIC" ]]; then
39+
echo "ERROR: Could not derive public key from ADMIN_SECRET" >&2
40+
exit 1
41+
fi
42+
fi
43+
44+
echo "Funding account: $ADMIN_PUBLIC"
45+
46+
# ── Call Friendbot ─────────────────────────────────────────────────────────────
47+
RESPONSE=$(curl -sS "https://friendbot.stellar.org/?addr=${ADMIN_PUBLIC}") || {
48+
echo "ERROR: Failed to reach Friendbot" >&2
49+
exit 1
50+
}
51+
52+
# Friendbot returns the transaction envelope on success or JSON error
53+
if echo "$RESPONSE" | grep -q '"hash"'; then
54+
echo "Account funded successfully!"
55+
echo " Address : $ADMIN_PUBLIC"
56+
echo " Tx hash : $(echo "$RESPONSE" | grep -o '"hash":"[^"]*"' | cut -d'"' -f4)"
57+
else
58+
# Already funded accounts return a friendly message
59+
if echo "$RESPONSE" | grep -qi "already"; then
60+
echo "Account already funded: $ADMIN_PUBLIC"
61+
else
62+
echo "WARNING: Unexpected Friendbot response:" >&2
63+
echo "$RESPONSE" >&2
64+
fi
65+
fi
66+
67+
echo ""
68+
echo "Verify on Testnet explorer:"
69+
echo " https://stellar.expert/explorer/testnet/account/$ADMIN_PUBLIC"

0 commit comments

Comments
 (0)