Skip to content

Use stellar scaffold cli upgrade command in setup script #587

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 44 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
44 commits
Select commit Hold shift + click to select a range
27ebf04
Before running with prettier
CoveMB Feb 21, 2025
7c7828e
After running with prettier
CoveMB Feb 21, 2025
ce5fcd3
Add consistent-type-imports rule
CoveMB Feb 21, 2025
3cd0b59
Add lint step in ci action
CoveMB Feb 21, 2025
31f0c78
resolve prettier conflict
CoveMB Feb 21, 2025
365421b
After running with prettier
CoveMB Feb 21, 2025
cedaeaa
resolve prettier conflict
CoveMB Feb 21, 2025
98bd8af
Add lint step in ci action
CoveMB Feb 21, 2025
a9098d0
resolve prettier conflict
CoveMB Feb 21, 2025
6e9df26
resolve prettier conflict
CoveMB Feb 21, 2025
574a739
Remove .vscode directory from Git tracking
CoveMB Feb 21, 2025
c0e9002
move linter action in it's own job
CoveMB Feb 21, 2025
86c65dc
add lint note in readme
CoveMB Feb 21, 2025
a1111d3
Update .github/workflows/test.yml
CoveMB Feb 21, 2025
abbd5a4
Merge remote-tracking branch 'upstream/master'
CoveMB Feb 21, 2025
beffa34
Merge branch 'master' into master
ericglau Feb 21, 2025
d6bec2a
lint script files
CoveMB Feb 21, 2025
315b775
Merge branch 'master' of github.com:CoveMB/contracts-wizard
CoveMB Feb 21, 2025
6ed6e4f
Merge remote-tracking branch 'upstream/master'
CoveMB Feb 24, 2025
ea90cd1
Merge remote-tracking branch 'upstream/master'
CoveMB Feb 28, 2025
abf687a
Merge remote-tracking branch 'upstream/master'
CoveMB Mar 4, 2025
426b62d
Merge remote-tracking branch 'upstream/master'
CoveMB Mar 20, 2025
ea25cc1
Merge remote-tracking branch 'upstream/master'
CoveMB Mar 20, 2025
0911f87
Merge remote-tracking branch 'upstream/master'
CoveMB Mar 25, 2025
4914083
Merge remote-tracking branch 'upstream/master'
CoveMB Mar 27, 2025
5ce527f
Merge remote-tracking branch 'upstream/master'
CoveMB Apr 4, 2025
03a32fc
Merge remote-tracking branch 'upstream/master'
CoveMB Apr 7, 2025
b3c0347
Merge remote-tracking branch 'upstream/master'
CoveMB Apr 12, 2025
0a52a65
Merge remote-tracking branch 'upstream/master'
CoveMB May 13, 2025
9e74342
Merge remote-tracking branch 'upstream/master'
CoveMB May 19, 2025
d727f51
Merge remote-tracking branch 'upstream/master'
CoveMB May 21, 2025
60fb18f
Merge remote-tracking branch 'upstream/master'
CoveMB May 26, 2025
cbb7631
Merge remote-tracking branch 'upstream/master'
CoveMB May 27, 2025
0f1267f
Merge remote-tracking branch 'upstream/master'
CoveMB Jun 5, 2025
acc5e6e
Merge remote-tracking branch 'upstream/master'
CoveMB Jun 16, 2025
e3b74c8
Merge remote-tracking branch 'upstream/master'
CoveMB Jun 17, 2025
16ba867
Merge remote-tracking branch 'upstream/master'
CoveMB Jun 26, 2025
10442ac
Merge remote-tracking branch 'upstream/master'
CoveMB Jun 27, 2025
bdabd75
Use stellar scaffold upgrade for scallar scaffold setup
CoveMB Jun 27, 2025
38e5956
Make async
CoveMB Jun 27, 2025
5e3d6da
Merge remote-tracking branch 'upstream/master' into use-stellar-scaff…
CoveMB Jul 2, 2025
108e990
Update packages/core/stellar/src/zip-scaffold.ts
CoveMB Jul 4, 2025
8f216ce
Merge branch 'master' into use-stellar-scaffold-cli-upgrade
CoveMB Jul 4, 2025
c18d5a7
Merge branch 'master' into use-stellar-scaffold-cli-upgrade
ericglau Jul 4, 2025
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
10 changes: 7 additions & 3 deletions packages/core/stellar/src/zip-rust.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ Continue your development journey with [Stellar CLI](https://github.com/stellar/
- See [Git installation guide](https://github.com/git-guides/install-git).
`;

export async function zipRust(c: Contract, opts: GenericOptions) {
export const createRustZipEnvironment = (c: Contract, opts: GenericOptions) => {
const zip = new JSZip();

const contractName = contractOptionsToContractName(opts?.kind || 'contract');
Expand All @@ -51,7 +51,11 @@ export async function zipRust(c: Contract, opts: GenericOptions) {
zip.file(`contracts/${contractName}/src/lib.rs`, createRustLibFile);
zip.file(`contracts/${contractName}/Cargo.toml`, printContractCargo(contractName));
zip.file('Cargo.toml', workspaceCargo);
zip.file('README.md', readme);

return zip;
}
};

const addRustProjectReadme = (zip: JSZip) => zip.file('README.md', readme);

export const zipRustProject = async (c: Contract, opts: GenericOptions) =>
addRustProjectReadme(createRustZipEnvironment(c, opts));
5 changes: 3 additions & 2 deletions packages/core/stellar/src/zip-scaffold.test.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
import type { TestFn, ExecutionContext } from 'ava';
import _test from 'ava';

import { zipScaffold } from './zip-scaffold';
import { zipScaffoldProject } from './zip-scaffold';

import { buildFungible } from './fungible';

Check warning on line 6 in packages/core/stellar/src/zip-scaffold.test.ts

View workflow job for this annotation

GitHub Actions / format-lint

'buildFungible' is defined but never used. Allowed unused vars must match /^_/u
import { buildNonFungible } from './non-fungible';

Check warning on line 7 in packages/core/stellar/src/zip-scaffold.test.ts

View workflow job for this annotation

GitHub Actions / format-lint

'buildNonFungible' is defined but never used. Allowed unused vars must match /^_/u
import { promises as fs } from 'fs';
import path from 'path';
import os from 'os';
import util from 'util';
import child from 'child_process';
import type { Contract } from './contract';
import { rimraf } from 'rimraf';

Check warning on line 14 in packages/core/stellar/src/zip-scaffold.test.ts

View workflow job for this annotation

GitHub Actions / format-lint

'rimraf' is defined but never used. Allowed unused vars must match /^_/u
import type { JSZipObject } from 'jszip';
import type JSZip from 'jszip';
import type { GenericOptions } from './build-generic';
Expand All @@ -32,6 +32,7 @@
const scaffoldContractName = contractOptionsToContractName(opts?.kind || 'contract');

t.deepEqual(sorted, [
'Cargo.toml',
'README-WIZARD.md',
'contracts/',
`contracts/${scaffoldContractName}/`,
Expand Down Expand Up @@ -106,10 +107,10 @@
await fs.rm(t.context.tempFolder, { recursive: true, force: true });
});

async function runTest(t: ExecutionContext<Context>, c: Contract, opts: GenericOptions) {

Check warning on line 110 in packages/core/stellar/src/zip-scaffold.test.ts

View workflow job for this annotation

GitHub Actions / format-lint

'runTest' is defined but never used. Allowed unused vars must match /^_/u
t.timeout(3_000_000);

const zip = await zipScaffold(c, opts);
const zip = await zipScaffoldProject(c, opts);

assertLayout(t, zip, opts);
await extractPackage(t, zip);
Expand Down
184 changes: 15 additions & 169 deletions packages/core/stellar/src/zip-scaffold.ts
Original file line number Diff line number Diff line change
@@ -1,138 +1,14 @@
import JSZip from 'jszip';
import type JSZip from 'jszip';
import type { GenericOptions } from './build-generic';
import type { Contract } from './contract';
import { printContract, removeCreateLevelAttributes } from './print';
import { compatibleSorobanVersion, contractsVersionTag } from './utils/version';
import {
addDependenciesWith,
allStellarDependencies,
contractOptionsToContractName,
createRustLibFile,
printContractCargo,
printRustNameTest,
} from './zip-shared';
import { createRustZipEnvironment } from './zip-rust';

function getAddressArgs(c: Contract): string[] {
return c.constructorArgs
.filter(constructorArg => constructorArg.type?.toLowerCase() === 'address')
.map(constructorArg => constructorArg.name);
}

const setupSh = (c: Contract, opts: GenericOptions, scaffoldContractName: string) => {
const environmentsFileUpdate = (setUpContract: Contract, setUpScaffoldContractName: string) => `
# Update environments.toml: remove original contracts and insert wizard's contract
setup_environment() {
local file="environments.toml"
local temp
temp="$(mktemp)"

local in_dev_contracts=0
local skip_entry=0
local contract_entry_inserted=0
insert_contract_entry() {
{
printf '%s\\n' "[development.contracts.${setUpScaffoldContractName}_contract]" \\
"client = true" "" \\
"# If your contract has a \\\`__constructor\\\`, specify your arguments to it here." \\
"# These are the same arguments you could pass after the \\\`--\\\` in a call to" \\
"# \\\`stellar contract deploy\\\`" \\
"# Only available in \\\`development\\\` and \\\`test\\\` environments" \\
${
setUpContract.constructorArgs.length
? // Mind the spacing
`"# TODO add appropriate values for for the constructors arguments" \\
"constructor_args = \\"\\"\\"" \\
"${setUpContract.constructorArgs.map(constructorArg => `--${constructorArg.name} \\"ADD_${constructorArg.name.toLocaleUpperCase()}_${constructorArg.type?.toLocaleUpperCase() || 'ARGUMENT'}_HERE\\"`).join(' ')}" \\
"\\"\\"\\"" \\
""`
: '""'
}
} >> "$temp"
}

while IFS= read -r line; do
if [[ $contract_entry_inserted -eq 0 && $line == '[staging.network]' ]]; then
insert_contract_entry
contract_entry_inserted=1
fi

if [[ $line =~ ^\\[development\\.contracts\\]$ ]]; then
printf '%s\\n' "$line" >> "$temp"
in_dev_contracts=1
skip_entry=0
continue
fi

if [[ $line =~ ^\\[[^]]+\\]$ ]]; then
if (( in_dev_contracts )) && [[ $line =~ ^\\[development\\.contracts\\..+\\]$ ]]; then
skip_entry=1
in_dev_contracts=0
continue
fi
in_dev_contracts=0
skip_entry=0
printf '%s\\n' "$line" >> "$temp"
continue
fi

if (( skip_entry )); then
continue
fi

if (( in_dev_contracts )); then
if [[ $line =~ ^[[:space:]]*# ]]; then
printf '%s\\n' "$line" >> "$temp"
fi
continue
fi

printf '%s\\n' "$line" >> "$temp"
done < "$file"

mv "$temp" "$file"
}
`;

const updateWorkspaceCargo = `update_cargo() {
cp Cargo.toml Cargo.toml.bak

cat <<EOF > deps.tmp
${addDependenciesWith(`{ git = "https://github.com/OpenZeppelin/stellar-contracts", tag = "${contractsVersionTag}" }`, allStellarDependencies)}${addDependenciesWith(`{ version = "${compatibleSorobanVersion}" }`, ['soroban'])}
EOF

awk '
BEGIN {
inserted = 0
deps = ""
while ((getline line < "deps.tmp") > 0) {
deps = deps line "\\n"
}
close("deps.tmp")
}
/^\\[workspace.dependencies\\]/ {
in_deps = 1
print
if (!inserted) {
printf "%s", deps
inserted = 1
}
next
}
/^\\[/ { in_deps = 0 }
in_deps { next }
{ print }
' Cargo.toml.bak > Cargo.toml

rm deps.tmp
rm Cargo.toml.bak
}`;

return `\
const setupSh = `\
#!/usr/bin/env bash
#
# setup.sh
#
# This script is meant to set up a Scaffold project and insert the Wizard's contracts in the project
#
# This script is meant to set up a Scaffold project with the Wizard's contracts

check_is_installed() {
if ! which "$1" &> /dev/null; then
Expand All @@ -143,18 +19,7 @@ check_is_installed() {
}

scaffold() {
tmp_folder="tmp"
stellar scaffold init "$tmp_folder"

rm -rf "$tmp_folder/contracts"

local current_directory
current_directory="$(cd "$(dirname "\${BASH_SOURCE[0]}")" && pwd)"

shopt -s dotglob

cp -a "$current_directory/$tmp_folder"/. "$current_directory"/
rm -rf "$current_directory/$tmp_folder"
stellar-scaffold upgrade
}

init_git(){
Expand All @@ -163,10 +28,6 @@ init_git(){
git commit -m "openzeppelin: add wizard output" --quiet
}

${environmentsFileUpdate(c, scaffoldContractName)}

${updateWorkspaceCargo}

build_contracts() {
cargo build
}
Expand Down Expand Up @@ -196,10 +57,6 @@ then
echo "🏗️ Building Scaffold project"

scaffold

setup_environment

update_cargo

build_contracts

Expand All @@ -212,15 +69,11 @@ else
echo "✅ Scaffold project already initialized."
fi
`;
};

const readme = (c: Contract) => {
const hasTodosToResolve = (c: Contract) => getAddressArgs(c).length > 0;

return `\
const wizardReadme = `\
# Sample Scaffold Project

This project demonstrates a basic Scaffold use case. It comes with a contract generated by [OpenZeppelin Wizard](https://wizard.openzeppelin.com/), a test for that contract, and a script that initiate a Stellar Scaffold project with this contract. [Scaffold Stellar](https://github.com/AhaLabs/scaffold-stellar?tab=readme-ov-file#scaffold-stellar) is a convention-over-configuration toolkit for blockchain and distributed application development on the Stellar network. It provides a seamless development experience through CLI tools, smart contract management, and deployment utilities.
This project demonstrates a basic Scaffold use case. It comes with a contract generated by [OpenZeppelin Wizard](https://wizard.openzeppelin.com/), a test for that contract, and a script that initiates a Stellar Scaffold project with this contract. [Scaffold Stellar](https://github.com/AhaLabs/scaffold-stellar?tab=readme-ov-file#scaffold-stellar) is a convention-over-configuration toolkit for blockchain and distributed application development on the Stellar network. It provides a seamless development experience through CLI tools, smart contract management, and deployment utilities.

## Installing dependencies

Expand All @@ -235,7 +88,6 @@ This project demonstrates a basic Scaffold use case. It comes with a contract ge
\`\`\`
bash setup.sh
\`\`\`
${hasTodosToResolve(c) ? '\n## Resolve any TODOs \n\nSearch for any TODO comments in the project and resolve them (search for TODO with your code editor).\n' : ''}

## Testing the contract

Expand All @@ -255,19 +107,13 @@ stellar scaffold watch --build-clients
npm run dev
\`\`\`
`;
};

export async function zipScaffold(c: Contract, opts: GenericOptions) {
const zip = new JSZip();

const scaffoldContractName = contractOptionsToContractName(opts?.kind || 'contract');

zip.file(`contracts/${scaffoldContractName}/src/contract.rs`, removeCreateLevelAttributes(printContract(c)));
zip.file(`contracts/${scaffoldContractName}/src/test.rs`, printRustNameTest(c));
zip.file(`contracts/${scaffoldContractName}/src/lib.rs`, createRustLibFile);
zip.file(`contracts/${scaffoldContractName}/Cargo.toml`, printContractCargo(scaffoldContractName));
zip.file('setup.sh', setupSh(c, opts, scaffoldContractName));
zip.file('README-WIZARD.md', readme(c));
const addScaffoldProjectFiles = (zip: JSZip) => {
zip.file('README-WIZARD.md', wizardReadme);
zip.file('setup.sh', setupSh);

return zip;
}
};

export const zipScaffoldProject = async (c: Contract, opts: GenericOptions) =>
addScaffoldProjectFiles(createRustZipEnvironment(c, opts));
15 changes: 15 additions & 0 deletions packages/core/stellar/src/zip-shared.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import type { Contract } from './contract';
import { contractsVersionTag, compatibleSorobanVersion } from './utils/version';

function pascalToSnakeCase(string: string) {
return string
Expand Down Expand Up @@ -83,3 +84,17 @@ export const createRustLibFile = `#![no_std]
mod contract;
mod test;
`;

export const workspaceCargo = `[workspace]
resolver = "2"
members = ["contracts/*"]

[workspace.package]
authors = []
edition = "2021"
license = "Apache-2.0"
version = "0.0.1"

[workspace.dependencies]
${addDependenciesWith(`{ git = "https://github.com/OpenZeppelin/stellar-contracts", tag = "${contractsVersionTag}" }`, allStellarDependencies)}${addDependenciesWith(`{ version = "${compatibleSorobanVersion}" }`, ['soroban'])}
`;
8 changes: 4 additions & 4 deletions packages/ui/src/stellar/App.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -82,17 +82,17 @@
const zipScaffoldModule = import('@openzeppelin/wizard-stellar/zip-env-scaffold');

const downloadScaffoldHandler = async () => {
const { zipScaffold } = await zipScaffoldModule;
const { zipScaffoldProject } = await zipScaffoldModule;

await downloadZip(zipScaffold, 'download-scaffold', 'stellar', contract, opts);
await downloadZip(zipScaffoldProject, 'download-scaffold', 'stellar', contract, opts);
};

const zipRustModule = import('@openzeppelin/wizard-stellar/zip-env-rust');

const downloadRustHandler = async () => {
const { zipRust } = await zipRustModule;
const { zipRustProject } = await zipRustModule;

await downloadZip(zipRust, 'download-rust-stellar', 'stellar', contract, opts);
await downloadZip(zipRustProject, 'download-rust-stellar', 'stellar', contract, opts);
};

export let initialTab: string | undefined = 'Fungible';
Expand Down
Loading