@openzeppelin/wizard-stellar 0.1.0 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (71) hide show
  1. package/README.md +1 -0
  2. package/dist/add-pausable.js +7 -7
  3. package/dist/add-pausable.js.map +1 -1
  4. package/dist/add-upgradeable.d.ts +4 -0
  5. package/dist/add-upgradeable.d.ts.map +1 -0
  6. package/dist/add-upgradeable.js +26 -0
  7. package/dist/add-upgradeable.js.map +1 -0
  8. package/dist/api.d.ts +3 -0
  9. package/dist/api.d.ts.map +1 -1
  10. package/dist/api.js +6 -1
  11. package/dist/api.js.map +1 -1
  12. package/dist/build-generic.d.ts +4 -0
  13. package/dist/build-generic.d.ts.map +1 -1
  14. package/dist/build-generic.js +5 -2
  15. package/dist/build-generic.js.map +1 -1
  16. package/dist/contract.d.ts +22 -11
  17. package/dist/contract.d.ts.map +1 -1
  18. package/dist/contract.js +58 -12
  19. package/dist/contract.js.map +1 -1
  20. package/dist/fungible.d.ts +1 -0
  21. package/dist/fungible.d.ts.map +1 -1
  22. package/dist/fungible.js +38 -32
  23. package/dist/fungible.js.map +1 -1
  24. package/dist/generate/fungible.d.ts.map +1 -1
  25. package/dist/generate/fungible.js +1 -0
  26. package/dist/generate/fungible.js.map +1 -1
  27. package/dist/generate/non-fungible.d.ts +3 -0
  28. package/dist/generate/non-fungible.d.ts.map +1 -0
  29. package/dist/generate/non-fungible.js +24 -0
  30. package/dist/generate/non-fungible.js.map +1 -0
  31. package/dist/generate/sources.d.ts.map +1 -1
  32. package/dist/generate/sources.js +6 -0
  33. package/dist/generate/sources.js.map +1 -1
  34. package/dist/index.d.ts +1 -0
  35. package/dist/index.d.ts.map +1 -1
  36. package/dist/index.js +3 -1
  37. package/dist/index.js.map +1 -1
  38. package/dist/kind.js +2 -1
  39. package/dist/kind.js.map +1 -1
  40. package/dist/non-fungible.d.ts +17 -0
  41. package/dist/non-fungible.d.ts.map +1 -0
  42. package/dist/non-fungible.js +356 -0
  43. package/dist/non-fungible.js.map +1 -0
  44. package/dist/print.d.ts.map +1 -1
  45. package/dist/print.js +54 -17
  46. package/dist/print.js.map +1 -1
  47. package/dist/set-access-control.d.ts +2 -2
  48. package/dist/set-access-control.d.ts.map +1 -1
  49. package/dist/set-access-control.js +2 -7
  50. package/dist/set-access-control.js.map +1 -1
  51. package/dist/test.js +3 -0
  52. package/dist/test.js.map +1 -1
  53. package/dist/utils/version.d.ts +3 -3
  54. package/dist/utils/version.js +2 -2
  55. package/package.json +3 -4
  56. package/src/add-pausable.ts +7 -7
  57. package/src/add-upgradeable.ts +30 -0
  58. package/src/api.ts +8 -0
  59. package/src/build-generic.ts +9 -2
  60. package/src/contract.ts +73 -21
  61. package/src/fungible.ts +38 -30
  62. package/src/generate/fungible.ts +1 -0
  63. package/src/generate/non-fungible.ts +24 -0
  64. package/src/generate/sources.ts +7 -0
  65. package/src/index.ts +1 -0
  66. package/src/kind.ts +2 -1
  67. package/src/non-fungible.ts +410 -0
  68. package/src/print.ts +78 -28
  69. package/src/set-access-control.ts +8 -9
  70. package/src/test.ts +4 -0
  71. package/src/utils/version.ts +2 -2
package/src/print.ts CHANGED
@@ -1,4 +1,4 @@
1
- import type { Contract, Argument, ContractFunction, ImplementedTrait, UseClause } from './contract';
1
+ import type { Contract, Argument, ContractFunction, TraitImplBlock, UseClause } from './contract';
2
2
 
3
3
  import type { Lines } from './utils/format-lines';
4
4
  import { formatLines, spaceBetween } from './utils/format-lines';
@@ -16,6 +16,7 @@ export function printContract(contract: Contract): string {
16
16
  [
17
17
  `// SPDX-License-Identifier: ${contract.license}`,
18
18
  `// Compatible with OpenZeppelin Stellar Soroban Contracts ${compatibleContractsSemver}`,
19
+ `#![no_std]`,
19
20
  ],
20
21
  spaceBetween(
21
22
  printUseClauses(contract),
@@ -30,7 +31,13 @@ export function printContract(contract: Contract): string {
30
31
  }
31
32
 
32
33
  function printContractStruct(contract: Contract): Lines[] {
33
- return ['#[contract]', `pub struct ${contract.name};`];
34
+ const lines = [];
35
+ if (contract.derives.length > 0) {
36
+ lines.push(`#[derive(${contract.derives.sort().join(', ')})]`);
37
+ }
38
+ lines.push('#[contract]');
39
+ lines.push(`pub struct ${contract.name};`);
40
+ return lines;
34
41
  }
35
42
 
36
43
  function printContractErrors(contract: Contract): Lines[] {
@@ -150,28 +157,25 @@ function printImplementedTraits(contract: Contract): Lines[] {
150
157
  if (a.tags.length !== b.tags.length) {
151
158
  return a.tags.length - b.tags.length;
152
159
  }
153
- return a.name.localeCompare(b.name);
160
+ return a.traitName.localeCompare(b.traitName);
154
161
  });
155
162
 
156
163
  // group by section
157
- const grouped = sortedTraits.reduce(
158
- (result: { [section: string]: ImplementedTrait[] }, current: ImplementedTrait) => {
159
- // default to no section
160
- const section = current.section ?? DEFAULT_SECTION;
161
- (result[section] = result[section] || []).push(current);
162
- return result;
163
- },
164
- {},
165
- );
164
+ const grouped = sortedTraits.reduce((result: { [section: string]: TraitImplBlock[] }, current: TraitImplBlock) => {
165
+ // default to no section
166
+ const section = current.section ?? DEFAULT_SECTION;
167
+ (result[section] = result[section] || []).push(current);
168
+ return result;
169
+ }, {});
166
170
 
167
171
  const sections = Object.entries(grouped)
168
172
  .sort((a, b) => a[0].localeCompare(b[0]))
169
- .map(([section, impls]) => printImplementedTraitsSection(section, impls as ImplementedTrait[]));
173
+ .map(([section, impls]) => printImplementedTraitsSection(section, impls as TraitImplBlock[]));
170
174
 
171
175
  return spaceBetween(...sections);
172
176
  }
173
177
 
174
- function printImplementedTraitsSection(section: string, impls: ImplementedTrait[]): Lines[] {
178
+ function printImplementedTraitsSection(section: string, impls: TraitImplBlock[]): Lines[] {
175
179
  const lines = [];
176
180
  const isDefaultSection = section === DEFAULT_SECTION;
177
181
  if (!isDefaultSection) {
@@ -188,13 +192,33 @@ function printImplementedTraitsSection(section: string, impls: ImplementedTrait[
188
192
  return lines;
189
193
  }
190
194
 
191
- function printImplementedTrait(trait: ImplementedTrait): Lines[] {
195
+ function printImplementedTrait(trait: TraitImplBlock): Lines[] {
192
196
  const implLines = [];
193
197
  implLines.push(...trait.tags.map(t => `#[${t}]`));
194
- implLines.push(`impl ${trait.name} for ${trait.for} {`);
195
- const fns = trait.functions.map(fn => printFunction(fn));
196
- implLines.push(spaceBetween(...fns));
197
- implLines.push('}');
198
+
199
+ const head = `impl ${trait.traitName} for ${trait.structName}`;
200
+
201
+ const assocTypeLines =
202
+ trait.assocType !== undefined && trait.assocType.trim().length > 0 ? [TAB + trait.assocType.trim(), ''] : [];
203
+
204
+ const functionLines = trait.functions.map(fn => printFunction(fn));
205
+
206
+ const hasBodyContent = assocTypeLines.length > 0 || functionLines.length > 0;
207
+
208
+ if (!hasBodyContent) {
209
+ // Empty impl
210
+ implLines.push(`${head} {}`);
211
+ } else {
212
+ implLines.push(`${head} {`);
213
+ if (assocTypeLines.length > 0) {
214
+ implLines.push(...assocTypeLines);
215
+ }
216
+ if (functionLines.length > 0) {
217
+ implLines.push(spaceBetween(...functionLines));
218
+ }
219
+ implLines.push('}');
220
+ }
221
+
198
222
  return implLines;
199
223
  }
200
224
 
@@ -215,26 +239,45 @@ function printFunction(fn: ContractFunction): Lines[] {
215
239
  }
216
240
  }
217
241
 
218
- return printFunction2(head, args, fn.tag, fn.returns, undefined, codeLines);
242
+ return printFunction2(fn.pub, head, args, fn.tag, fn.returns, undefined, codeLines);
219
243
  }
220
244
 
221
245
  function printContractFunctions(contract: Contract): Lines[] {
222
- const implLines = [];
223
- implLines.push('#[contractimpl]');
224
- implLines.push(`impl ${contract.name} {`);
225
- implLines.push(printConstructor(contract));
226
- implLines.push('}');
227
- return implLines;
246
+ const constructorLines = printConstructor(contract);
247
+ const freeFunctionLines = contract.freeFunctions.map(fn => printFunction(fn));
248
+
249
+ if (constructorLines.length === 0 && freeFunctionLines.length === 0) {
250
+ return [];
251
+ }
252
+
253
+ const implBlock: Lines[] = ['#[contractimpl]', `impl ${contract.name} {`];
254
+
255
+ if (constructorLines.length > 0) {
256
+ implBlock.push(constructorLines);
257
+ }
258
+
259
+ if (constructorLines.length > 0 && freeFunctionLines.length > 0) {
260
+ // Add line break between constructor and first free function
261
+ implBlock.push('');
262
+ }
263
+
264
+ if (freeFunctionLines.length > 0) {
265
+ implBlock.push(spaceBetween(...freeFunctionLines));
266
+ }
267
+
268
+ implBlock.push('}');
269
+ return implBlock;
228
270
  }
229
271
 
230
272
  function printConstructor(contract: Contract): Lines[] {
231
273
  if (contract.constructorCode.length > 0) {
232
- const head = 'pub fn __constructor';
274
+ const head = 'fn __constructor';
233
275
  const args = [getSelfArg(), ...contract.constructorArgs];
234
276
 
235
277
  const body = spaceBetween(withSemicolons(contract.constructorCode));
236
278
 
237
279
  const constructor = printFunction2(
280
+ true,
238
281
  head,
239
282
  args.map(a => printArgument(a)),
240
283
  undefined,
@@ -251,6 +294,7 @@ function printConstructor(contract: Contract): Lines[] {
251
294
  // generic for functions and constructors
252
295
  // kindedName = 'fn foo'
253
296
  function printFunction2(
297
+ pub: boolean | undefined,
254
298
  kindedName: string,
255
299
  args: string[],
256
300
  tag: string | undefined,
@@ -264,7 +308,13 @@ function printFunction2(
264
308
  fn.push(`#[${tag}]`);
265
309
  }
266
310
 
267
- let accum = `${kindedName}(`;
311
+ let accum = '';
312
+
313
+ if (pub) {
314
+ accum += 'pub ';
315
+ }
316
+
317
+ accum += `${kindedName}(`;
268
318
 
269
319
  if (args.length > 0) {
270
320
  const formattedArgs = args.join(', ');
@@ -1,4 +1,4 @@
1
- import type { BaseFunction, BaseImplementedTrait, ContractBuilder } from './contract';
1
+ import type { BaseFunction, BaseTraitImplBlock, ContractBuilder } from './contract';
2
2
 
3
3
  export const accessOptions = [false, 'ownable'] as const;
4
4
  export const DEFAULT_ACCESS_CONTROL = 'ownable';
@@ -37,7 +37,7 @@ export function setAccessControl(c: ContractBuilder, access: Access): void {
37
37
  */
38
38
  export function requireAccessControl(
39
39
  c: ContractBuilder,
40
- trait: BaseImplementedTrait,
40
+ trait: BaseTraitImplBlock | undefined,
41
41
  fn: BaseFunction,
42
42
  access: Access,
43
43
  caller?: string,
@@ -54,14 +54,13 @@ export function requireAccessControl(
54
54
  if (caller) {
55
55
  c.addUseClause('soroban_sdk', 'panic_with_error');
56
56
  c.addError('Unauthorized', 1); // TODO: Ensure there are no conflicts in error codes
57
- c.addFunctionCodeBefore(trait, fn, [
58
- getOwner,
59
- 'if owner != caller {',
60
- ` panic_with_error!(e, ${c.name}Error::Unauthorized)`,
61
- '}',
62
- ]);
57
+ c.addFunctionCodeBefore(
58
+ fn,
59
+ [getOwner, `if owner != ${caller} {`, ` panic_with_error!(e, ${c.name}Error::Unauthorized)`, '}'],
60
+ trait,
61
+ );
63
62
  } else {
64
- c.addFunctionCodeBefore(trait, fn, [getOwner, 'owner.require_auth();']);
63
+ c.addFunctionCodeBefore(fn, [getOwner, 'owner.require_auth();'], trait);
65
64
  }
66
65
  break;
67
66
  }
package/src/test.ts CHANGED
@@ -17,6 +17,10 @@ test.serial('fungible result generated', async t => {
17
17
  await testGenerate(t, 'Fungible');
18
18
  });
19
19
 
20
+ test.serial('non-fungible result generated', async t => {
21
+ await testGenerate(t, 'NonFungible');
22
+ });
23
+
20
24
  async function testGenerate(t: ExecutionContext<Context>, kind: keyof KindedOptions) {
21
25
  const generatedSourcesPath = path.join(os.tmpdir(), 'oz-wizard-stellar');
22
26
  await fs.rm(generatedSourcesPath, { force: true, recursive: true });
@@ -1,10 +1,10 @@
1
1
  /**
2
2
  * The actual latest version to use in links.
3
3
  */
4
- export const contractsVersion = '0.1.0';
4
+ export const contractsVersion = '0.2.0';
5
5
  export const contractsVersionTag = `v${contractsVersion}`;
6
6
 
7
7
  /**
8
8
  * Semantic version string representing of the minimum compatible version of Contracts to display in output.
9
9
  */
10
- export const compatibleContractsSemver = '^0.1.0';
10
+ export const compatibleContractsSemver = '^0.2.0';