@openzeppelin/wizard-stellar 0.5.0 → 0.6.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 (92) hide show
  1. package/dist/add-upgradeable.d.ts.map +1 -1
  2. package/dist/add-upgradeable.js +15 -14
  3. package/dist/add-upgradeable.js.map +1 -1
  4. package/dist/api.d.ts +5 -2
  5. package/dist/api.d.ts.map +1 -1
  6. package/dist/api.js +7 -1
  7. package/dist/api.js.map +1 -1
  8. package/dist/build-generic.d.ts +4 -0
  9. package/dist/build-generic.d.ts.map +1 -1
  10. package/dist/build-generic.js +3 -0
  11. package/dist/build-generic.js.map +1 -1
  12. package/dist/contract.d.ts +3 -0
  13. package/dist/contract.d.ts.map +1 -1
  14. package/dist/contract.js +4 -0
  15. package/dist/contract.js.map +1 -1
  16. package/dist/fungible.d.ts +1 -0
  17. package/dist/fungible.d.ts.map +1 -1
  18. package/dist/fungible.js +74 -25
  19. package/dist/fungible.js.map +1 -1
  20. package/dist/generate/fungible.d.ts.map +1 -1
  21. package/dist/generate/fungible.js +1 -0
  22. package/dist/generate/fungible.js.map +1 -1
  23. package/dist/generate/governor.d.ts +3 -0
  24. package/dist/generate/governor.d.ts.map +1 -0
  25. package/dist/generate/governor.js +24 -0
  26. package/dist/generate/governor.js.map +1 -0
  27. package/dist/generate/non-fungible.d.ts.map +1 -1
  28. package/dist/generate/non-fungible.js +1 -0
  29. package/dist/generate/non-fungible.js.map +1 -1
  30. package/dist/generate/sources.d.ts.map +1 -1
  31. package/dist/generate/sources.js +6 -0
  32. package/dist/generate/sources.js.map +1 -1
  33. package/dist/generate/stablecoin.d.ts.map +1 -1
  34. package/dist/generate/stablecoin.js +1 -0
  35. package/dist/generate/stablecoin.js.map +1 -1
  36. package/dist/governor.d.ts +17 -0
  37. package/dist/governor.d.ts.map +1 -0
  38. package/dist/governor.js +378 -0
  39. package/dist/governor.js.map +1 -0
  40. package/dist/index.d.ts +2 -0
  41. package/dist/index.d.ts.map +1 -1
  42. package/dist/index.js +5 -3
  43. package/dist/index.js.map +1 -1
  44. package/dist/kind.js +1 -0
  45. package/dist/kind.js.map +1 -1
  46. package/dist/non-fungible.d.ts +1 -0
  47. package/dist/non-fungible.d.ts.map +1 -1
  48. package/dist/non-fungible.js +68 -7
  49. package/dist/non-fungible.js.map +1 -1
  50. package/dist/print.d.ts.map +1 -1
  51. package/dist/print.js +6 -1
  52. package/dist/print.js.map +1 -1
  53. package/dist/stablecoin.d.ts.map +1 -1
  54. package/dist/stablecoin.js +7 -0
  55. package/dist/stablecoin.js.map +1 -1
  56. package/dist/test.js +3 -0
  57. package/dist/test.js.map +1 -1
  58. package/dist/utils/compile-test.d.ts +2 -2
  59. package/dist/utils/compile-test.d.ts.map +1 -1
  60. package/dist/utils/compile-test.js +54 -3
  61. package/dist/utils/compile-test.js.map +1 -1
  62. package/dist/utils/version.d.ts +4 -4
  63. package/dist/utils/version.js +3 -3
  64. package/dist/zip-rust.d.ts.map +1 -1
  65. package/dist/zip-rust.js +3 -2
  66. package/dist/zip-rust.js.map +1 -1
  67. package/dist/zip-shared.d.ts +3 -4
  68. package/dist/zip-shared.d.ts.map +1 -1
  69. package/dist/zip-shared.js +20 -7
  70. package/dist/zip-shared.js.map +1 -1
  71. package/package.json +1 -1
  72. package/src/add-upgradeable.ts +15 -16
  73. package/src/api.ts +15 -2
  74. package/src/build-generic.ts +6 -0
  75. package/src/contract.ts +6 -0
  76. package/src/fungible.ts +93 -25
  77. package/src/generate/fungible.ts +1 -0
  78. package/src/generate/governor.ts +24 -0
  79. package/src/generate/non-fungible.ts +1 -0
  80. package/src/generate/sources.ts +7 -0
  81. package/src/generate/stablecoin.ts +1 -0
  82. package/src/governor.ts +425 -0
  83. package/src/index.ts +2 -0
  84. package/src/kind.ts +1 -0
  85. package/src/non-fungible.ts +73 -3
  86. package/src/print.ts +6 -1
  87. package/src/stablecoin.ts +8 -0
  88. package/src/test.ts +4 -0
  89. package/src/utils/compile-test.ts +84 -5
  90. package/src/utils/version.ts +3 -3
  91. package/src/zip-rust.ts +4 -2
  92. package/src/zip-shared.ts +17 -6
@@ -1,10 +1,12 @@
1
1
  import type { ExecutionContext } from 'ava';
2
2
  import { exec } from 'child_process';
3
- import { mkdir, mkdtemp, rm } from 'fs/promises';
4
- import { tmpdir } from 'os';
3
+ import { copyFile, mkdir, mkdtemp, readFile, rm, writeFile } from 'fs/promises';
4
+ import { homedir, tmpdir } from 'os';
5
5
  import path from 'path';
6
6
  import { promisify } from 'util';
7
7
  import type { GenericOptions } from '../build-generic';
8
+ import type { CommonContractOptions } from '../common-options';
9
+ import { withCommonContractDefaults } from '../common-options';
8
10
  import type { Contract } from '../contract';
9
11
  import { zipRustProject } from '../zip-rust';
10
12
  import { contractOptionsToContractName } from '../zip-shared';
@@ -18,6 +20,63 @@ export const runCargoTest = async (t: ExecutionContext, temporaryFolder: string)
18
20
  t.regex(result.stdout, /0 failed/);
19
21
  };
20
22
 
23
+ const resolvePath = (inputPath: string) =>
24
+ inputPath.startsWith('~/') ? path.join(homedir(), inputPath.slice(2)) : path.resolve(inputPath);
25
+ const toCargoPath = (inputPath: string) => inputPath.replace(/\\/g, '/');
26
+
27
+ const localDependencies = [
28
+ ['stellar-tokens', 'packages/tokens'],
29
+ ['stellar-access', 'packages/access'],
30
+ ['stellar-contract-utils', 'packages/contract-utils'],
31
+ ['stellar-governance', 'packages/governance'],
32
+ ['stellar-macros', 'packages/macros'],
33
+ ] as const;
34
+
35
+ const workspaceDependenciesPattern = /\[workspace\.dependencies\][\s\S]*?(?=\n\[profile\.release\])/;
36
+
37
+ async function rewriteWorkspaceCargoForLocalContracts(workspaceCargoPath: string, stellarContractsPath: string) {
38
+ const absoluteContractsPath = resolvePath(stellarContractsPath);
39
+ const upstreamCargoPath = path.join(absoluteContractsPath, 'Cargo.toml');
40
+ const upstreamLockPath = path.join(absoluteContractsPath, 'Cargo.lock');
41
+ const workspaceDir = path.dirname(workspaceCargoPath);
42
+
43
+ const [workspaceCargo, upstreamCargo] = await Promise.all([
44
+ readFile(workspaceCargoPath, 'utf8'),
45
+ readFile(upstreamCargoPath, 'utf8'),
46
+ ]);
47
+
48
+ const sorobanMatch = upstreamCargo.match(/^\s*soroban-sdk\s*=\s*"([^"]+)"/m);
49
+ if (sorobanMatch === null || sorobanMatch[1] === undefined) {
50
+ throw new Error(`Unable to find soroban-sdk version in ${upstreamCargoPath}`);
51
+ }
52
+
53
+ const dependencyLines = [
54
+ `soroban-sdk = "${sorobanMatch[1]}"`,
55
+ ...localDependencies.map(
56
+ ([crate, relativePath]) =>
57
+ `${crate} = { path = "${toCargoPath(path.join(absoluteContractsPath, relativePath))}" }`,
58
+ ),
59
+ ];
60
+
61
+ if (!workspaceDependenciesPattern.test(workspaceCargo)) {
62
+ throw new Error(`Unable to locate [workspace.dependencies] section in ${workspaceCargoPath}`);
63
+ }
64
+
65
+ const nextCargo = workspaceCargo.replace(
66
+ workspaceDependenciesPattern,
67
+ `[workspace.dependencies]\n${dependencyLines.join('\n')}\n`,
68
+ );
69
+
70
+ await writeFile(workspaceCargoPath, nextCargo);
71
+
72
+ // Reuse upstream lockfile when available to minimize resolver drift/offline cache misses.
73
+ try {
74
+ await copyFile(upstreamLockPath, path.join(workspaceDir, 'Cargo.lock'));
75
+ } catch {
76
+ // Ignore if lockfile is unavailable.
77
+ }
78
+ }
79
+
21
80
  type WithTemporaryFolderTestFunction<Args extends unknown[]> = (
22
81
  ...args: [...Args, ExecutionContext, string]
23
82
  ) => Promise<void> | void;
@@ -63,12 +122,21 @@ const doRunRustCompilationTest = async (
63
122
 
64
123
  assertLayout(test, zip, expandPathsFromFilesPaths(expectedZipFiles));
65
124
  await extractPackage(zip, folderPath);
125
+
126
+ if (process.env.STELLAR_CONTRACTS_PATH !== undefined) {
127
+ // Useful for release-candidate validation before crates.io publication.
128
+ await rewriteWorkspaceCargoForLocalContracts(
129
+ path.join(folderPath, 'Cargo.toml'),
130
+ process.env.STELLAR_CONTRACTS_PATH,
131
+ );
132
+ }
133
+
66
134
  await runCargoTest(test, folderPath);
67
135
 
68
136
  if (testOptions.snapshotResult) await snapshotZipContents(test, zip, expectedZipFiles);
69
137
  };
70
138
 
71
- export const runRustCompilationTest = withTemporaryFolderDo(
139
+ const _runRustCompilationTest = withTemporaryFolderDo(
72
140
  async (
73
141
  makeContract: MakeContract,
74
142
  opts: GenericOptions,
@@ -78,13 +146,16 @@ export const runRustCompilationTest = withTemporaryFolderDo(
78
146
  ) => {
79
147
  await doRunRustCompilationTest(makeContract, opts, testOptions, test, `${folderPath}/default`);
80
148
 
81
- const shouldBeExcludedOrHasAlreadyRun = testOptions.excludeExplicitTraitTest || opts.explicitImplementations;
149
+ const mergedOpts = withCommonContractDefaults(opts as GenericOptions & CommonContractOptions);
150
+ const supportsExplicitImplementations = 'explicitImplementations' in mergedOpts;
151
+ const shouldBeExcludedOrHasAlreadyRun =
152
+ testOptions.excludeExplicitTraitTest || !supportsExplicitImplementations || mergedOpts.explicitImplementations;
82
153
  if (shouldBeExcludedOrHasAlreadyRun) return;
83
154
 
84
155
  try {
85
156
  await doRunRustCompilationTest(
86
157
  makeContract,
87
- { ...opts, explicitImplementations: true },
158
+ { ...opts, explicitImplementations: true } as GenericOptions,
88
159
  testOptions,
89
160
  test,
90
161
  `${folderPath}/explicit`,
@@ -94,3 +165,11 @@ export const runRustCompilationTest = withTemporaryFolderDo(
94
165
  }
95
166
  },
96
167
  );
168
+
169
+ export function runRustCompilationTest<T extends GenericOptions>(
170
+ makeContract: (opt: T) => Contract,
171
+ opts: T,
172
+ testOptions: { snapshotResult: boolean; excludeExplicitTraitTest?: boolean },
173
+ ) {
174
+ return _runRustCompilationTest(makeContract as MakeContract, opts, testOptions);
175
+ }
@@ -1,15 +1,15 @@
1
1
  /**
2
2
  * The actual latest version to use in links.
3
3
  */
4
- export const contractsVersion = '0.6.0';
4
+ export const contractsVersion = '0.7.1';
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.6.0';
10
+ export const compatibleContractsSemver = '^0.7.1';
11
11
 
12
12
  /**
13
13
  * The Soroban version for which compilation and testing have passing tests
14
14
  */
15
- export const compatibleSorobanVersion = '23.4.0';
15
+ export const compatibleSorobanVersion = '25.3.0';
package/src/zip-rust.ts CHANGED
@@ -5,6 +5,7 @@ import { printContract, removeCreateLevelAttributes } from './print';
5
5
  import {
6
6
  contractOptionsToContractName,
7
7
  createRustLibFile,
8
+ getRequiredLibDependencies,
8
9
  printContractCargo,
9
10
  printRustNameTest,
10
11
  workspaceCargo,
@@ -33,12 +34,13 @@ export const createRustZipEnvironment = (c: Contract, opts: GenericOptions) => {
33
34
  const zip = new JSZip();
34
35
 
35
36
  const contractName = contractOptionsToContractName(opts?.kind || 'contract');
37
+ const requiredLibDeps = getRequiredLibDependencies(c);
36
38
 
37
39
  zip.file(`contracts/${contractName}/src/contract.rs`, removeCreateLevelAttributes(printContract(c)));
38
40
  zip.file(`contracts/${contractName}/src/test.rs`, printRustNameTest(c));
39
41
  zip.file(`contracts/${contractName}/src/lib.rs`, createRustLibFile);
40
- zip.file(`contracts/${contractName}/Cargo.toml`, printContractCargo(contractName));
41
- zip.file('Cargo.toml', workspaceCargo);
42
+ zip.file(`contracts/${contractName}/Cargo.toml`, printContractCargo(contractName, requiredLibDeps));
43
+ zip.file('Cargo.toml', workspaceCargo(requiredLibDeps));
42
44
  zip.file('.gitignore', gitIgnore);
43
45
 
44
46
  return zip;
package/src/zip-shared.ts CHANGED
@@ -39,19 +39,30 @@ fn initial_state() {
39
39
  // Add more tests bellow
40
40
  `;
41
41
 
42
- export const libDependencies = [
42
+ const libDependencies = [
43
43
  'stellar-tokens',
44
44
  'stellar-access',
45
45
  'stellar-contract-utils',
46
+ 'stellar-governance',
46
47
  'stellar-macros',
47
48
  ] as const;
48
49
 
49
- export const allDependencies = [...libDependencies, 'soroban-sdk'] as const;
50
+ // Derives required lib crate dependencies from the contract's use clauses.
51
+ // Each use clause has a containerPath like "stellar_tokens::fungible::Base".
52
+ // We extract the first segment (the crate name), convert underscores to hyphens
53
+ // to match Cargo naming (e.g., stellar_tokens -> stellar-tokens), then filter
54
+ // libDependencies to include only crates the contract actually references.
55
+ // Filtering against the known list preserves stable ordering and ignores
56
+ // non-lib crates like soroban_sdk (which is always added separately).
57
+ export function getRequiredLibDependencies(c: Pick<Contract, 'useClauses'>): string[] {
58
+ const usedCrates = new Set(c.useClauses.map(uc => uc.containerPath.split('::')[0]!.replace(/_/g, '-')));
59
+ return libDependencies.filter(dep => usedCrates.has(dep));
60
+ }
50
61
 
51
62
  export const addDependenciesWith = (dependencyValue: string, dependenciesToAdd: string[]) =>
52
63
  `${dependenciesToAdd.map(dependency => `${dependency} = ${dependencyValue}\n`).join('')}`;
53
64
 
54
- export const printContractCargo = (scaffoldContractName: string) => `[package]
65
+ export const printContractCargo = (scaffoldContractName: string, requiredLibDeps: readonly string[]) => `[package]
55
66
  name = "${scaffoldContractName.replace(/_/, '-')}-contract"
56
67
  edition.workspace = true
57
68
  license.workspace = true
@@ -66,7 +77,7 @@ crate-type = ["cdylib"]
66
77
  doctest = false
67
78
 
68
79
  [dependencies]
69
- ${addDependenciesWith('{ workspace = true }', [...allDependencies])}
80
+ ${addDependenciesWith('{ workspace = true }', [...requiredLibDeps, 'soroban-sdk'])}
70
81
  [dev-dependencies]
71
82
  ${addDependenciesWith('{ workspace = true, features = ["testutils"] }', ['soroban-sdk'])}`;
72
83
 
@@ -77,7 +88,7 @@ mod contract;
77
88
  mod test;
78
89
  `;
79
90
 
80
- export const workspaceCargo = `[workspace]
91
+ export const workspaceCargo = (requiredLibDeps: readonly string[]) => `[workspace]
81
92
  resolver = "2"
82
93
  members = ["contracts/*"]
83
94
 
@@ -88,7 +99,7 @@ license = "Apache-2.0"
88
99
  version = "0.0.1"
89
100
 
90
101
  [workspace.dependencies]
91
- ${addDependenciesWith(`"${compatibleSorobanVersion}"`, ['soroban-sdk'])}${addDependenciesWith(`"=${contractsVersion}"`, [...libDependencies])}
102
+ ${addDependenciesWith(`"${compatibleSorobanVersion}"`, ['soroban-sdk'])}${addDependenciesWith(`"=${contractsVersion}"`, [...requiredLibDeps])}
92
103
 
93
104
  [profile.release]
94
105
  opt-level = "z"