diff --git a/.changeset/big-buttons-cover.md b/.changeset/big-buttons-cover.md new file mode 100644 index 000000000..53d336b2b --- /dev/null +++ b/.changeset/big-buttons-cover.md @@ -0,0 +1,5 @@ +--- +'@openzeppelin/wizard-stellar': minor +--- + +Use constructor args for Sellar smart contracts diff --git a/packages/core/stellar/README.md b/packages/core/stellar/README.md index c73099e7c..29930aeae 100644 --- a/packages/core/stellar/README.md +++ b/packages/core/stellar/README.md @@ -13,6 +13,7 @@ This package provides a programmatic API. For a web interface, see https://wizar The following contract types are supported: - `fungible` - `nonFungible` +- `stablecoin` Each contract type has functions/constants as defined below. diff --git a/packages/core/stellar/src/contract.ts b/packages/core/stellar/src/contract.ts index 5dafa0d1b..047e5d8bc 100644 --- a/packages/core/stellar/src/contract.ts +++ b/packages/core/stellar/src/contract.ts @@ -7,7 +7,7 @@ export interface Contract { name: string; useClauses: UseClause[]; constructorCode: string[]; - constructorArgs: Argument[]; + constructorArgs: ConstructorArgument[]; implementedTraits: TraitImplBlock[]; freeFunctions: ContractFunction[]; variables: Variable[]; @@ -71,6 +71,10 @@ export interface Argument { type?: string; } +export interface ConstructorArgument extends Argument { + value?: string; +} + export class ContractBuilder implements Contract { readonly name: string; license = 'MIT'; @@ -79,7 +83,7 @@ export class ContractBuilder implements Contract { readonly documentations: string[] = []; - readonly constructorArgs: Argument[] = []; + readonly constructorArgs: ConstructorArgument[] = []; readonly constructorCode: string[] = []; private implementedTraitsMap: Map = new Map(); @@ -241,7 +245,7 @@ export class ContractBuilder implements Contract { existingFn.tags = [...(existingFn.tags ?? []), tag]; } - addConstructorArgument(arg: Argument): void { + addConstructorArgument(arg: ConstructorArgument): void { for (const existingArg of this.constructorArgs) { if (existingArg.name == arg.name) { return; diff --git a/packages/core/stellar/src/fungible.test.ts.md b/packages/core/stellar/src/fungible.test.ts.md index 466c2739c..02ee04efc 100644 --- a/packages/core/stellar/src/fungible.test.ts.md +++ b/packages/core/stellar/src/fungible.test.ts.md @@ -21,8 +21,15 @@ Generated by [AVA](https://avajs.dev). ␊ #[contractimpl]␊ impl MyToken {␊ - pub fn __constructor(e: &Env) {␊ - Base::set_metadata(e, 18, String::from_str(e, "MyToken"), String::from_str(e, "MTK"));␊ + // deploy this smart contract with the Stellar CLI:␊ + //␊ + // stellar contract deploy \\␊ + // --wasm path/to/file.wasm \\␊ + // -- \\␊ + // --name MyToken \\␊ + // --symbol MTK␊ + pub fn __constructor(e: &Env, name: String, symbol: String) {␊ + Base::set_metadata(e, 18, name, symbol);␊ }␊ }␊ ␊ @@ -51,8 +58,15 @@ Generated by [AVA](https://avajs.dev). ␊ #[contractimpl]␊ impl MyToken {␊ - pub fn __constructor(e: &Env) {␊ - Base::set_metadata(e, 18, String::from_str(e, "MyToken"), String::from_str(e, "MTK"));␊ + // deploy this smart contract with the Stellar CLI:␊ + //␊ + // stellar contract deploy \\␊ + // --wasm path/to/file.wasm \\␊ + // -- \\␊ + // --name MyToken \\␊ + // --symbol MTK␊ + pub fn __constructor(e: &Env, name: String, symbol: String) {␊ + Base::set_metadata(e, 18, name, symbol);␊ }␊ }␊ ␊ @@ -91,8 +105,16 @@ Generated by [AVA](https://avajs.dev). ␊ #[contractimpl]␊ impl MyToken {␊ - pub fn __constructor(e: &Env, owner: Address) {␊ - Base::set_metadata(e, 18, String::from_str(e, "MyToken"), String::from_str(e, "MTK"));␊ + // deploy this smart contract with the Stellar CLI:␊ + //␊ + // stellar contract deploy \\␊ + // --wasm path/to/file.wasm \\␊ + // -- \\␊ + // --name MyToken \\␊ + // --symbol MTK \\␊ + // --owner ␊ + pub fn __constructor(e: &Env, name: String, symbol: String, owner: Address) {␊ + Base::set_metadata(e, 18, name, symbol);␊ ownable::set_owner(e, &owner);␊ }␊ }␊ @@ -158,8 +180,16 @@ Generated by [AVA](https://avajs.dev). ␊ #[contractimpl]␊ impl MyToken {␊ - pub fn __constructor(e: &Env, owner: Address) {␊ - Base::set_metadata(e, 18, String::from_str(e, "MyToken"), String::from_str(e, "MTK"));␊ + // deploy this smart contract with the Stellar CLI:␊ + //␊ + // stellar contract deploy \\␊ + // --wasm path/to/file.wasm \\␊ + // -- \\␊ + // --name MyToken \\␊ + // --symbol MTK \\␊ + // --owner ␊ + pub fn __constructor(e: &Env, name: String, symbol: String, owner: Address) {␊ + Base::set_metadata(e, 18, name, symbol);␊ ownable::set_owner(e, &owner);␊ }␊ }␊ @@ -240,9 +270,18 @@ Generated by [AVA](https://avajs.dev). ␊ #[contractimpl]␊ impl MyToken {␊ - pub fn __constructor(e: &Env, recipient: Address) {␊ - Base::set_metadata(e, 18, String::from_str(e, "MyToken"), String::from_str(e, "MTK"));␊ - Base::mint(e, &recipient, 1000000000000000000000);␊ + // deploy this smart contract with the Stellar CLI:␊ + //␊ + // stellar contract deploy \\␊ + // --wasm path/to/file.wasm \\␊ + // -- \\␊ + // --name MyToken \\␊ + // --symbol MTK \\␊ + // --recipient \\␊ + // --premint 1000000000000000000000␊ + pub fn __constructor(e: &Env, name: String, symbol: String, recipient: Address, premint: i128) {␊ + Base::set_metadata(e, 18, name, symbol);␊ + Base::mint(e, &recipient, premint);␊ }␊ }␊ ␊ @@ -271,8 +310,15 @@ Generated by [AVA](https://avajs.dev). ␊ #[contractimpl]␊ impl MyToken {␊ - pub fn __constructor(e: &Env) {␊ - Base::set_metadata(e, 18, String::from_str(e, "MyToken"), String::from_str(e, "MTK"));␊ + // deploy this smart contract with the Stellar CLI:␊ + //␊ + // stellar contract deploy \\␊ + // --wasm path/to/file.wasm \\␊ + // -- \\␊ + // --name MyToken \\␊ + // --symbol MTK␊ + pub fn __constructor(e: &Env, name: String, symbol: String) {␊ + Base::set_metadata(e, 18, name, symbol);␊ }␊ }␊ ␊ @@ -301,8 +347,15 @@ Generated by [AVA](https://avajs.dev). ␊ #[contractimpl]␊ impl MyToken {␊ - pub fn __constructor(e: &Env) {␊ - Base::set_metadata(e, 18, String::from_str(e, "MyToken"), String::from_str(e, "MTK"));␊ + // deploy this smart contract with the Stellar CLI:␊ + //␊ + // stellar contract deploy \\␊ + // --wasm path/to/file.wasm \\␊ + // -- \\␊ + // --name MyToken \\␊ + // --symbol MTK␊ + pub fn __constructor(e: &Env, name: String, symbol: String) {␊ + Base::set_metadata(e, 18, name, symbol);␊ }␊ }␊ ␊ @@ -332,8 +385,16 @@ Generated by [AVA](https://avajs.dev). ␊ #[contractimpl]␊ impl MyToken {␊ - pub fn __constructor(e: &Env, owner: Address) {␊ - Base::set_metadata(e, 18, String::from_str(e, "MyToken"), String::from_str(e, "MTK"));␊ + // deploy this smart contract with the Stellar CLI:␊ + //␊ + // stellar contract deploy \\␊ + // --wasm path/to/file.wasm \\␊ + // -- \\␊ + // --name MyToken \\␊ + // --symbol MTK \\␊ + // --owner ␊ + pub fn __constructor(e: &Env, name: String, symbol: String, owner: Address) {␊ + Base::set_metadata(e, 18, name, symbol);␊ ownable::set_owner(e, &owner);␊ }␊ }␊ @@ -372,8 +433,16 @@ Generated by [AVA](https://avajs.dev). ␊ #[contractimpl]␊ impl MyToken {␊ - pub fn __constructor(e: &Env, admin: Address) {␊ - Base::set_metadata(e, 18, String::from_str(e, "MyToken"), String::from_str(e, "MTK"));␊ + // deploy this smart contract with the Stellar CLI:␊ + //␊ + // stellar contract deploy \\␊ + // --wasm path/to/file.wasm \\␊ + // -- \\␊ + // --name MyToken \\␊ + // --symbol MTK \\␊ + // --admin ␊ + pub fn __constructor(e: &Env, name: String, symbol: String, admin: Address) {␊ + Base::set_metadata(e, 18, name, symbol);␊ access_control::set_admin(e, &admin);␊ }␊ }␊ @@ -413,9 +482,26 @@ Generated by [AVA](https://avajs.dev). ␊ #[contractimpl]␊ impl MyToken {␊ - pub fn __constructor(e: &Env, recipient: Address, owner: Address) {␊ - Base::set_metadata(e, 18, String::from_str(e, "MyToken"), String::from_str(e, "MTK"));␊ - Base::mint(e, &recipient, 2000000000000000000000);␊ + // deploy this smart contract with the Stellar CLI:␊ + //␊ + // stellar contract deploy \\␊ + // --wasm path/to/file.wasm \\␊ + // -- \\␊ + // --name MyToken \\␊ + // --symbol MTK \\␊ + // --recipient \\␊ + // --premint 2000000000000000000000 \\␊ + // --owner ␊ + pub fn __constructor(␊ + e: &Env,␊ + name: String,␊ + symbol: String,␊ + recipient: Address,␊ + premint: i128,␊ + owner: Address,␊ + ) {␊ + Base::set_metadata(e, 18, name, symbol);␊ + Base::mint(e, &recipient, premint);␊ ownable::set_owner(e, &owner);␊ }␊ ␊ @@ -506,16 +592,32 @@ Generated by [AVA](https://avajs.dev). ␊ #[contractimpl]␊ impl MyToken {␊ + // deploy this smart contract with the Stellar CLI:␊ + //␊ + // stellar contract deploy \\␊ + // --wasm path/to/file.wasm \\␊ + // -- \\␊ + // --name MyToken \\␊ + // --symbol MTK \\␊ + // --recipient \\␊ + // --premint 2000000000000000000000 \\␊ + // --admin \\␊ + // --pauser \\␊ + // --upgrader \\␊ + // --minter ␊ pub fn __constructor(␊ e: &Env,␊ + name: String,␊ + symbol: String,␊ recipient: Address,␊ + premint: i128,␊ admin: Address,␊ pauser: Address,␊ upgrader: Address,␊ minter: Address,␊ ) {␊ - Base::set_metadata(e, 18, String::from_str(e, "MyToken"), String::from_str(e, "MTK"));␊ - Base::mint(e, &recipient, 2000000000000000000000);␊ + Base::set_metadata(e, 18, name, symbol);␊ + Base::mint(e, &recipient, premint);␊ access_control::set_admin(e, &admin);␊ access_control::grant_role_no_auth(e, &admin, &pauser, &Symbol::new(e, "pauser"));␊ access_control::grant_role_no_auth(e, &admin, &upgrader, &Symbol::new(e, "upgrader"));␊ @@ -616,9 +718,26 @@ Generated by [AVA](https://avajs.dev). ␊ #[contractimpl]␊ impl CustomToken {␊ - pub fn __constructor(e: &Env, recipient: Address, owner: Address) {␊ - Base::set_metadata(e, 18, String::from_str(e, "Custom $ Token"), String::from_str(e, "MTK"));␊ - Base::mint(e, &recipient, 2000000000000000000000);␊ + // deploy this smart contract with the Stellar CLI:␊ + //␊ + // stellar contract deploy \\␊ + // --wasm path/to/file.wasm \\␊ + // -- \\␊ + // --name "Custom $ Token" \\␊ + // --symbol MTK \\␊ + // --recipient \\␊ + // --premint 2000000000000000000000 \\␊ + // --owner ␊ + pub fn __constructor(␊ + e: &Env,␊ + name: String,␊ + symbol: String,␊ + recipient: Address,␊ + premint: i128,␊ + owner: Address,␊ + ) {␊ + Base::set_metadata(e, 18, name, symbol);␊ + Base::mint(e, &recipient, premint);␊ ownable::set_owner(e, &owner);␊ }␊ ␊ diff --git a/packages/core/stellar/src/fungible.test.ts.snap b/packages/core/stellar/src/fungible.test.ts.snap index 8cc950058..86a390549 100644 Binary files a/packages/core/stellar/src/fungible.test.ts.snap and b/packages/core/stellar/src/fungible.test.ts.snap differ diff --git a/packages/core/stellar/src/fungible.ts b/packages/core/stellar/src/fungible.ts index 083fe5105..0834c5441 100644 --- a/packages/core/stellar/src/fungible.ts +++ b/packages/core/stellar/src/fungible.ts @@ -89,7 +89,9 @@ export function buildFungible(opts: FungibleOptions): ContractBuilder { function addBase(c: ContractBuilder, name: string, symbol: string, pausable: boolean) { // Set metadata - c.addConstructorCode(`Base::set_metadata(e, 18, String::from_str(e, "${name}"), String::from_str(e, "${symbol}"));`); + c.addConstructorArgument({ name: 'name', type: 'String', value: name }); + c.addConstructorArgument({ name: 'symbol', type: 'String', value: symbol }); + c.addConstructorCode('Base::set_metadata(e, 18, name, symbol);'); // Set token functions c.addUseClause('stellar_tokens::fungible', 'Base'); @@ -198,8 +200,9 @@ function addPremint(c: ContractBuilder, amount: string) { c.addUseClause('soroban_sdk', 'Address'); - c.addConstructorArgument({ name: 'recipient', type: 'Address' }); - c.addConstructorCode(`Base::mint(e, &recipient, ${premintAbsolute});`); + c.addConstructorArgument({ name: 'recipient', type: 'Address', value: '' }); + c.addConstructorArgument({ name: 'premint', type: 'i128', value: String(premintAbsolute) }); + c.addConstructorCode(`Base::mint(e, &recipient, premint);`); } } diff --git a/packages/core/stellar/src/generate/non-fungible.ts b/packages/core/stellar/src/generate/non-fungible.ts index b86fb5c86..94648b899 100644 --- a/packages/core/stellar/src/generate/non-fungible.ts +++ b/packages/core/stellar/src/generate/non-fungible.ts @@ -8,7 +8,7 @@ const booleans = [true, false]; const blueprint = { name: ['MyToken'], symbol: ['MTK'], - tokenUri: ['https://www.mytoken.com'], + tokenUri: ['https://example.com'], burnable: booleans, pausable: booleans, upgradeable: booleans, diff --git a/packages/core/stellar/src/non-fungible.test.ts.md b/packages/core/stellar/src/non-fungible.test.ts.md index 60e88769c..bce41b7b9 100644 --- a/packages/core/stellar/src/non-fungible.test.ts.md +++ b/packages/core/stellar/src/non-fungible.test.ts.md @@ -21,10 +21,15 @@ Generated by [AVA](https://avajs.dev). ␊ #[contractimpl]␊ impl MyToken {␊ - pub fn __constructor(e: &Env) {␊ - let uri = String::from_str(e, "https://www.mytoken.com");␊ - let name = String::from_str(e, "MyToken");␊ - let symbol = String::from_str(e, "MTK");␊ + // deploy this smart contract with the Stellar CLI:␊ + //␊ + // stellar contract deploy \\␊ + // --wasm path/to/file.wasm \\␊ + // -- \\␊ + // --name MyToken \\␊ + // --symbol MTK \\␊ + // --uri "https://example.com"␊ + pub fn __constructor(e: &Env, name: String, symbol: String, uri: String) {␊ Base::set_metadata(e, uri, name, symbol);␊ }␊ }␊ @@ -54,10 +59,15 @@ Generated by [AVA](https://avajs.dev). ␊ #[contractimpl]␊ impl MyToken {␊ - pub fn __constructor(e: &Env) {␊ - let uri = String::from_str(e, "https://www.mytoken.com");␊ - let name = String::from_str(e, "MyToken");␊ - let symbol = String::from_str(e, "MTK");␊ + // deploy this smart contract with the Stellar CLI:␊ + //␊ + // stellar contract deploy \\␊ + // --wasm path/to/file.wasm \\␊ + // -- \\␊ + // --name MyToken \\␊ + // --symbol MTK \\␊ + // --uri "https://example.com"␊ + pub fn __constructor(e: &Env, name: String, symbol: String, uri: String) {␊ Base::set_metadata(e, uri, name, symbol);␊ }␊ }␊ @@ -97,10 +107,16 @@ Generated by [AVA](https://avajs.dev). ␊ #[contractimpl]␊ impl MyToken {␊ - pub fn __constructor(e: &Env, owner: Address) {␊ - let uri = String::from_str(e, "https://www.mytoken.com");␊ - let name = String::from_str(e, "MyToken");␊ - let symbol = String::from_str(e, "MTK");␊ + // deploy this smart contract with the Stellar CLI:␊ + //␊ + // stellar contract deploy \\␊ + // --wasm path/to/file.wasm \\␊ + // -- \\␊ + // --name MyToken \\␊ + // --symbol MTK \\␊ + // --uri "https://example.com" \\␊ + // --owner ␊ + pub fn __constructor(e: &Env, name: String, symbol: String, uri: String, owner: Address) {␊ Base::set_metadata(e, uri, name, symbol);␊ ownable::set_owner(e, &owner);␊ }␊ @@ -167,10 +183,16 @@ Generated by [AVA](https://avajs.dev). ␊ #[contractimpl]␊ impl MyToken {␊ - pub fn __constructor(e: &Env, owner: Address) {␊ - let uri = String::from_str(e, "https://www.mytoken.com");␊ - let name = String::from_str(e, "MyToken");␊ - let symbol = String::from_str(e, "MTK");␊ + // deploy this smart contract with the Stellar CLI:␊ + //␊ + // stellar contract deploy \\␊ + // --wasm path/to/file.wasm \\␊ + // -- \\␊ + // --name MyToken \\␊ + // --symbol MTK \\␊ + // --uri "https://example.com" \\␊ + // --owner ␊ + pub fn __constructor(e: &Env, name: String, symbol: String, uri: String, owner: Address) {␊ Base::set_metadata(e, uri, name, symbol);␊ ownable::set_owner(e, &owner);␊ }␊ @@ -253,10 +275,16 @@ Generated by [AVA](https://avajs.dev). ␊ #[contractimpl]␊ impl MyToken {␊ - pub fn __constructor(e: &Env, owner: Address) {␊ - let uri = String::from_str(e, "https://www.mytoken.com");␊ - let name = String::from_str(e, "MyToken");␊ - let symbol = String::from_str(e, "MTK");␊ + // deploy this smart contract with the Stellar CLI:␊ + //␊ + // stellar contract deploy \\␊ + // --wasm path/to/file.wasm \\␊ + // -- \\␊ + // --name MyToken \\␊ + // --symbol MTK \\␊ + // --uri "https://example.com" \\␊ + // --owner ␊ + pub fn __constructor(e: &Env, name: String, symbol: String, uri: String, owner: Address) {␊ Base::set_metadata(e, uri, name, symbol);␊ ownable::set_owner(e, &owner);␊ }␊ @@ -302,10 +330,15 @@ Generated by [AVA](https://avajs.dev). ␊ #[contractimpl]␊ impl MyToken {␊ - pub fn __constructor(e: &Env) {␊ - let uri = String::from_str(e, "https://www.mytoken.com");␊ - let name = String::from_str(e, "MyToken");␊ - let symbol = String::from_str(e, "MTK");␊ + // deploy this smart contract with the Stellar CLI:␊ + //␊ + // stellar contract deploy \\␊ + // --wasm path/to/file.wasm \\␊ + // -- \\␊ + // --name MyToken \\␊ + // --symbol MTK \\␊ + // --uri "https://example.com"␊ + pub fn __constructor(e: &Env, name: String, symbol: String, uri: String) {␊ Base::set_metadata(e, uri, name, symbol);␊ }␊ }␊ @@ -346,10 +379,16 @@ Generated by [AVA](https://avajs.dev). ␊ #[contractimpl]␊ impl MyToken {␊ - pub fn __constructor(e: &Env, owner: Address) {␊ - let uri = String::from_str(e, "https://www.mytoken.com");␊ - let name = String::from_str(e, "MyToken");␊ - let symbol = String::from_str(e, "MTK");␊ + // deploy this smart contract with the Stellar CLI:␊ + //␊ + // stellar contract deploy \\␊ + // --wasm path/to/file.wasm \\␊ + // -- \\␊ + // --name MyToken \\␊ + // --symbol MTK \\␊ + // --uri "https://example.com" \\␊ + // --owner ␊ + pub fn __constructor(e: &Env, name: String, symbol: String, uri: String, owner: Address) {␊ Base::set_metadata(e, uri, name, symbol);␊ ownable::set_owner(e, &owner);␊ }␊ @@ -404,10 +443,16 @@ Generated by [AVA](https://avajs.dev). ␊ #[contractimpl]␊ impl MyToken {␊ - pub fn __constructor(e: &Env, owner: Address) {␊ - let uri = String::from_str(e, "https://www.mytoken.com");␊ - let name = String::from_str(e, "MyToken");␊ - let symbol = String::from_str(e, "MTK");␊ + // deploy this smart contract with the Stellar CLI:␊ + //␊ + // stellar contract deploy \\␊ + // --wasm path/to/file.wasm \\␊ + // -- \\␊ + // --name MyToken \\␊ + // --symbol MTK \\␊ + // --uri "https://example.com" \\␊ + // --owner ␊ + pub fn __constructor(e: &Env, name: String, symbol: String, uri: String, owner: Address) {␊ Base::set_metadata(e, uri, name, symbol);␊ ownable::set_owner(e, &owner);␊ }␊ @@ -466,10 +511,16 @@ Generated by [AVA](https://avajs.dev). ␊ #[contractimpl]␊ impl MyToken {␊ - pub fn __constructor(e: &Env, owner: Address) {␊ - let uri = String::from_str(e, "https://www.mytoken.com");␊ - let name = String::from_str(e, "MyToken");␊ - let symbol = String::from_str(e, "MTK");␊ + // deploy this smart contract with the Stellar CLI:␊ + //␊ + // stellar contract deploy \\␊ + // --wasm path/to/file.wasm \\␊ + // -- \\␊ + // --name MyToken \\␊ + // --symbol MTK \\␊ + // --uri "https://example.com" \\␊ + // --owner ␊ + pub fn __constructor(e: &Env, name: String, symbol: String, uri: String, owner: Address) {␊ Base::set_metadata(e, uri, name, symbol);␊ ownable::set_owner(e, &owner);␊ }␊ @@ -552,10 +603,16 @@ Generated by [AVA](https://avajs.dev). ␊ #[contractimpl]␊ impl MyToken {␊ - pub fn __constructor(e: &Env, owner: Address) {␊ - let uri = String::from_str(e, "https://www.mytoken.com");␊ - let name = String::from_str(e, "MyToken");␊ - let symbol = String::from_str(e, "MTK");␊ + // deploy this smart contract with the Stellar CLI:␊ + //␊ + // stellar contract deploy \\␊ + // --wasm path/to/file.wasm \\␊ + // -- \\␊ + // --name MyToken \\␊ + // --symbol MTK \\␊ + // --uri "https://example.com" \\␊ + // --owner ␊ + pub fn __constructor(e: &Env, name: String, symbol: String, uri: String, owner: Address) {␊ Base::set_metadata(e, uri, name, symbol);␊ ownable::set_owner(e, &owner);␊ }␊ @@ -646,10 +703,15 @@ Generated by [AVA](https://avajs.dev). ␊ #[contractimpl]␊ impl MyToken {␊ - pub fn __constructor(e: &Env) {␊ - let uri = String::from_str(e, "https://www.mytoken.com");␊ - let name = String::from_str(e, "MyToken");␊ - let symbol = String::from_str(e, "MTK");␊ + // deploy this smart contract with the Stellar CLI:␊ + //␊ + // stellar contract deploy \\␊ + // --wasm path/to/file.wasm \\␊ + // -- \\␊ + // --name MyToken \\␊ + // --symbol MTK \\␊ + // --uri "https://example.com"␊ + pub fn __constructor(e: &Env, name: String, symbol: String, uri: String) {␊ Base::set_metadata(e, uri, name, symbol);␊ }␊ }␊ @@ -682,10 +744,16 @@ Generated by [AVA](https://avajs.dev). ␊ #[contractimpl]␊ impl MyToken {␊ - pub fn __constructor(e: &Env, owner: Address) {␊ - let uri = String::from_str(e, "https://www.mytoken.com");␊ - let name = String::from_str(e, "MyToken");␊ - let symbol = String::from_str(e, "MTK");␊ + // deploy this smart contract with the Stellar CLI:␊ + //␊ + // stellar contract deploy \\␊ + // --wasm path/to/file.wasm \\␊ + // -- \\␊ + // --name MyToken \\␊ + // --symbol MTK \\␊ + // --uri "https://example.com" \\␊ + // --owner ␊ + pub fn __constructor(e: &Env, name: String, symbol: String, uri: String, owner: Address) {␊ Base::set_metadata(e, uri, name, symbol);␊ ownable::set_owner(e, &owner);␊ }␊ @@ -738,10 +806,16 @@ Generated by [AVA](https://avajs.dev). ␊ #[contractimpl]␊ impl MyToken {␊ - pub fn __constructor(e: &Env, owner: Address) {␊ - let uri = String::from_str(e, "https://www.mytoken.com");␊ - let name = String::from_str(e, "MyToken");␊ - let symbol = String::from_str(e, "MTK");␊ + // deploy this smart contract with the Stellar CLI:␊ + //␊ + // stellar contract deploy \\␊ + // --wasm path/to/file.wasm \\␊ + // -- \\␊ + // --name MyToken \\␊ + // --symbol MTK \\␊ + // --uri "https://example.com" \\␊ + // --owner ␊ + pub fn __constructor(e: &Env, name: String, symbol: String, uri: String, owner: Address) {␊ Base::set_metadata(e, uri, name, symbol);␊ ownable::set_owner(e, &owner);␊ }␊ @@ -841,10 +915,16 @@ Generated by [AVA](https://avajs.dev). ␊ #[contractimpl]␊ impl CustomToken {␊ - pub fn __constructor(e: &Env, owner: Address) {␊ - let uri = String::from_str(e, "https://www.mytoken.com");␊ - let name = String::from_str(e, "Custom $ Token");␊ - let symbol = String::from_str(e, "MTK");␊ + // deploy this smart contract with the Stellar CLI:␊ + //␊ + // stellar contract deploy \\␊ + // --wasm path/to/file.wasm \\␊ + // -- \\␊ + // --name "Custom $ Token" \\␊ + // --symbol MTK \\␊ + // --uri "https://example.com" \\␊ + // --owner ␊ + pub fn __constructor(e: &Env, name: String, symbol: String, uri: String, owner: Address) {␊ Base::set_metadata(e, uri, name, symbol);␊ ownable::set_owner(e, &owner);␊ }␊ @@ -926,10 +1006,15 @@ Generated by [AVA](https://avajs.dev). ␊ #[contractimpl]␊ impl MyToken {␊ - pub fn __constructor(e: &Env) {␊ - let uri = String::from_str(e, "https://example.com/nfts/");␊ - let name = String::from_str(e, "MyToken");␊ - let symbol = String::from_str(e, "MTK");␊ + // deploy this smart contract with the Stellar CLI:␊ + //␊ + // stellar contract deploy \\␊ + // --wasm path/to/file.wasm \\␊ + // -- \\␊ + // --name MyToken \\␊ + // --symbol MTK \\␊ + // --uri "https://example.com/nfts/"␊ + pub fn __constructor(e: &Env, name: String, symbol: String, uri: String) {␊ Base::set_metadata(e, uri, name, symbol);␊ }␊ }␊ diff --git a/packages/core/stellar/src/non-fungible.test.ts.snap b/packages/core/stellar/src/non-fungible.test.ts.snap index 52c1cee76..e153f1dc5 100644 Binary files a/packages/core/stellar/src/non-fungible.test.ts.snap and b/packages/core/stellar/src/non-fungible.test.ts.snap differ diff --git a/packages/core/stellar/src/non-fungible.ts b/packages/core/stellar/src/non-fungible.ts index 1859626f6..6dafe7bfb 100644 --- a/packages/core/stellar/src/non-fungible.ts +++ b/packages/core/stellar/src/non-fungible.ts @@ -16,7 +16,7 @@ import { toByteArray } from './utils/convert-strings'; export const defaults: Required = { name: 'MyToken', symbol: 'MTK', - tokenUri: 'https://www.mytoken.com', + tokenUri: 'https://example.com', burnable: false, enumerable: false, consecutive: false, @@ -124,9 +124,9 @@ export function buildNonFungible(opts: NonFungibleOptions): Contract { function addBase(c: ContractBuilder, name: string, symbol: string, tokenUri: string, pausable: boolean) { // Set metadata - c.addConstructorCode(`let uri = String::from_str(e, "${tokenUri}");`); - c.addConstructorCode(`let name = String::from_str(e, "${name}");`); - c.addConstructorCode(`let symbol = String::from_str(e, "${symbol}");`); + c.addConstructorArgument({ name: 'name', type: 'String', value: name }); + c.addConstructorArgument({ name: 'symbol', type: 'String', value: symbol }); + c.addConstructorArgument({ name: 'uri', type: 'String', value: tokenUri }); c.addConstructorCode(`Base::set_metadata(e, uri, name, symbol);`); // Set token functions diff --git a/packages/core/stellar/src/print.ts b/packages/core/stellar/src/print.ts index 7b46f2e03..1dbaf4f8b 100644 --- a/packages/core/stellar/src/print.ts +++ b/packages/core/stellar/src/print.ts @@ -1,10 +1,9 @@ -import type { Contract, Argument, ContractFunction, TraitImplBlock, UseClause } from './contract'; +import type { Contract, Argument, ContractFunction, TraitImplBlock, UseClause, ConstructorArgument } from './contract'; import type { Lines } from './utils/format-lines'; import { formatLines, spaceBetween } from './utils/format-lines'; import { getSelfArg } from './common-options'; import { compatibleContractsSemver } from './utils/version'; -import { toByteArray } from './utils/convert-strings'; const DEFAULT_SECTION = '1. with no section'; const STANDALONE_IMPORTS_GROUP = 'Standalone Imports'; @@ -249,7 +248,7 @@ function printFunction(fn: ContractFunction): Lines[] { } } - return printFunction2(fn.pub, head, args, fn.tags, fn.returns, undefined, codeLines); + return printFunction2(fn.pub, head, args, fn.tags, fn.returns, undefined, codeLines, undefined); } function printContractFunctions(contract: Contract): Lines[] { @@ -283,6 +282,7 @@ function printConstructor(contract: Contract): Lines[] { if (contract.constructorCode.length > 0) { const head = 'fn __constructor'; const args = [getSelfArg(), ...contract.constructorArgs]; + const deploy = printDeployCommand(contract.constructorArgs); const body = spaceBetween(withSemicolons(contract.constructorCode)); @@ -294,6 +294,7 @@ function printConstructor(contract: Contract): Lines[] { undefined, undefined, body, + deploy, ); return constructor; } else { @@ -311,6 +312,7 @@ function printFunction2( returns: string | undefined, returnLine: string | undefined, code: Lines[], + deploy: string[] | undefined, ): Lines[] { const fn = []; @@ -318,6 +320,10 @@ function printFunction2( fn.push(`#[${tags[i]}]`); } + if (kindedName === 'fn __constructor' && deploy) { + fn.push(...deploy); + } + let accum = ''; if (pub) { @@ -371,3 +377,28 @@ function printDocumentations(documentations: string[]): string[] { function printMetadata(contract: Contract) { return Array.from(contract.metadata.entries()).map(([key, value]) => `contractmeta!(key="${key}", val="${value}");`); } + +const escapeQuotes = (s: string): string => s.replace(/"/g, '\\"'); + +const needsQuoting = (name: string, value?: string): boolean => + name === 'uri' || (value !== undefined && /[\s"'$\\]/.test(value)); + +const formatDeployValue = (name: string, value?: string): string => { + if (value === undefined && name === 'uri') return `"https://example.com/"`; + if (value === undefined) return ''; + return needsQuoting(name, value) ? `"${escapeQuotes(value)}"` : value; +}; + +const formatDeployArgument = (arg: ConstructorArgument, isLast: boolean): string => + [`// --${arg.name} ${formatDeployValue(arg.name, arg.value)}`, isLast ? '' : ' \\'].join(''); + +const deployHeader = (): string[] => [ + '// deploy this smart contract with the Stellar CLI:', + '//', + '// stellar contract deploy \\', + '// --wasm path/to/file.wasm \\', + '// -- \\', +]; + +export const printDeployCommand = (args: ConstructorArgument[]): string[] => + args.length === 0 ? [] : [...deployHeader(), ...args.map((a, i) => formatDeployArgument(a, i === args.length - 1))]; diff --git a/packages/core/stellar/src/set-access-control.ts b/packages/core/stellar/src/set-access-control.ts index 9725c58ed..8caabf0ce 100644 --- a/packages/core/stellar/src/set-access-control.ts +++ b/packages/core/stellar/src/set-access-control.ts @@ -32,7 +32,7 @@ export function setAccessControl(c: ContractBuilder, access: Access): void { }; c.addTraitImplBlock(ownableTrait); - c.addConstructorArgument({ name: 'owner', type: 'Address' }); + c.addConstructorArgument({ name: 'owner', type: 'Address', value: '' }); c.addConstructorCode('ownable::set_owner(e, &owner);'); } break; @@ -50,7 +50,7 @@ export function setAccessControl(c: ContractBuilder, access: Access): void { }; c.addTraitImplBlock(accessControltrait); - c.addConstructorArgument({ name: 'admin', type: 'Address' }); + c.addConstructorArgument({ name: 'admin', type: 'Address', value: '' }); c.addConstructorCode('access_control::set_admin(e, &admin);'); break; } @@ -93,7 +93,7 @@ export function requireAccessControl( if (caller && role) { c.addUseClause('soroban_sdk', 'Symbol'); - c.addConstructorArgument({ name: role, type: 'Address' }); + c.addConstructorArgument({ name: role, type: 'Address', value: `<${role}_address>` }); c.addConstructorCode(`access_control::grant_role_no_auth(e, &admin, &${role}, &Symbol::new(e, "${role}"));`); if (useMacro) { diff --git a/packages/core/stellar/src/stablecoin.test.ts.md b/packages/core/stellar/src/stablecoin.test.ts.md index 496964c3e..914b12043 100644 --- a/packages/core/stellar/src/stablecoin.test.ts.md +++ b/packages/core/stellar/src/stablecoin.test.ts.md @@ -21,8 +21,15 @@ Generated by [AVA](https://avajs.dev). ␊ #[contractimpl]␊ impl MyStablecoin {␊ - pub fn __constructor(e: &Env) {␊ - Base::set_metadata(e, 18, String::from_str(e, "MyStablecoin"), String::from_str(e, "MST"));␊ + // deploy this smart contract with the Stellar CLI:␊ + //␊ + // stellar contract deploy \\␊ + // --wasm path/to/file.wasm \\␊ + // -- \\␊ + // --name MyStablecoin \\␊ + // --symbol MST␊ + pub fn __constructor(e: &Env, name: String, symbol: String) {␊ + Base::set_metadata(e, 18, name, symbol);␊ }␊ }␊ ␊ @@ -51,8 +58,15 @@ Generated by [AVA](https://avajs.dev). ␊ #[contractimpl]␊ impl MyStablecoin {␊ - pub fn __constructor(e: &Env) {␊ - Base::set_metadata(e, 18, String::from_str(e, "MyStablecoin"), String::from_str(e, "MST"));␊ + // deploy this smart contract with the Stellar CLI:␊ + //␊ + // stellar contract deploy \\␊ + // --wasm path/to/file.wasm \\␊ + // -- \\␊ + // --name MyStablecoin \\␊ + // --symbol MST␊ + pub fn __constructor(e: &Env, name: String, symbol: String) {␊ + Base::set_metadata(e, 18, name, symbol);␊ }␊ }␊ ␊ @@ -91,8 +105,16 @@ Generated by [AVA](https://avajs.dev). ␊ #[contractimpl]␊ impl MyStablecoin {␊ - pub fn __constructor(e: &Env, owner: Address) {␊ - Base::set_metadata(e, 18, String::from_str(e, "MyStablecoin"), String::from_str(e, "MST"));␊ + // deploy this smart contract with the Stellar CLI:␊ + //␊ + // stellar contract deploy \\␊ + // --wasm path/to/file.wasm \\␊ + // -- \\␊ + // --name MyStablecoin \\␊ + // --symbol MST \\␊ + // --owner ␊ + pub fn __constructor(e: &Env, name: String, symbol: String, owner: Address) {␊ + Base::set_metadata(e, 18, name, symbol);␊ ownable::set_owner(e, &owner);␊ }␊ }␊ @@ -158,8 +180,16 @@ Generated by [AVA](https://avajs.dev). ␊ #[contractimpl]␊ impl MyStablecoin {␊ - pub fn __constructor(e: &Env, owner: Address) {␊ - Base::set_metadata(e, 18, String::from_str(e, "MyStablecoin"), String::from_str(e, "MST"));␊ + // deploy this smart contract with the Stellar CLI:␊ + //␊ + // stellar contract deploy \\␊ + // --wasm path/to/file.wasm \\␊ + // -- \\␊ + // --name MyStablecoin \\␊ + // --symbol MST \\␊ + // --owner ␊ + pub fn __constructor(e: &Env, name: String, symbol: String, owner: Address) {␊ + Base::set_metadata(e, 18, name, symbol);␊ ownable::set_owner(e, &owner);␊ }␊ }␊ @@ -240,9 +270,18 @@ Generated by [AVA](https://avajs.dev). ␊ #[contractimpl]␊ impl MyStablecoin {␊ - pub fn __constructor(e: &Env, recipient: Address) {␊ - Base::set_metadata(e, 18, String::from_str(e, "MyStablecoin"), String::from_str(e, "MST"));␊ - Base::mint(e, &recipient, 1000000000000000000000);␊ + // deploy this smart contract with the Stellar CLI:␊ + //␊ + // stellar contract deploy \\␊ + // --wasm path/to/file.wasm \\␊ + // -- \\␊ + // --name MyStablecoin \\␊ + // --symbol MST \\␊ + // --recipient \\␊ + // --premint 1000000000000000000000␊ + pub fn __constructor(e: &Env, name: String, symbol: String, recipient: Address, premint: i128) {␊ + Base::set_metadata(e, 18, name, symbol);␊ + Base::mint(e, &recipient, premint);␊ }␊ }␊ ␊ @@ -271,8 +310,15 @@ Generated by [AVA](https://avajs.dev). ␊ #[contractimpl]␊ impl MyStablecoin {␊ - pub fn __constructor(e: &Env) {␊ - Base::set_metadata(e, 18, String::from_str(e, "MyStablecoin"), String::from_str(e, "MST"));␊ + // deploy this smart contract with the Stellar CLI:␊ + //␊ + // stellar contract deploy \\␊ + // --wasm path/to/file.wasm \\␊ + // -- \\␊ + // --name MyStablecoin \\␊ + // --symbol MST␊ + pub fn __constructor(e: &Env, name: String, symbol: String) {␊ + Base::set_metadata(e, 18, name, symbol);␊ }␊ }␊ ␊ @@ -301,8 +347,15 @@ Generated by [AVA](https://avajs.dev). ␊ #[contractimpl]␊ impl MyStablecoin {␊ - pub fn __constructor(e: &Env) {␊ - Base::set_metadata(e, 18, String::from_str(e, "MyStablecoin"), String::from_str(e, "MST"));␊ + // deploy this smart contract with the Stellar CLI:␊ + //␊ + // stellar contract deploy \\␊ + // --wasm path/to/file.wasm \\␊ + // -- \\␊ + // --name MyStablecoin \\␊ + // --symbol MST␊ + pub fn __constructor(e: &Env, name: String, symbol: String) {␊ + Base::set_metadata(e, 18, name, symbol);␊ }␊ }␊ ␊ @@ -332,8 +385,16 @@ Generated by [AVA](https://avajs.dev). ␊ #[contractimpl]␊ impl MyStablecoin {␊ - pub fn __constructor(e: &Env, owner: Address) {␊ - Base::set_metadata(e, 18, String::from_str(e, "MyStablecoin"), String::from_str(e, "MST"));␊ + // deploy this smart contract with the Stellar CLI:␊ + //␊ + // stellar contract deploy \\␊ + // --wasm path/to/file.wasm \\␊ + // -- \\␊ + // --name MyStablecoin \\␊ + // --symbol MST \\␊ + // --owner ␊ + pub fn __constructor(e: &Env, name: String, symbol: String, owner: Address) {␊ + Base::set_metadata(e, 18, name, symbol);␊ ownable::set_owner(e, &owner);␊ }␊ }␊ @@ -372,8 +433,16 @@ Generated by [AVA](https://avajs.dev). ␊ #[contractimpl]␊ impl MyStablecoin {␊ - pub fn __constructor(e: &Env, admin: Address) {␊ - Base::set_metadata(e, 18, String::from_str(e, "MyStablecoin"), String::from_str(e, "MST"));␊ + // deploy this smart contract with the Stellar CLI:␊ + //␊ + // stellar contract deploy \\␊ + // --wasm path/to/file.wasm \\␊ + // -- \\␊ + // --name MyStablecoin \\␊ + // --symbol MST \\␊ + // --admin ␊ + pub fn __constructor(e: &Env, name: String, symbol: String, admin: Address) {␊ + Base::set_metadata(e, 18, name, symbol);␊ access_control::set_admin(e, &admin);␊ }␊ }␊ @@ -414,8 +483,16 @@ Generated by [AVA](https://avajs.dev). ␊ #[contractimpl]␊ impl MyStablecoin {␊ - pub fn __constructor(e: &Env, owner: Address) {␊ - Base::set_metadata(e, 18, String::from_str(e, "MyStablecoin"), String::from_str(e, "MST"));␊ + // deploy this smart contract with the Stellar CLI:␊ + //␊ + // stellar contract deploy \\␊ + // --wasm path/to/file.wasm \\␊ + // -- \\␊ + // --name MyStablecoin \\␊ + // --symbol MST \\␊ + // --owner ␊ + pub fn __constructor(e: &Env, name: String, symbol: String, owner: Address) {␊ + Base::set_metadata(e, 18, name, symbol);␊ ownable::set_owner(e, &owner);␊ }␊ }␊ @@ -477,8 +554,16 @@ Generated by [AVA](https://avajs.dev). ␊ #[contractimpl]␊ impl MyStablecoin {␊ - pub fn __constructor(e: &Env, owner: Address) {␊ - Base::set_metadata(e, 18, String::from_str(e, "MyStablecoin"), String::from_str(e, "MST"));␊ + // deploy this smart contract with the Stellar CLI:␊ + //␊ + // stellar contract deploy \\␊ + // --wasm path/to/file.wasm \\␊ + // -- \\␊ + // --name MyStablecoin \\␊ + // --symbol MST \\␊ + // --owner ␊ + pub fn __constructor(e: &Env, name: String, symbol: String, owner: Address) {␊ + Base::set_metadata(e, 18, name, symbol);␊ ownable::set_owner(e, &owner);␊ }␊ }␊ @@ -541,9 +626,26 @@ Generated by [AVA](https://avajs.dev). ␊ #[contractimpl]␊ impl MyStablecoin {␊ - pub fn __constructor(e: &Env, recipient: Address, owner: Address) {␊ - Base::set_metadata(e, 18, String::from_str(e, "MyStablecoin"), String::from_str(e, "MST"));␊ - Base::mint(e, &recipient, 2000000000000000000000);␊ + // deploy this smart contract with the Stellar CLI:␊ + //␊ + // stellar contract deploy \\␊ + // --wasm path/to/file.wasm \\␊ + // -- \\␊ + // --name MyStablecoin \\␊ + // --symbol MST \\␊ + // --recipient \\␊ + // --premint 2000000000000000000000 \\␊ + // --owner ␊ + pub fn __constructor(␊ + e: &Env,␊ + name: String,␊ + symbol: String,␊ + recipient: Address,␊ + premint: i128,␊ + owner: Address,␊ + ) {␊ + Base::set_metadata(e, 18, name, symbol);␊ + Base::mint(e, &recipient, premint);␊ ownable::set_owner(e, &owner);␊ }␊ ␊ @@ -651,9 +753,26 @@ Generated by [AVA](https://avajs.dev). ␊ #[contractimpl]␊ impl MyStablecoin {␊ - pub fn __constructor(e: &Env, recipient: Address, owner: Address) {␊ - Base::set_metadata(e, 18, String::from_str(e, "MyStablecoin"), String::from_str(e, "MST"));␊ - Base::mint(e, &recipient, 2000000000000000000000);␊ + // deploy this smart contract with the Stellar CLI:␊ + //␊ + // stellar contract deploy \\␊ + // --wasm path/to/file.wasm \\␊ + // -- \\␊ + // --name MyStablecoin \\␊ + // --symbol MST \\␊ + // --recipient \\␊ + // --premint 2000000000000000000000 \\␊ + // --owner ␊ + pub fn __constructor(␊ + e: &Env,␊ + name: String,␊ + symbol: String,␊ + recipient: Address,␊ + premint: i128,␊ + owner: Address,␊ + ) {␊ + Base::set_metadata(e, 18, name, symbol);␊ + Base::mint(e, &recipient, premint);␊ ownable::set_owner(e, &owner);␊ }␊ ␊ @@ -761,16 +880,32 @@ Generated by [AVA](https://avajs.dev). ␊ #[contractimpl]␊ impl MyStablecoin {␊ + // deploy this smart contract with the Stellar CLI:␊ + //␊ + // stellar contract deploy \\␊ + // --wasm path/to/file.wasm \\␊ + // -- \\␊ + // --name MyStablecoin \\␊ + // --symbol MST \\␊ + // --recipient \\␊ + // --premint 2000000000000000000000 \\␊ + // --admin \\␊ + // --pauser \\␊ + // --minter \\␊ + // --manager ␊ pub fn __constructor(␊ e: &Env,␊ + name: String,␊ + symbol: String,␊ recipient: Address,␊ + premint: i128,␊ admin: Address,␊ pauser: Address,␊ minter: Address,␊ manager: Address,␊ ) {␊ - Base::set_metadata(e, 18, String::from_str(e, "MyStablecoin"), String::from_str(e, "MST"));␊ - Base::mint(e, &recipient, 2000000000000000000000);␊ + Base::set_metadata(e, 18, name, symbol);␊ + Base::mint(e, &recipient, premint);␊ access_control::set_admin(e, &admin);␊ access_control::grant_role_no_auth(e, &admin, &pauser, &Symbol::new(e, "pauser"));␊ access_control::grant_role_no_auth(e, &admin, &minter, &Symbol::new(e, "minter"));␊ @@ -881,16 +1016,32 @@ Generated by [AVA](https://avajs.dev). ␊ #[contractimpl]␊ impl MyStablecoin {␊ + // deploy this smart contract with the Stellar CLI:␊ + //␊ + // stellar contract deploy \\␊ + // --wasm path/to/file.wasm \\␊ + // -- \\␊ + // --name MyStablecoin \\␊ + // --symbol MST \\␊ + // --recipient \\␊ + // --premint 2000000000000000000000 \\␊ + // --admin \\␊ + // --pauser \\␊ + // --minter \\␊ + // --manager ␊ pub fn __constructor(␊ e: &Env,␊ + name: String,␊ + symbol: String,␊ recipient: Address,␊ + premint: i128,␊ admin: Address,␊ pauser: Address,␊ minter: Address,␊ manager: Address,␊ ) {␊ - Base::set_metadata(e, 18, String::from_str(e, "MyStablecoin"), String::from_str(e, "MST"));␊ - Base::mint(e, &recipient, 2000000000000000000000);␊ + Base::set_metadata(e, 18, name, symbol);␊ + Base::mint(e, &recipient, premint);␊ access_control::set_admin(e, &admin);␊ access_control::grant_role_no_auth(e, &admin, &pauser, &Symbol::new(e, "pauser"));␊ access_control::grant_role_no_auth(e, &admin, &minter, &Symbol::new(e, "minter"));␊ @@ -999,9 +1150,26 @@ Generated by [AVA](https://avajs.dev). ␊ #[contractimpl]␊ impl CustomToken {␊ - pub fn __constructor(e: &Env, recipient: Address, owner: Address) {␊ - Base::set_metadata(e, 18, String::from_str(e, "Custom $ Token"), String::from_str(e, "MST"));␊ - Base::mint(e, &recipient, 2000000000000000000000);␊ + // deploy this smart contract with the Stellar CLI:␊ + //␊ + // stellar contract deploy \\␊ + // --wasm path/to/file.wasm \\␊ + // -- \\␊ + // --name "Custom $ Token" \\␊ + // --symbol MST \\␊ + // --recipient \\␊ + // --premint 2000000000000000000000 \\␊ + // --owner ␊ + pub fn __constructor(␊ + e: &Env,␊ + name: String,␊ + symbol: String,␊ + recipient: Address,␊ + premint: i128,␊ + owner: Address,␊ + ) {␊ + Base::set_metadata(e, 18, name, symbol);␊ + Base::mint(e, &recipient, premint);␊ ownable::set_owner(e, &owner);␊ }␊ ␊ diff --git a/packages/core/stellar/src/stablecoin.test.ts.snap b/packages/core/stellar/src/stablecoin.test.ts.snap index 93b9ab4da..b1238021e 100644 Binary files a/packages/core/stellar/src/stablecoin.test.ts.snap and b/packages/core/stellar/src/stablecoin.test.ts.snap differ diff --git a/packages/core/stellar/src/zip-rust.compile.test.ts.md b/packages/core/stellar/src/zip-rust.compile.test.ts.md index 8eecc5875..da75f30f7 100644 --- a/packages/core/stellar/src/zip-rust.compile.test.ts.md +++ b/packages/core/stellar/src/zip-rust.compile.test.ts.md @@ -22,9 +22,18 @@ Generated by [AVA](https://avajs.dev). ␊ #[contractimpl]␊ impl MyToken {␊ - pub fn __constructor(e: &Env, recipient: Address) {␊ - Base::set_metadata(e, 18, String::from_str(e, "MyToken"), String::from_str(e, "MTK"));␊ - Base::mint(e, &recipient, 2000000000000000000000);␊ + // deploy this smart contract with the Stellar CLI:␊ + //␊ + // stellar contract deploy \\␊ + // --wasm path/to/file.wasm \\␊ + // -- \\␊ + // --name MyToken \\␊ + // --symbol MTK \\␊ + // --recipient \\␊ + // --premint 2000000000000000000000␊ + pub fn __constructor(e: &Env, name: String, symbol: String, recipient: Address, premint: i128) {␊ + Base::set_metadata(e, 18, name, symbol);␊ + Base::mint(e, &recipient, premint);␊ }␊ }␊ ␊ @@ -55,13 +64,13 @@ Generated by [AVA](https://avajs.dev). fn initial_state() {␊ let env = Env::default();␊ ␊ - let contract_addr = env.register(MyToken, (Address::generate(&env),));␊ + let contract_addr = env.register(MyToken, (String::from_str(&env, "MyToken"),String::from_str(&env, "MTK"),Address::generate(&env),2000000000000000000000i128));␊ let client = MyTokenClient::new(&env, &contract_addr);␊ ␊ assert_eq!(client.name(), String::from_str(&env, "MyToken"));␊ }␊ ␊ - // Add more tests bellow␊ + // Add more tests below␊ `, `#![no_std]␊ #![allow(dead_code)]␊ diff --git a/packages/core/stellar/src/zip-rust.compile.test.ts.snap b/packages/core/stellar/src/zip-rust.compile.test.ts.snap index d554d6bd2..26d8c9fbf 100644 Binary files a/packages/core/stellar/src/zip-rust.compile.test.ts.snap and b/packages/core/stellar/src/zip-rust.compile.test.ts.snap differ diff --git a/packages/core/stellar/src/zip-shared.test.ts b/packages/core/stellar/src/zip-shared.test.ts index 6c0b640cd..50b54524c 100644 --- a/packages/core/stellar/src/zip-shared.test.ts +++ b/packages/core/stellar/src/zip-shared.test.ts @@ -134,7 +134,7 @@ fn initial_state() { assert_eq!(client.name(), String::from_str(&env, "Fungible")); } -// Add more tests bellow +// Add more tests below `; t.is(output, expected); }); @@ -164,7 +164,7 @@ fn initial_state() { assert_eq!(client.name(), String::from_str(&env, "NoArgs")); } -// Add more tests bellow +// Add more tests below `; t.is(output, expected); }); @@ -194,7 +194,37 @@ fn initial_state() { assert_eq!(client.name(), String::from_str(&env, "SingleArg")); } -// Add more tests bellow +// Add more tests below +`; + t.is(output, expected); +}); + +test('printRustNameTest handles single String arg', t => { + const contract = { + name: 'SingleToken', + constructorArgs: [{ name: 'name', type: 'String', value: 'SingleToken' }], + }; + const output = printRustNameTest(contract); + + const expected = `#![cfg(test)] + +extern crate std; + +use soroban_sdk::{ Env, String }; + +use crate::contract::{ SingleToken, SingleTokenClient }; + +#[test] +fn initial_state() { + let env = Env::default(); + + let contract_addr = env.register(SingleToken, (String::from_str(&env, "SingleToken"),)); + let client = SingleTokenClient::new(&env, &contract_addr); + + assert_eq!(client.name(), String::from_str(&env, "SingleToken")); +} + +// Add more tests below `; t.is(output, expected); }); diff --git a/packages/core/stellar/src/zip-shared.ts b/packages/core/stellar/src/zip-shared.ts index b87e51702..562520452 100644 --- a/packages/core/stellar/src/zip-shared.ts +++ b/packages/core/stellar/src/zip-shared.ts @@ -8,6 +8,10 @@ function pascalToSnakeCase(string: string) { .toLowerCase(); } +function stringFromStr(str: string): string { + return `String::from_str(&env, "${str}")`; +} + export const contractOptionsToContractName = pascalToSnakeCase; export function getAddressArgs(c: Pick): string[] { @@ -16,6 +20,29 @@ export function getAddressArgs(c: Pick): string[] { .map(constructorArg => constructorArg.name); } +export function getConstructorArgs(c: Pick): string[] { + return (c.constructorArgs || []) + .map(constructorArg => { + switch (constructorArg.type?.trim()) { + case 'Address': + return 'Address::generate(&env)'; + case 'String': + return constructorArg.value + ? stringFromStr(constructorArg.value) + : constructorArg.name === 'name' + ? stringFromStr('MyToken') + : constructorArg.name === 'symbol' + ? stringFromStr('MTK') + : stringFromStr('SomeString'); + case 'i128': + return constructorArg.value ? `${constructorArg.value}i128` : '100i128'; + default: + return ''; + } + }) + .filter(Boolean); +} + export const printRustNameTest = (c: Pick) => `#![cfg(test)] extern crate std; @@ -28,15 +55,15 @@ use crate::contract::{ ${c.name}, ${c.name}Client }; fn initial_state() { let env = Env::default(); - let contract_addr = env.register(${c.name}, (${getAddressArgs(c) - .map(() => 'Address::generate(&env)') - .join(',')}${getAddressArgs(c).length === 1 ? ',' : ''})); + let contract_addr = env.register(${c.name}, (${getConstructorArgs(c).join( + ',', + )}${getConstructorArgs(c).length === 1 ? ',' : ''})); let client = ${c.name}Client::new(&env, &contract_addr); assert_eq!(client.name(), String::from_str(&env, "${c.name}")); } -// Add more tests bellow +// Add more tests below `; export const libDependencies = [