@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.
- package/README.md +1 -0
- package/dist/add-pausable.js +7 -7
- package/dist/add-pausable.js.map +1 -1
- package/dist/add-upgradeable.d.ts +4 -0
- package/dist/add-upgradeable.d.ts.map +1 -0
- package/dist/add-upgradeable.js +26 -0
- package/dist/add-upgradeable.js.map +1 -0
- package/dist/api.d.ts +3 -0
- package/dist/api.d.ts.map +1 -1
- package/dist/api.js +6 -1
- package/dist/api.js.map +1 -1
- package/dist/build-generic.d.ts +4 -0
- package/dist/build-generic.d.ts.map +1 -1
- package/dist/build-generic.js +5 -2
- package/dist/build-generic.js.map +1 -1
- package/dist/contract.d.ts +22 -11
- package/dist/contract.d.ts.map +1 -1
- package/dist/contract.js +58 -12
- package/dist/contract.js.map +1 -1
- package/dist/fungible.d.ts +1 -0
- package/dist/fungible.d.ts.map +1 -1
- package/dist/fungible.js +38 -32
- package/dist/fungible.js.map +1 -1
- package/dist/generate/fungible.d.ts.map +1 -1
- package/dist/generate/fungible.js +1 -0
- package/dist/generate/fungible.js.map +1 -1
- package/dist/generate/non-fungible.d.ts +3 -0
- package/dist/generate/non-fungible.d.ts.map +1 -0
- package/dist/generate/non-fungible.js +24 -0
- package/dist/generate/non-fungible.js.map +1 -0
- package/dist/generate/sources.d.ts.map +1 -1
- package/dist/generate/sources.js +6 -0
- package/dist/generate/sources.js.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -1
- package/dist/index.js.map +1 -1
- package/dist/kind.js +2 -1
- package/dist/kind.js.map +1 -1
- package/dist/non-fungible.d.ts +17 -0
- package/dist/non-fungible.d.ts.map +1 -0
- package/dist/non-fungible.js +356 -0
- package/dist/non-fungible.js.map +1 -0
- package/dist/print.d.ts.map +1 -1
- package/dist/print.js +54 -17
- package/dist/print.js.map +1 -1
- package/dist/set-access-control.d.ts +2 -2
- package/dist/set-access-control.d.ts.map +1 -1
- package/dist/set-access-control.js +2 -7
- package/dist/set-access-control.js.map +1 -1
- package/dist/test.js +3 -0
- package/dist/test.js.map +1 -1
- package/dist/utils/version.d.ts +3 -3
- package/dist/utils/version.js +2 -2
- package/package.json +3 -4
- package/src/add-pausable.ts +7 -7
- package/src/add-upgradeable.ts +30 -0
- package/src/api.ts +8 -0
- package/src/build-generic.ts +9 -2
- package/src/contract.ts +73 -21
- package/src/fungible.ts +38 -30
- package/src/generate/fungible.ts +1 -0
- package/src/generate/non-fungible.ts +24 -0
- package/src/generate/sources.ts +7 -0
- package/src/index.ts +1 -0
- package/src/kind.ts +2 -1
- package/src/non-fungible.ts +410 -0
- package/src/print.ts +78 -28
- package/src/set-access-control.ts +8 -9
- package/src/test.ts +4 -0
- package/src/utils/version.ts +2 -2
package/src/print.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { Contract, Argument, ContractFunction,
|
|
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
|
-
|
|
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.
|
|
160
|
+
return a.traitName.localeCompare(b.traitName);
|
|
154
161
|
});
|
|
155
162
|
|
|
156
163
|
// group by section
|
|
157
|
-
const grouped = sortedTraits.reduce(
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
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
|
|
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:
|
|
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:
|
|
195
|
+
function printImplementedTrait(trait: TraitImplBlock): Lines[] {
|
|
192
196
|
const implLines = [];
|
|
193
197
|
implLines.push(...trait.tags.map(t => `#[${t}]`));
|
|
194
|
-
|
|
195
|
-
const
|
|
196
|
-
|
|
197
|
-
|
|
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
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
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 = '
|
|
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 =
|
|
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,
|
|
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:
|
|
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(
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
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(
|
|
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 });
|
package/src/utils/version.ts
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* The actual latest version to use in links.
|
|
3
3
|
*/
|
|
4
|
-
export const contractsVersion = '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.
|
|
10
|
+
export const compatibleContractsSemver = '^0.2.0';
|