@openzeppelin/wizard-stellar 0.4.3 → 0.4.5
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 +2 -2
- package/dist/add-pausable.d.ts +1 -1
- package/dist/add-pausable.d.ts.map +1 -1
- package/dist/add-pausable.js +10 -8
- package/dist/add-pausable.js.map +1 -1
- package/dist/add-upgradeable.d.ts +1 -1
- package/dist/add-upgradeable.d.ts.map +1 -1
- package/dist/add-upgradeable.js +2 -2
- package/dist/add-upgradeable.js.map +1 -1
- package/dist/common-options.d.ts +1 -0
- package/dist/common-options.d.ts.map +1 -1
- package/dist/common-options.js +4 -4
- package/dist/common-options.js.map +1 -1
- package/dist/contract.d.ts +2 -0
- package/dist/contract.d.ts.map +1 -1
- package/dist/contract.js +11 -7
- package/dist/contract.js.map +1 -1
- package/dist/fungible.d.ts +1 -1
- package/dist/fungible.d.ts.map +1 -1
- package/dist/fungible.js +43 -24
- package/dist/fungible.js.map +1 -1
- package/dist/generate/alternatives.js +1 -1
- package/dist/generate/alternatives.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.map +1 -1
- package/dist/generate/non-fungible.js +2 -0
- package/dist/generate/non-fungible.js.map +1 -1
- package/dist/generate/stablecoin.d.ts.map +1 -1
- package/dist/generate/stablecoin.js +1 -0
- package/dist/generate/stablecoin.js.map +1 -1
- package/dist/non-fungible.d.ts +2 -1
- package/dist/non-fungible.d.ts.map +1 -1
- package/dist/non-fungible.js +96 -45
- package/dist/non-fungible.js.map +1 -1
- package/dist/print.js +3 -6
- 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 +105 -8
- package/dist/set-access-control.js.map +1 -1
- package/dist/stablecoin.d.ts +2 -1
- package/dist/stablecoin.d.ts.map +1 -1
- package/dist/stablecoin.js +30 -10
- package/dist/stablecoin.js.map +1 -1
- package/dist/utils/compile-test.d.ts +1 -0
- package/dist/utils/compile-test.d.ts.map +1 -1
- package/dist/utils/compile-test.js +20 -6
- package/dist/utils/compile-test.js.map +1 -1
- package/dist/utils/define-functions.js +4 -7
- package/dist/utils/define-functions.js.map +1 -1
- package/dist/zip-rust.d.ts.map +1 -1
- package/dist/zip-rust.js +5 -1
- package/dist/zip-rust.js.map +1 -1
- package/dist/zip-shared.js +1 -1
- package/dist/zip-shared.js.map +1 -1
- package/package.json +3 -3
- package/src/add-pausable.ts +30 -15
- package/src/add-upgradeable.ts +13 -6
- package/src/common-options.ts +3 -0
- package/src/contract.ts +9 -0
- package/src/fungible.ts +54 -20
- package/src/generate/fungible.ts +1 -0
- package/src/generate/non-fungible.ts +2 -0
- package/src/generate/stablecoin.ts +1 -0
- package/src/non-fungible.ts +127 -41
- package/src/set-access-control.ts +105 -7
- package/src/stablecoin.ts +39 -9
- package/src/utils/compile-test.ts +52 -25
- package/src/zip-rust.ts +5 -0
package/src/contract.ts
CHANGED
|
@@ -185,6 +185,10 @@ export class ContractBuilder implements Contract {
|
|
|
185
185
|
}
|
|
186
186
|
}
|
|
187
187
|
|
|
188
|
+
addTraitForEachFunctions(baseTrait: BaseTraitImplBlock, functions: Record<string, BaseFunction>) {
|
|
189
|
+
Object.values(functions).forEach(fn => this.addTraitFunction(baseTrait, fn));
|
|
190
|
+
}
|
|
191
|
+
|
|
188
192
|
// used for adding a function to a trait implementation block
|
|
189
193
|
addTraitFunction(baseTrait: BaseTraitImplBlock, fn: BaseFunction): ContractFunction {
|
|
190
194
|
const t = this.addTraitImplBlock(baseTrait);
|
|
@@ -241,6 +245,11 @@ export class ContractBuilder implements Contract {
|
|
|
241
245
|
existingFn.tags = [...(existingFn.tags ?? []), tag];
|
|
242
246
|
}
|
|
243
247
|
|
|
248
|
+
setFunctionCode(fn: BaseFunction, code: string[], baseTrait?: BaseTraitImplBlock): void {
|
|
249
|
+
const existingFn = this.getOrCreateFunction(fn, baseTrait);
|
|
250
|
+
existingFn.code = [...code];
|
|
251
|
+
}
|
|
252
|
+
|
|
244
253
|
addConstructorArgument(arg: Argument): void {
|
|
245
254
|
for (const existingArg of this.constructorArgs) {
|
|
246
255
|
if (existingArg.name == arg.name) {
|
package/src/fungible.ts
CHANGED
|
@@ -11,6 +11,7 @@ import { OptionsError } from './error';
|
|
|
11
11
|
import { contractDefaults as commonDefaults } from './common-options';
|
|
12
12
|
import { printContract } from './print';
|
|
13
13
|
import { toByteArray, toUint } from './utils/convert-strings';
|
|
14
|
+
import { pickKeys } from '@openzeppelin/wizard-common';
|
|
14
15
|
|
|
15
16
|
export const defaults: Required<FungibleOptions> = {
|
|
16
17
|
name: 'MyToken',
|
|
@@ -22,6 +23,7 @@ export const defaults: Required<FungibleOptions> = {
|
|
|
22
23
|
mintable: false,
|
|
23
24
|
access: commonDefaults.access,
|
|
24
25
|
info: commonDefaults.info,
|
|
26
|
+
explicitImplementations: commonDefaults.explicitImplementations,
|
|
25
27
|
} as const;
|
|
26
28
|
|
|
27
29
|
export function printFungible(opts: FungibleOptions = defaults): string {
|
|
@@ -59,58 +61,68 @@ export function buildFungible(opts: FungibleOptions): ContractBuilder {
|
|
|
59
61
|
|
|
60
62
|
const allOpts = withDefaults(opts);
|
|
61
63
|
|
|
62
|
-
addBase(c, toByteArray(allOpts.name), toByteArray(allOpts.symbol), allOpts.pausable);
|
|
64
|
+
addBase(c, toByteArray(allOpts.name), toByteArray(allOpts.symbol), allOpts.pausable, allOpts.explicitImplementations);
|
|
63
65
|
|
|
64
66
|
if (allOpts.premint) {
|
|
65
67
|
addPremint(c, allOpts.premint);
|
|
66
68
|
}
|
|
67
69
|
|
|
68
70
|
if (allOpts.pausable) {
|
|
69
|
-
addPausable(c, allOpts.access);
|
|
71
|
+
addPausable(c, allOpts.access, allOpts.explicitImplementations);
|
|
70
72
|
}
|
|
71
73
|
|
|
72
74
|
if (allOpts.upgradeable) {
|
|
73
|
-
addUpgradeable(c, allOpts.access);
|
|
75
|
+
addUpgradeable(c, allOpts.access, allOpts.explicitImplementations);
|
|
74
76
|
}
|
|
75
77
|
|
|
76
78
|
if (allOpts.burnable) {
|
|
77
|
-
addBurnable(c, allOpts.pausable);
|
|
79
|
+
addBurnable(c, allOpts.pausable, allOpts.explicitImplementations);
|
|
78
80
|
}
|
|
79
81
|
|
|
80
82
|
if (allOpts.mintable) {
|
|
81
|
-
addMintable(c, allOpts.access, allOpts.pausable);
|
|
83
|
+
addMintable(c, allOpts.access, allOpts.pausable, allOpts.explicitImplementations);
|
|
82
84
|
}
|
|
83
85
|
|
|
84
|
-
setAccessControl(c, allOpts.access);
|
|
86
|
+
setAccessControl(c, allOpts.access, allOpts.explicitImplementations);
|
|
85
87
|
setInfo(c, allOpts.info);
|
|
86
88
|
|
|
87
89
|
return c;
|
|
88
90
|
}
|
|
89
91
|
|
|
90
|
-
function addBase(
|
|
92
|
+
function addBase(
|
|
93
|
+
c: ContractBuilder,
|
|
94
|
+
name: string,
|
|
95
|
+
symbol: string,
|
|
96
|
+
pausable: boolean,
|
|
97
|
+
explicitImplementations: boolean,
|
|
98
|
+
) {
|
|
91
99
|
// Set metadata
|
|
92
100
|
c.addConstructorCode(`Base::set_metadata(e, 18, String::from_str(e, "${name}"), String::from_str(e, "${symbol}"));`);
|
|
93
101
|
|
|
94
102
|
// Set token functions
|
|
95
103
|
c.addUseClause('stellar_tokens::fungible', 'Base');
|
|
96
104
|
c.addUseClause('stellar_tokens::fungible', 'FungibleToken');
|
|
97
|
-
c.addUseClause('stellar_macros', 'default_impl');
|
|
105
|
+
if (!explicitImplementations) c.addUseClause('stellar_macros', 'default_impl');
|
|
98
106
|
c.addUseClause('soroban_sdk', 'contract');
|
|
99
107
|
c.addUseClause('soroban_sdk', 'contractimpl');
|
|
100
108
|
c.addUseClause('soroban_sdk', 'String');
|
|
101
109
|
c.addUseClause('soroban_sdk', 'Env');
|
|
110
|
+
if (explicitImplementations || pausable) {
|
|
111
|
+
c.addUseClause('soroban_sdk', 'Address');
|
|
112
|
+
}
|
|
102
113
|
|
|
103
114
|
const fungibleTokenTrait = {
|
|
104
115
|
traitName: 'FungibleToken',
|
|
105
116
|
structName: c.name,
|
|
106
|
-
tags: ['default_impl', 'contractimpl'],
|
|
117
|
+
tags: explicitImplementations ? ['contractimpl'] : ['default_impl', 'contractimpl'],
|
|
107
118
|
assocType: 'type ContractType = Base;',
|
|
108
119
|
};
|
|
109
120
|
|
|
110
121
|
c.addTraitImplBlock(fungibleTokenTrait);
|
|
111
122
|
|
|
123
|
+
if (explicitImplementations) c.addTraitForEachFunctions(fungibleTokenTrait, fungibleTokenTraitFunctions);
|
|
124
|
+
|
|
112
125
|
if (pausable) {
|
|
113
|
-
c.addUseClause('soroban_sdk', 'Address');
|
|
114
126
|
c.addUseClause('stellar_macros', 'when_not_paused');
|
|
115
127
|
|
|
116
128
|
c.addTraitFunction(fungibleTokenTrait, functions.transfer);
|
|
@@ -121,7 +133,7 @@ function addBase(c: ContractBuilder, name: string, symbol: string, pausable: boo
|
|
|
121
133
|
}
|
|
122
134
|
}
|
|
123
135
|
|
|
124
|
-
function addMintable(c: ContractBuilder, access: Access, pausable: boolean) {
|
|
136
|
+
function addMintable(c: ContractBuilder, access: Access, pausable: boolean, explicitImplementations: boolean) {
|
|
125
137
|
c.addUseClause('soroban_sdk', 'Address');
|
|
126
138
|
switch (access) {
|
|
127
139
|
case false:
|
|
@@ -129,7 +141,7 @@ function addMintable(c: ContractBuilder, access: Access, pausable: boolean) {
|
|
|
129
141
|
case 'ownable': {
|
|
130
142
|
c.addFreeFunction(functions.mint);
|
|
131
143
|
|
|
132
|
-
requireAccessControl(c, undefined, functions.mint, access);
|
|
144
|
+
requireAccessControl(c, undefined, functions.mint, access, undefined, explicitImplementations);
|
|
133
145
|
|
|
134
146
|
if (pausable) {
|
|
135
147
|
c.addFunctionTag(functions.mint, 'when_not_paused');
|
|
@@ -139,11 +151,18 @@ function addMintable(c: ContractBuilder, access: Access, pausable: boolean) {
|
|
|
139
151
|
case 'roles': {
|
|
140
152
|
c.addFreeFunction(functions.mint_with_caller);
|
|
141
153
|
|
|
142
|
-
requireAccessControl(
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
154
|
+
requireAccessControl(
|
|
155
|
+
c,
|
|
156
|
+
undefined,
|
|
157
|
+
functions.mint_with_caller,
|
|
158
|
+
access,
|
|
159
|
+
{
|
|
160
|
+
useMacro: true,
|
|
161
|
+
caller: 'caller',
|
|
162
|
+
role: 'minter',
|
|
163
|
+
},
|
|
164
|
+
explicitImplementations,
|
|
165
|
+
);
|
|
147
166
|
|
|
148
167
|
if (pausable) {
|
|
149
168
|
c.addFunctionTag(functions.mint_with_caller, 'when_not_paused');
|
|
@@ -157,7 +176,7 @@ function addMintable(c: ContractBuilder, access: Access, pausable: boolean) {
|
|
|
157
176
|
}
|
|
158
177
|
}
|
|
159
178
|
|
|
160
|
-
function addBurnable(c: ContractBuilder, pausable: boolean) {
|
|
179
|
+
function addBurnable(c: ContractBuilder, pausable: boolean, explicitImplementations: boolean) {
|
|
161
180
|
c.addUseClause('stellar_tokens::fungible', 'burnable::FungibleBurnable');
|
|
162
181
|
c.addUseClause('soroban_sdk', 'Address');
|
|
163
182
|
|
|
@@ -176,7 +195,8 @@ function addBurnable(c: ContractBuilder, pausable: boolean) {
|
|
|
176
195
|
|
|
177
196
|
c.addTraitFunction(fungibleBurnableTrait, functions.burn_from);
|
|
178
197
|
c.addFunctionTag(functions.burn_from, 'when_not_paused', fungibleBurnableTrait);
|
|
179
|
-
} else
|
|
198
|
+
} else if (explicitImplementations) c.addTraitForEachFunctions(fungibleBurnableTrait, fungibleBurnableFunctions);
|
|
199
|
+
else {
|
|
180
200
|
// prepend '#[default_impl]'
|
|
181
201
|
fungibleBurnableTrait.tags.unshift('default_impl');
|
|
182
202
|
c.addTraitImplBlock(fungibleBurnableTrait);
|
|
@@ -204,7 +224,7 @@ function addPremint(c: ContractBuilder, amount: string) {
|
|
|
204
224
|
}
|
|
205
225
|
|
|
206
226
|
/**
|
|
207
|
-
* Calculates the initial supply that would be used in
|
|
227
|
+
* Calculates the initial supply that would be used in a Fungible contract based on a given premint amount and number of decimals.
|
|
208
228
|
*
|
|
209
229
|
* @param premint Premint amount in token units, may be fractional
|
|
210
230
|
* @param decimals The number of decimals in the token
|
|
@@ -335,3 +355,17 @@ export const functions = defineFunctions({
|
|
|
335
355
|
code: ['Base::mint(e, &account, amount);'],
|
|
336
356
|
},
|
|
337
357
|
});
|
|
358
|
+
|
|
359
|
+
const fungibleTokenTraitFunctions = pickKeys(functions, [
|
|
360
|
+
'total_supply',
|
|
361
|
+
'balance',
|
|
362
|
+
'allowance',
|
|
363
|
+
'transfer',
|
|
364
|
+
'transfer_from',
|
|
365
|
+
'approve',
|
|
366
|
+
'decimals',
|
|
367
|
+
'name',
|
|
368
|
+
'symbol',
|
|
369
|
+
]);
|
|
370
|
+
|
|
371
|
+
const fungibleBurnableFunctions = pickKeys(functions, ['burn', 'burn_from']);
|
package/src/generate/fungible.ts
CHANGED
|
@@ -8,6 +8,7 @@ const booleans = [true, false];
|
|
|
8
8
|
const blueprint = {
|
|
9
9
|
name: ['MyToken'],
|
|
10
10
|
symbol: ['MTK'],
|
|
11
|
+
tokenUri: ['https://www.mytoken.com'],
|
|
11
12
|
burnable: booleans,
|
|
12
13
|
pausable: booleans,
|
|
13
14
|
upgradeable: booleans,
|
|
@@ -17,6 +18,7 @@ const blueprint = {
|
|
|
17
18
|
mintable: booleans,
|
|
18
19
|
access: accessOptions,
|
|
19
20
|
info: infoOptions,
|
|
21
|
+
explicitImplementations: booleans,
|
|
20
22
|
};
|
|
21
23
|
|
|
22
24
|
export function* generateNonFungibleOptions(): Generator<Required<NonFungibleOptions>> {
|
package/src/non-fungible.ts
CHANGED
|
@@ -1,21 +1,22 @@
|
|
|
1
|
-
import
|
|
2
|
-
import { ContractBuilder } from './contract';
|
|
3
|
-
import { type Access, requireAccessControl, setAccessControl } from './set-access-control';
|
|
1
|
+
import { pickKeys } from '@openzeppelin/wizard-common';
|
|
4
2
|
import { addPausable } from './add-pausable';
|
|
5
3
|
import { addUpgradeable } from './add-upgradeable';
|
|
6
|
-
import { defineFunctions } from './utils/define-functions';
|
|
7
4
|
import type { CommonContractOptions } from './common-options';
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
5
|
+
import { contractDefaults as commonDefaults, getSelfArg, withCommonContractDefaults } from './common-options';
|
|
6
|
+
import type { Contract } from './contract';
|
|
7
|
+
import { ContractBuilder } from './contract';
|
|
10
8
|
import type { OptionsErrorMessages } from './error';
|
|
11
9
|
import { OptionsError } from './error';
|
|
12
|
-
import { contractDefaults as commonDefaults } from './common-options';
|
|
13
10
|
import { printContract } from './print';
|
|
11
|
+
import { type Access, DEFAULT_ACCESS_CONTROL, requireAccessControl, setAccessControl } from './set-access-control';
|
|
12
|
+
import { setInfo } from './set-info';
|
|
14
13
|
import { toByteArray } from './utils/convert-strings';
|
|
14
|
+
import { defineFunctions } from './utils/define-functions';
|
|
15
15
|
|
|
16
16
|
export const defaults: Required<NonFungibleOptions> = {
|
|
17
17
|
name: 'MyToken',
|
|
18
18
|
symbol: 'MTK',
|
|
19
|
+
tokenUri: 'https://www.mytoken.com',
|
|
19
20
|
burnable: false,
|
|
20
21
|
enumerable: false,
|
|
21
22
|
consecutive: false,
|
|
@@ -25,6 +26,7 @@ export const defaults: Required<NonFungibleOptions> = {
|
|
|
25
26
|
sequential: false,
|
|
26
27
|
access: commonDefaults.access, // TODO: Determine whether Access Control options should be visible in the UI before they are implemented as modules
|
|
27
28
|
info: commonDefaults.info,
|
|
29
|
+
explicitImplementations: commonDefaults.explicitImplementations,
|
|
28
30
|
} as const;
|
|
29
31
|
|
|
30
32
|
export function printNonFungible(opts: NonFungibleOptions = defaults): string {
|
|
@@ -34,6 +36,7 @@ export function printNonFungible(opts: NonFungibleOptions = defaults): string {
|
|
|
34
36
|
export interface NonFungibleOptions extends CommonContractOptions {
|
|
35
37
|
name: string;
|
|
36
38
|
symbol: string;
|
|
39
|
+
tokenUri?: string;
|
|
37
40
|
burnable?: boolean;
|
|
38
41
|
enumerable?: boolean;
|
|
39
42
|
consecutive?: boolean;
|
|
@@ -47,6 +50,7 @@ function withDefaults(opts: NonFungibleOptions): Required<NonFungibleOptions> {
|
|
|
47
50
|
return {
|
|
48
51
|
...opts,
|
|
49
52
|
...withCommonContractDefaults(opts),
|
|
53
|
+
tokenUri: opts.tokenUri ?? defaults.tokenUri,
|
|
50
54
|
burnable: opts.burnable ?? defaults.burnable,
|
|
51
55
|
consecutive: opts.consecutive ?? defaults.consecutive,
|
|
52
56
|
enumerable: opts.enumerable ?? defaults.enumerable,
|
|
@@ -87,41 +91,62 @@ export function buildNonFungible(opts: NonFungibleOptions): Contract {
|
|
|
87
91
|
throw new OptionsError(errors);
|
|
88
92
|
}
|
|
89
93
|
|
|
90
|
-
addBase(
|
|
94
|
+
addBase(
|
|
95
|
+
c,
|
|
96
|
+
toByteArray(allOpts.name),
|
|
97
|
+
toByteArray(allOpts.symbol),
|
|
98
|
+
toByteArray(allOpts.tokenUri),
|
|
99
|
+
allOpts.pausable,
|
|
100
|
+
allOpts.explicitImplementations,
|
|
101
|
+
);
|
|
91
102
|
|
|
92
103
|
if (allOpts.pausable) {
|
|
93
|
-
addPausable(c, allOpts.access);
|
|
104
|
+
addPausable(c, allOpts.access, allOpts.explicitImplementations);
|
|
94
105
|
}
|
|
95
106
|
|
|
96
107
|
if (allOpts.upgradeable) {
|
|
97
|
-
addUpgradeable(c, allOpts.access);
|
|
108
|
+
addUpgradeable(c, allOpts.access, allOpts.explicitImplementations);
|
|
98
109
|
}
|
|
99
110
|
|
|
100
111
|
if (allOpts.burnable) {
|
|
101
|
-
addBurnable(c, allOpts.pausable);
|
|
112
|
+
addBurnable(c, allOpts.pausable, allOpts.explicitImplementations);
|
|
102
113
|
}
|
|
103
114
|
|
|
104
115
|
if (allOpts.enumerable) {
|
|
105
|
-
addEnumerable(c);
|
|
116
|
+
addEnumerable(c, allOpts.explicitImplementations);
|
|
106
117
|
}
|
|
107
118
|
|
|
108
119
|
if (allOpts.consecutive) {
|
|
109
|
-
addConsecutive(c, allOpts.pausable, allOpts.access);
|
|
120
|
+
addConsecutive(c, allOpts.pausable, allOpts.access, allOpts.explicitImplementations);
|
|
110
121
|
}
|
|
111
122
|
|
|
112
123
|
if (allOpts.mintable) {
|
|
113
|
-
addMintable(
|
|
124
|
+
addMintable(
|
|
125
|
+
c,
|
|
126
|
+
allOpts.enumerable,
|
|
127
|
+
allOpts.pausable,
|
|
128
|
+
allOpts.sequential,
|
|
129
|
+
allOpts.access,
|
|
130
|
+
allOpts.explicitImplementations,
|
|
131
|
+
);
|
|
114
132
|
}
|
|
115
133
|
|
|
116
|
-
setAccessControl(c, allOpts.access);
|
|
134
|
+
setAccessControl(c, allOpts.access, allOpts.explicitImplementations);
|
|
117
135
|
setInfo(c, allOpts.info);
|
|
118
136
|
|
|
119
137
|
return c;
|
|
120
138
|
}
|
|
121
139
|
|
|
122
|
-
function addBase(
|
|
140
|
+
function addBase(
|
|
141
|
+
c: ContractBuilder,
|
|
142
|
+
name: string,
|
|
143
|
+
symbol: string,
|
|
144
|
+
tokenUri: string,
|
|
145
|
+
pausable: boolean,
|
|
146
|
+
explicitImplementations: boolean,
|
|
147
|
+
) {
|
|
123
148
|
// Set metadata
|
|
124
|
-
c.addConstructorCode(
|
|
149
|
+
c.addConstructorCode(`let uri = String::from_str(e, "${tokenUri}");`);
|
|
125
150
|
c.addConstructorCode(`let name = String::from_str(e, "${name}");`);
|
|
126
151
|
c.addConstructorCode(`let symbol = String::from_str(e, "${symbol}");`);
|
|
127
152
|
c.addConstructorCode(`Base::set_metadata(e, uri, name, symbol);`);
|
|
@@ -129,21 +154,25 @@ function addBase(c: ContractBuilder, name: string, symbol: string, pausable: boo
|
|
|
129
154
|
// Set token functions
|
|
130
155
|
c.addUseClause('stellar_tokens::non_fungible', 'Base');
|
|
131
156
|
c.addUseClause('stellar_tokens::non_fungible', 'NonFungibleToken');
|
|
132
|
-
c.addUseClause('
|
|
157
|
+
if (explicitImplementations) c.addUseClause('stellar_tokens::non_fungible', 'ContractOverrides');
|
|
158
|
+
else c.addUseClause('stellar_macros', 'default_impl');
|
|
133
159
|
c.addUseClause('soroban_sdk', 'contract');
|
|
134
160
|
c.addUseClause('soroban_sdk', 'contractimpl');
|
|
135
161
|
c.addUseClause('soroban_sdk', 'String');
|
|
136
162
|
c.addUseClause('soroban_sdk', 'Env');
|
|
163
|
+
if (explicitImplementations || pausable) c.addUseClause('soroban_sdk', 'Address');
|
|
137
164
|
|
|
138
165
|
const nonFungibleTokenTrait = {
|
|
139
166
|
traitName: 'NonFungibleToken',
|
|
140
167
|
structName: c.name,
|
|
141
|
-
tags: ['default_impl', 'contractimpl'],
|
|
168
|
+
tags: explicitImplementations ? ['contractimpl'] : ['default_impl', 'contractimpl'],
|
|
142
169
|
assocType: 'type ContractType = Base;',
|
|
143
170
|
};
|
|
144
171
|
|
|
145
172
|
c.addTraitImplBlock(nonFungibleTokenTrait);
|
|
146
173
|
|
|
174
|
+
if (explicitImplementations) c.addTraitForEachFunctions(nonFungibleTokenTrait, nonFungibleTokenTraitFunctions);
|
|
175
|
+
|
|
147
176
|
if (pausable) {
|
|
148
177
|
c.addUseClause('stellar_macros', 'when_not_paused');
|
|
149
178
|
|
|
@@ -155,7 +184,7 @@ function addBase(c: ContractBuilder, name: string, symbol: string, pausable: boo
|
|
|
155
184
|
}
|
|
156
185
|
}
|
|
157
186
|
|
|
158
|
-
function addBurnable(c: ContractBuilder, pausable: boolean) {
|
|
187
|
+
function addBurnable(c: ContractBuilder, pausable: boolean, explicitImplementations: boolean) {
|
|
159
188
|
c.addUseClause('stellar_tokens::non_fungible', 'burnable::NonFungibleBurnable');
|
|
160
189
|
|
|
161
190
|
const nonFungibleBurnableTrait = {
|
|
@@ -173,32 +202,38 @@ function addBurnable(c: ContractBuilder, pausable: boolean) {
|
|
|
173
202
|
|
|
174
203
|
c.addTraitFunction(nonFungibleBurnableTrait, burnableFunctions.burn_from);
|
|
175
204
|
c.addFunctionTag(burnableFunctions.burn_from, 'when_not_paused', nonFungibleBurnableTrait);
|
|
176
|
-
} else
|
|
205
|
+
} else if (explicitImplementations)
|
|
206
|
+
c.addTraitForEachFunctions(nonFungibleBurnableTrait, nonFungibleBurnableFunctions);
|
|
207
|
+
else {
|
|
177
208
|
// prepend '#[default_impl]'
|
|
178
209
|
nonFungibleBurnableTrait.tags.unshift('default_impl');
|
|
179
210
|
c.addTraitImplBlock(nonFungibleBurnableTrait);
|
|
180
211
|
}
|
|
181
212
|
}
|
|
182
213
|
|
|
183
|
-
function addEnumerable(c: ContractBuilder) {
|
|
214
|
+
function addEnumerable(c: ContractBuilder, explicitImplementations: boolean) {
|
|
184
215
|
c.addUseClause('stellar_tokens::non_fungible', 'enumerable::{NonFungibleEnumerable, Enumerable}');
|
|
185
|
-
c.addUseClause('
|
|
216
|
+
if (explicitImplementations) c.addUseClause('soroban_sdk', 'Address');
|
|
217
|
+
else c.addUseClause('stellar_macros', 'default_impl');
|
|
186
218
|
|
|
187
219
|
const nonFungibleEnumerableTrait = {
|
|
188
220
|
traitName: 'NonFungibleEnumerable',
|
|
189
221
|
structName: c.name,
|
|
190
|
-
tags: ['default_impl', 'contractimpl'],
|
|
222
|
+
tags: explicitImplementations ? ['contractimpl'] : ['default_impl', 'contractimpl'],
|
|
191
223
|
section: 'Extensions',
|
|
192
224
|
};
|
|
193
|
-
|
|
225
|
+
if (explicitImplementations)
|
|
226
|
+
c.addTraitForEachFunctions(nonFungibleEnumerableTrait, nonFungibleEnumerableTraitFunctions);
|
|
227
|
+
else c.addTraitImplBlock(nonFungibleEnumerableTrait);
|
|
194
228
|
|
|
195
229
|
c.overrideAssocType('NonFungibleToken', 'type ContractType = Enumerable;');
|
|
196
230
|
}
|
|
197
231
|
|
|
198
|
-
function addConsecutive(c: ContractBuilder, pausable: boolean, access: Access) {
|
|
232
|
+
function addConsecutive(c: ContractBuilder, pausable: boolean, access: Access, explicitImplementations: boolean) {
|
|
199
233
|
c.addUseClause('stellar_tokens::non_fungible', 'consecutive::{NonFungibleConsecutive, Consecutive}');
|
|
200
234
|
c.addUseClause('soroban_sdk', 'Address');
|
|
201
235
|
|
|
236
|
+
const effectiveAccess = access === false ? DEFAULT_ACCESS_CONTROL : access;
|
|
202
237
|
const nonFungibleConsecutiveTrait = {
|
|
203
238
|
traitName: 'NonFungibleConsecutive',
|
|
204
239
|
structName: c.name,
|
|
@@ -210,45 +245,64 @@ function addConsecutive(c: ContractBuilder, pausable: boolean, access: Access) {
|
|
|
210
245
|
|
|
211
246
|
c.overrideAssocType('NonFungibleToken', 'type ContractType = Consecutive;');
|
|
212
247
|
|
|
213
|
-
const mintFn =
|
|
248
|
+
const mintFn =
|
|
249
|
+
effectiveAccess === 'ownable' ? consecutiveFunctions.batch_mint : consecutiveFunctions.batch_mint_with_caller;
|
|
214
250
|
c.addFreeFunction(mintFn);
|
|
215
251
|
if (pausable) {
|
|
216
252
|
c.addFunctionTag(mintFn, 'when_not_paused');
|
|
217
253
|
}
|
|
218
254
|
|
|
219
|
-
requireAccessControl(
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
255
|
+
requireAccessControl(
|
|
256
|
+
c,
|
|
257
|
+
undefined,
|
|
258
|
+
mintFn,
|
|
259
|
+
effectiveAccess,
|
|
260
|
+
{
|
|
261
|
+
useMacro: true,
|
|
262
|
+
role: 'minter',
|
|
263
|
+
caller: 'caller',
|
|
264
|
+
},
|
|
265
|
+
explicitImplementations,
|
|
266
|
+
);
|
|
224
267
|
}
|
|
225
268
|
|
|
226
|
-
function addMintable(
|
|
269
|
+
function addMintable(
|
|
270
|
+
c: ContractBuilder,
|
|
271
|
+
enumerable: boolean,
|
|
272
|
+
pausable: boolean,
|
|
273
|
+
sequential: boolean,
|
|
274
|
+
access: Access,
|
|
275
|
+
explicitImplementations: boolean,
|
|
276
|
+
) {
|
|
227
277
|
c.addUseClause('soroban_sdk', 'Address');
|
|
228
278
|
const accessProps = { useMacro: true, role: 'minter', caller: 'caller' };
|
|
279
|
+
const effectiveAccess = access === false ? DEFAULT_ACCESS_CONTROL : access;
|
|
229
280
|
|
|
230
281
|
let mintFn;
|
|
231
282
|
|
|
232
283
|
if (enumerable) {
|
|
233
284
|
if (sequential) {
|
|
234
285
|
mintFn =
|
|
235
|
-
|
|
286
|
+
effectiveAccess === 'ownable'
|
|
287
|
+
? enumerableFunctions.sequential_mint
|
|
288
|
+
: enumerableFunctions.sequential_mint_with_caller;
|
|
236
289
|
} else {
|
|
237
290
|
mintFn =
|
|
238
|
-
|
|
291
|
+
effectiveAccess === 'ownable'
|
|
239
292
|
? enumerableFunctions.non_sequential_mint
|
|
240
293
|
: enumerableFunctions.non_sequential_mint_with_caller;
|
|
241
294
|
}
|
|
242
295
|
} else {
|
|
243
296
|
if (sequential) {
|
|
244
|
-
mintFn =
|
|
297
|
+
mintFn =
|
|
298
|
+
effectiveAccess === 'ownable' ? baseFunctions.sequential_mint : baseFunctions.sequential_mint_with_caller;
|
|
245
299
|
} else {
|
|
246
|
-
mintFn =
|
|
300
|
+
mintFn = effectiveAccess === 'ownable' ? baseFunctions.mint : baseFunctions.mint_with_caller;
|
|
247
301
|
}
|
|
248
302
|
}
|
|
249
303
|
|
|
250
304
|
c.addFreeFunction(mintFn);
|
|
251
|
-
requireAccessControl(c, undefined, mintFn,
|
|
305
|
+
requireAccessControl(c, undefined, mintFn, effectiveAccess, accessProps, explicitImplementations);
|
|
252
306
|
|
|
253
307
|
if (pausable) {
|
|
254
308
|
c.addFunctionTag(mintFn, 'when_not_paused');
|
|
@@ -358,6 +412,20 @@ const baseFunctions = defineFunctions({
|
|
|
358
412
|
},
|
|
359
413
|
});
|
|
360
414
|
|
|
415
|
+
const nonFungibleTokenTraitFunctions = pickKeys(baseFunctions, [
|
|
416
|
+
'balance',
|
|
417
|
+
'owner_of',
|
|
418
|
+
'transfer',
|
|
419
|
+
'transfer_from',
|
|
420
|
+
'approve',
|
|
421
|
+
'approve_for_all',
|
|
422
|
+
'get_approved',
|
|
423
|
+
'is_approved_for_all',
|
|
424
|
+
'name',
|
|
425
|
+
'symbol',
|
|
426
|
+
'token_uri',
|
|
427
|
+
]);
|
|
428
|
+
|
|
361
429
|
const burnableFunctions = defineFunctions({
|
|
362
430
|
burn: {
|
|
363
431
|
args: [getSelfArg(), { name: 'from', type: 'Address' }, { name: 'token_id', type: 'u32' }],
|
|
@@ -374,11 +442,23 @@ const burnableFunctions = defineFunctions({
|
|
|
374
442
|
},
|
|
375
443
|
});
|
|
376
444
|
|
|
445
|
+
const nonFungibleBurnableFunctions = pickKeys(burnableFunctions, ['burn', 'burn_from']);
|
|
446
|
+
|
|
377
447
|
const enumerableFunctions = defineFunctions({
|
|
378
448
|
total_supply: {
|
|
379
449
|
args: [getSelfArg()],
|
|
380
450
|
returns: 'u32',
|
|
381
|
-
code: ['
|
|
451
|
+
code: ['Enumerable::total_supply(e)'],
|
|
452
|
+
},
|
|
453
|
+
get_owner_token_id: {
|
|
454
|
+
args: [getSelfArg(), { name: 'owner', type: 'Address' }, { name: 'index', type: 'u32' }],
|
|
455
|
+
returns: 'u32',
|
|
456
|
+
code: ['Enumerable::get_owner_token_id(e, &owner, index)'],
|
|
457
|
+
},
|
|
458
|
+
get_token_id: {
|
|
459
|
+
args: [getSelfArg(), { name: 'index', type: 'u32' }],
|
|
460
|
+
returns: 'u32',
|
|
461
|
+
code: ['Enumerable::get_token_id(e, index)'],
|
|
382
462
|
},
|
|
383
463
|
non_sequential_mint: {
|
|
384
464
|
name: 'mint',
|
|
@@ -407,12 +487,18 @@ const enumerableFunctions = defineFunctions({
|
|
|
407
487
|
},
|
|
408
488
|
});
|
|
409
489
|
|
|
490
|
+
const nonFungibleEnumerableTraitFunctions = pickKeys(enumerableFunctions, [
|
|
491
|
+
'total_supply',
|
|
492
|
+
'get_owner_token_id',
|
|
493
|
+
'get_token_id',
|
|
494
|
+
]);
|
|
495
|
+
|
|
410
496
|
const consecutiveFunctions = defineFunctions({
|
|
411
497
|
batch_mint: {
|
|
412
498
|
name: 'batch_mint',
|
|
413
499
|
args: [getSelfArg(), { name: 'to', type: 'Address' }, { name: 'amount', type: 'u32' }],
|
|
414
500
|
returns: 'u32',
|
|
415
|
-
code: ['Consecutive::batch_mint(e, &to, amount)
|
|
501
|
+
code: ['Consecutive::batch_mint(e, &to, amount)'],
|
|
416
502
|
},
|
|
417
503
|
batch_mint_with_caller: {
|
|
418
504
|
name: 'batch_mint',
|
|
@@ -423,6 +509,6 @@ const consecutiveFunctions = defineFunctions({
|
|
|
423
509
|
{ name: 'caller', type: 'Address' },
|
|
424
510
|
],
|
|
425
511
|
returns: 'u32',
|
|
426
|
-
code: ['Consecutive::batch_mint(e, &to, amount)
|
|
512
|
+
code: ['Consecutive::batch_mint(e, &to, amount)'],
|
|
427
513
|
},
|
|
428
514
|
});
|