Skip to content
Open
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
1 change: 1 addition & 0 deletions .lintstagedrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,5 @@ module.exports = {
"*.{js,ts}":
"na biome lint --no-errors-on-unmatched --unsafe --write --only correctness/noUnusedImports",
"*.{md,yml}": "na prettier --cache --write",
"*.sh": "shfmt -i 2 -w -s",
};
10 changes: 10 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ Ensure you have the following software installed and configured on your machine:
- [Just](https://github.com/casey/just) (command runner)
- [Bun](https://bun.sh/docs/installation) (package manager)
- [Ni](https://github.com/antfu-collective/ni) (package manager resolver)
- [shfmt](https://github.com/mvdan/sh#shfmt) (shell script formatter) - install via `brew install shfmt` (macOS),
`apt install shfmt` (Ubuntu), or download from [releases](https://github.com/mvdan/sh/releases)

## Set Up

Expand Down Expand Up @@ -62,6 +64,14 @@ just build
just full-check
```

This will check:

- TypeScript/JavaScript formatting and linting (Biome)
- Markdown and YAML formatting (Prettier)
- Bash script formatting (shfmt)
- TypeScript type checking
- Rust code formatting and linting

### Testing

```bash
Expand Down
14 changes: 14 additions & 0 deletions justfile
Original file line number Diff line number Diff line change
Expand Up @@ -76,18 +76,32 @@ setup:
# CODE CHECKS #
# ---------------------------------------------------------------------------- #

# Check bash script formatting
[group("code-checks")]
bash-check:
shfmt -i 2 -d scripts/bash/*.sh
alias bashc := bash-check

# Format bash scripts
[group("code-fixes")]
bash-write:
shfmt -i 2 -w -s scripts/bash/*.sh
alias bashw := bash-write

# Run all code checks
full-check:
just _run-with-status codegen
just _run-with-status prettier-check
just _run-with-status biome-check
just _run-with-status bash-check
just _run-with-status tsc-check
just _run-with-status rust-check

# Run all code fixes
full-write:
just _run-with-status prettier-write
just _run-with-status biome-write
just _run-with-status bash-write
just _run-with-status rust-write

# Run Rust checks
Expand Down
198 changes: 99 additions & 99 deletions scripts/bash/deploy-programs.sh
Original file line number Diff line number Diff line change
Expand Up @@ -47,22 +47,22 @@ set -euo pipefail

# Error handling with usage display
show_usage_and_exit() {
local error_msg="$1"
echo "❌ Error: $error_msg"
echo ""
echo "Usage: $0 --program PROGRAM [PROGRAM...] [--mainnet] [--keep-keypairs]"
echo "Valid programs: ${VALID_PROGRAMS[*]}"
echo "Short forms: lk=sablier_lockup, mi=sablier_merkle_instant"
echo ""
echo "Flags:"
echo " --keep-keypairs # Keep existing keypairs if present (default: overwrite)"
echo ""
echo "Examples:"
echo " $0 --program sablier_lockup # Deploys the Lockup program to devnet with demo data setup, overwriting keypair"
echo " $0 --program lk --keep-keypairs # Same as above, but keeps existing keypair if present"
echo " $0 --program mi --mainnet # Deploys the Merkle Instant program to mainnet (init-only, no demo data)"
echo " $0 --program lk mi # Deploys both programs to devnet with demo data setup"
exit 1
local error_msg="$1"
echo "❌ Error: $error_msg"
echo ""
echo "Usage: $0 --program PROGRAM [PROGRAM...] [--mainnet] [--keep-keypairs]"
echo "Valid programs: ${VALID_PROGRAMS[*]}"
echo "Short forms: lk=sablier_lockup, mi=sablier_merkle_instant"
echo ""
echo "Flags:"
echo " --keep-keypairs # Keep existing keypairs if present (default: overwrite)"
echo ""
echo "Examples:"
echo " $0 --program sablier_lockup # Deploys the Lockup program to devnet with demo data setup, overwriting keypair"
echo " $0 --program lk --keep-keypairs # Same as above, but keeps existing keypair if present"
echo " $0 --program mi --mainnet # Deploys the Merkle Instant program to mainnet (init-only, no demo data)"
echo " $0 --program lk mi # Deploys both programs to devnet with demo data setup"
exit 1
}

# Logging functions
Expand Down Expand Up @@ -97,48 +97,48 @@ PROGRAM_CONFIG["sablier_merkle_instant"]="programs/merkle_instant/src/lib.rs"

# Map short forms to full program names
map_program_name() {
case "$1" in
"lk") echo "sablier_lockup" ;;
"mi") echo "sablier_merkle_instant" ;;
"sablier_lockup"|"sablier_merkle_instant") echo "$1" ;;
*) echo "$1" ;; # Return as-is for validation to catch invalid names
esac
case "$1" in
"lk") echo "sablier_lockup" ;;
"mi") echo "sablier_merkle_instant" ;;
"sablier_lockup" | "sablier_merkle_instant") echo "$1" ;;
*) echo "$1" ;; # Return as-is for validation to catch invalid names
esac
}

# Parse the command line arguments
while [[ $# -gt 0 ]]; do
case $1 in
--mainnet)
MAINNET_FLAG=true
shift
;;
--keep-keypairs)
KEEP_KEYPAIRS=true
shift
;;
--program)
shift
# Collect all program names until we hit another flag or end of args
while [[ $# -gt 0 && ! "$1" =~ ^-- ]]; do
mapped_program=$(map_program_name "$1")
PROGRAMS+=("$mapped_program")
shift
done
;;
*)
show_usage_and_exit "Unknown option: $1"
;;
esac
case $1 in
--mainnet)
MAINNET_FLAG=true
shift
;;
--keep-keypairs)
KEEP_KEYPAIRS=true
shift
;;
--program)
shift
# Collect all program names until we hit another flag or end of args
while [[ $# -gt 0 && ! $1 =~ ^-- ]]; do
mapped_program=$(map_program_name "$1")
PROGRAMS+=("$mapped_program")
shift
done
;;
*)
show_usage_and_exit "Unknown option: $1"
;;
esac
done

# Reset the affected variables if the mainnet flag has been passed
if [[ "$MAINNET_FLAG" == true ]]; then
CLUSTER="mainnet"
ANCHOR_PROVIDER_URL="https://api.mainnet-beta.solana.com"
if [[ $MAINNET_FLAG == true ]]; then
CLUSTER="mainnet"
ANCHOR_PROVIDER_URL="https://api.mainnet-beta.solana.com"

# Note: we don't want to create demo streams/campaigns on mainnet
INIT_SCRIPTS["sablier_lockup"]="scripts/ts/init-lockup.ts"
INIT_SCRIPTS["sablier_merkle_instant"]="scripts/ts/init-merkle-instant.ts"
# Note: we don't want to create demo streams/campaigns on mainnet
INIT_SCRIPTS["sablier_lockup"]="scripts/ts/init-lockup.ts"
INIT_SCRIPTS["sablier_merkle_instant"]="scripts/ts/init-merkle-instant.ts"
fi

# Configure Solana CLI to use the correct provider
Expand All @@ -150,17 +150,17 @@ solana config set --url $ANCHOR_PROVIDER_URL

# Assert that at least one program has been specified
if [[ ${#PROGRAMS[@]} -eq 0 ]]; then
show_usage_and_exit "No programs specified"
show_usage_and_exit "No programs specified"
fi

log_action "Programs to deploy: ${PROGRAMS[*]}"

# Assert that the specified programs are valid
for program in "${PROGRAMS[@]}"; do
if [[ ! " ${VALID_PROGRAMS[*]} " =~ " ${program} " ]]; then
show_usage_and_exit "Program '$program' is not supported. Supported programs: ${VALID_PROGRAMS[*]}"
fi
log_success "Program '$program' is valid"
if [[ ! " ${VALID_PROGRAMS[*]} " =~ " ${program} " ]]; then
show_usage_and_exit "Program '$program' is not supported. Supported programs: ${VALID_PROGRAMS[*]}"
fi
log_success "Program '$program' is valid"
done

# ---------------------------------------------------------------------------- #
Expand All @@ -169,19 +169,19 @@ done

# Generate new program keypairs (unless --keep-keypairs is set)
for program in "${PROGRAMS[@]}"; do
keypair_path="target/deploy/${program}-keypair.json"
if [[ "$KEEP_KEYPAIRS" == true ]]; then
if [[ -f "$keypair_path" ]]; then
log_info "Using existing keypair for $program at $keypair_path"
else
log_error "--keep-keypairs was specified, but $keypair_path does not exist for $program. Aborting."
exit 1
fi
keypair_path="target/deploy/${program}-keypair.json"
if [[ $KEEP_KEYPAIRS == true ]]; then
if [[ -f $keypair_path ]]; then
log_info "Using existing keypair for $program at $keypair_path"
else
# The `anchor build` command will automatically generate new keypairs if those files don’t already exist.
log_info "Cleaning build artifacts..."
just clean
log_error "--keep-keypairs was specified, but $keypair_path does not exist for $program. Aborting."
exit 1
fi
else
# The `anchor build` command will automatically generate new keypairs if those files don’t already exist.
log_info "Cleaning build artifacts..."
just clean
fi
done

# Start Colima (if it's already running, the command is being ignored automatically)
Expand All @@ -192,14 +192,14 @@ anchor keys sync

# Build the programs
for program in "${PROGRAMS[@]}"; do
echo "🔨 Building $program..."
anchor build -v -p "$program"
echo "🔨 Building $program..."
anchor build -v -p "$program"
done

# Deploy the programs
for program in "${PROGRAMS[@]}"; do
echo "🚀 Deploying $program"
anchor deploy -v -p "$program" --provider.cluster $CLUSTER
echo "🚀 Deploying $program"
anchor deploy -v -p "$program" --provider.cluster $CLUSTER
done

# Closes the associated buffer accounts, if any (in order to recover the rent SOL from them)
Expand All @@ -213,13 +213,13 @@ echo "🎉 Deployment completed for programs: ${PROGRAMS[*]}"
# ---------------------------------------------------------------------------- #

for program in "${PROGRAMS[@]}"; do
if [[ -n "${INIT_SCRIPTS[$program]}" ]]; then
ANCHOR_WALLET=~/.config/solana/id.json \
na vitest --run --mode scripts "${INIT_SCRIPTS[$program]}"
else
log_warning "No init script found for $program"
fi
log_success "All initializations completed"
if [[ -n ${INIT_SCRIPTS[$program]} ]]; then
ANCHOR_WALLET=~/.config/solana/id.json \
na vitest --run --mode scripts "${INIT_SCRIPTS[$program]}"
else
log_warning "No init script found for $program"
fi
log_success "All initializations completed"
done

# ---------------------------------------------------------------------------- #
Expand All @@ -240,11 +240,11 @@ git switch -c "$DEPLOYMENT_BRANCH"
# Prepare git files to add
git_files_to_add=("Anchor.toml")
for program in "${PROGRAMS[@]}"; do
if [[ -n "${PROGRAM_CONFIG[$program]:-}" ]]; then
git_files_to_add+=("${PROGRAM_CONFIG[$program]}")
else
log_warning "No lib.rs path configured for $program"
fi
if [[ -n ${PROGRAM_CONFIG[$program]:-} ]]; then
git_files_to_add+=("${PROGRAM_CONFIG[$program]}")
else
log_warning "No lib.rs path configured for $program"
fi
done

# Commit changes
Expand All @@ -253,22 +253,22 @@ git commit -m "chore($CLUSTER): deployment for ${PROGRAMS[*]}"

# Create zip files for each program
for program in "${PROGRAMS[@]}"; do
log_info "Creating zip file for $program..."

# Define paths
idl_source="target/idl/${program}.json"
types_source="target/types/${program}.ts"
zip_file="${program}_IDL_types.zip"

# Validate source files exist
for file in "$idl_source" "$types_source"; do
if [[ ! -f "$file" ]]; then
log_error "$file not found"
exit 1
fi
done
log_info "Creating zip file for $program..."

# Define paths
idl_source="target/idl/${program}.json"
types_source="target/types/${program}.ts"
zip_file="${program}_IDL_types.zip"

# Validate source files exist
for file in "$idl_source" "$types_source"; do
if [[ ! -f $file ]]; then
log_error "$file not found"
exit 1
fi
done

# Create zip file (removes existing file automatically with -o flag)
zip -o "$zip_file" "$idl_source" "$types_source"
log_success "Created $zip_file"
# Create zip file (removes existing file automatically with -o flag)
zip -o "$zip_file" "$idl_source" "$types_source"
log_success "Created $zip_file"
done
2 changes: 1 addition & 1 deletion scripts/bash/prepare-artifacts.sh
Original file line number Diff line number Diff line change
Expand Up @@ -20,4 +20,4 @@ mkdir $artifacts $idl $types

# Move all idl and types files to the new artifacts directories
cp target/idl/* $idl/
cp target/types/* $types/
cp target/types/* $types/