@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.
- package/dist/add-upgradeable.d.ts.map +1 -1
- package/dist/add-upgradeable.js +15 -14
- package/dist/add-upgradeable.js.map +1 -1
- package/dist/api.d.ts +5 -2
- package/dist/api.d.ts.map +1 -1
- package/dist/api.js +7 -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 +3 -0
- package/dist/build-generic.js.map +1 -1
- package/dist/contract.d.ts +3 -0
- package/dist/contract.d.ts.map +1 -1
- package/dist/contract.js +4 -0
- 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 +74 -25
- 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/governor.d.ts +3 -0
- package/dist/generate/governor.d.ts.map +1 -0
- package/dist/generate/governor.js +24 -0
- package/dist/generate/governor.js.map +1 -0
- package/dist/generate/non-fungible.d.ts.map +1 -1
- package/dist/generate/non-fungible.js +1 -0
- package/dist/generate/non-fungible.js.map +1 -1
- 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/generate/stablecoin.d.ts.map +1 -1
- package/dist/generate/stablecoin.js +1 -0
- package/dist/generate/stablecoin.js.map +1 -1
- package/dist/governor.d.ts +17 -0
- package/dist/governor.d.ts.map +1 -0
- package/dist/governor.js +378 -0
- package/dist/governor.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +5 -3
- package/dist/index.js.map +1 -1
- package/dist/kind.js +1 -0
- package/dist/kind.js.map +1 -1
- package/dist/non-fungible.d.ts +1 -0
- package/dist/non-fungible.d.ts.map +1 -1
- package/dist/non-fungible.js +68 -7
- package/dist/non-fungible.js.map +1 -1
- package/dist/print.d.ts.map +1 -1
- package/dist/print.js +6 -1
- package/dist/print.js.map +1 -1
- package/dist/stablecoin.d.ts.map +1 -1
- package/dist/stablecoin.js +7 -0
- package/dist/stablecoin.js.map +1 -1
- package/dist/test.js +3 -0
- package/dist/test.js.map +1 -1
- package/dist/utils/compile-test.d.ts +2 -2
- package/dist/utils/compile-test.d.ts.map +1 -1
- package/dist/utils/compile-test.js +54 -3
- package/dist/utils/compile-test.js.map +1 -1
- package/dist/utils/version.d.ts +4 -4
- package/dist/utils/version.js +3 -3
- package/dist/zip-rust.d.ts.map +1 -1
- package/dist/zip-rust.js +3 -2
- package/dist/zip-rust.js.map +1 -1
- package/dist/zip-shared.d.ts +3 -4
- package/dist/zip-shared.d.ts.map +1 -1
- package/dist/zip-shared.js +20 -7
- package/dist/zip-shared.js.map +1 -1
- package/package.json +1 -1
- package/src/add-upgradeable.ts +15 -16
- package/src/api.ts +15 -2
- package/src/build-generic.ts +6 -0
- package/src/contract.ts +6 -0
- package/src/fungible.ts +93 -25
- package/src/generate/fungible.ts +1 -0
- package/src/generate/governor.ts +24 -0
- package/src/generate/non-fungible.ts +1 -0
- package/src/generate/sources.ts +7 -0
- package/src/generate/stablecoin.ts +1 -0
- package/src/governor.ts +425 -0
- package/src/index.ts +2 -0
- package/src/kind.ts +1 -0
- package/src/non-fungible.ts +73 -3
- package/src/print.ts +6 -1
- package/src/stablecoin.ts +8 -0
- package/src/test.ts +4 -0
- package/src/utils/compile-test.ts +84 -5
- package/src/utils/version.ts +3 -3
- package/src/zip-rust.ts +4 -2
- package/src/zip-shared.ts +17 -6
package/dist/zip-shared.js
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.workspaceCargo = exports.createRustLibFile = exports.printContractCargo = exports.addDependenciesWith = exports.
|
|
3
|
+
exports.workspaceCargo = exports.createRustLibFile = exports.printContractCargo = exports.addDependenciesWith = exports.printRustNameTest = exports.contractOptionsToContractName = void 0;
|
|
4
4
|
exports.getAddressArgs = getAddressArgs;
|
|
5
|
+
exports.getRequiredLibDependencies = getRequiredLibDependencies;
|
|
5
6
|
const version_1 = require("./utils/version");
|
|
6
7
|
function pascalToSnakeCase(string) {
|
|
7
8
|
return string
|
|
@@ -38,16 +39,27 @@ fn initial_state() {
|
|
|
38
39
|
// Add more tests bellow
|
|
39
40
|
`;
|
|
40
41
|
exports.printRustNameTest = printRustNameTest;
|
|
41
|
-
|
|
42
|
+
const libDependencies = [
|
|
42
43
|
'stellar-tokens',
|
|
43
44
|
'stellar-access',
|
|
44
45
|
'stellar-contract-utils',
|
|
46
|
+
'stellar-governance',
|
|
45
47
|
'stellar-macros',
|
|
46
48
|
];
|
|
47
|
-
|
|
49
|
+
// Derives required lib crate dependencies from the contract's use clauses.
|
|
50
|
+
// Each use clause has a containerPath like "stellar_tokens::fungible::Base".
|
|
51
|
+
// We extract the first segment (the crate name), convert underscores to hyphens
|
|
52
|
+
// to match Cargo naming (e.g., stellar_tokens -> stellar-tokens), then filter
|
|
53
|
+
// libDependencies to include only crates the contract actually references.
|
|
54
|
+
// Filtering against the known list preserves stable ordering and ignores
|
|
55
|
+
// non-lib crates like soroban_sdk (which is always added separately).
|
|
56
|
+
function getRequiredLibDependencies(c) {
|
|
57
|
+
const usedCrates = new Set(c.useClauses.map(uc => uc.containerPath.split('::')[0].replace(/_/g, '-')));
|
|
58
|
+
return libDependencies.filter(dep => usedCrates.has(dep));
|
|
59
|
+
}
|
|
48
60
|
const addDependenciesWith = (dependencyValue, dependenciesToAdd) => `${dependenciesToAdd.map(dependency => `${dependency} = ${dependencyValue}\n`).join('')}`;
|
|
49
61
|
exports.addDependenciesWith = addDependenciesWith;
|
|
50
|
-
const printContractCargo = (scaffoldContractName) => `[package]
|
|
62
|
+
const printContractCargo = (scaffoldContractName, requiredLibDeps) => `[package]
|
|
51
63
|
name = "${scaffoldContractName.replace(/_/, '-')}-contract"
|
|
52
64
|
edition.workspace = true
|
|
53
65
|
license.workspace = true
|
|
@@ -62,7 +74,7 @@ crate-type = ["cdylib"]
|
|
|
62
74
|
doctest = false
|
|
63
75
|
|
|
64
76
|
[dependencies]
|
|
65
|
-
${(0, exports.addDependenciesWith)('{ workspace = true }', [...
|
|
77
|
+
${(0, exports.addDependenciesWith)('{ workspace = true }', [...requiredLibDeps, 'soroban-sdk'])}
|
|
66
78
|
[dev-dependencies]
|
|
67
79
|
${(0, exports.addDependenciesWith)('{ workspace = true, features = ["testutils"] }', ['soroban-sdk'])}`;
|
|
68
80
|
exports.printContractCargo = printContractCargo;
|
|
@@ -72,7 +84,7 @@ exports.createRustLibFile = `#![no_std]
|
|
|
72
84
|
mod contract;
|
|
73
85
|
mod test;
|
|
74
86
|
`;
|
|
75
|
-
|
|
87
|
+
const workspaceCargo = (requiredLibDeps) => `[workspace]
|
|
76
88
|
resolver = "2"
|
|
77
89
|
members = ["contracts/*"]
|
|
78
90
|
|
|
@@ -83,7 +95,7 @@ license = "Apache-2.0"
|
|
|
83
95
|
version = "0.0.1"
|
|
84
96
|
|
|
85
97
|
[workspace.dependencies]
|
|
86
|
-
${(0, exports.addDependenciesWith)(`"${version_1.compatibleSorobanVersion}"`, ['soroban-sdk'])}${(0, exports.addDependenciesWith)(`"=${version_1.contractsVersion}"`, [...
|
|
98
|
+
${(0, exports.addDependenciesWith)(`"${version_1.compatibleSorobanVersion}"`, ['soroban-sdk'])}${(0, exports.addDependenciesWith)(`"=${version_1.contractsVersion}"`, [...requiredLibDeps])}
|
|
87
99
|
|
|
88
100
|
[profile.release]
|
|
89
101
|
opt-level = "z"
|
|
@@ -99,4 +111,5 @@ lto = true
|
|
|
99
111
|
inherits = "release"
|
|
100
112
|
debug-assertions = true
|
|
101
113
|
`;
|
|
114
|
+
exports.workspaceCargo = workspaceCargo;
|
|
102
115
|
//# sourceMappingURL=zip-shared.js.map
|
package/dist/zip-shared.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"zip-shared.js","sourceRoot":"","sources":["../src/zip-shared.ts"],"names":[],"mappings":";;;AAYA,wCAIC;
|
|
1
|
+
{"version":3,"file":"zip-shared.js","sourceRoot":"","sources":["../src/zip-shared.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@openzeppelin/wizard-stellar",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.6.0",
|
|
4
4
|
"description": "A boilerplate generator to get started with OpenZeppelin Stellar Soroban Contracts",
|
|
5
5
|
"license": "AGPL-3.0-only",
|
|
6
6
|
"repository": "https://github.com/OpenZeppelin/contracts-wizard",
|
package/src/add-upgradeable.ts
CHANGED
|
@@ -6,31 +6,30 @@ import { defineFunctions } from './utils/define-functions';
|
|
|
6
6
|
|
|
7
7
|
export function addUpgradeable(c: ContractBuilder, access: Access, explicitImplementations: boolean) {
|
|
8
8
|
const functions = defineFunctions({
|
|
9
|
-
|
|
10
|
-
args: [getSelfArg(), { name: 'operator', type: '
|
|
11
|
-
code: ['
|
|
9
|
+
upgrade: {
|
|
10
|
+
args: [getSelfArg(), { name: 'new_wasm_hash', type: 'BytesN<32>' }, { name: 'operator', type: 'Address' }],
|
|
11
|
+
code: ['upgradeable::upgrade(e, &new_wasm_hash)'],
|
|
12
12
|
},
|
|
13
|
-
|
|
14
|
-
name: '
|
|
15
|
-
args: [getSelfArg(), { name: '_operator', type: '
|
|
16
|
-
code: [],
|
|
13
|
+
upgrade_unused_operator: {
|
|
14
|
+
name: 'upgrade',
|
|
15
|
+
args: [getSelfArg(), { name: 'new_wasm_hash', type: 'BytesN<32>' }, { name: '_operator', type: 'Address' }],
|
|
16
|
+
code: ['upgradeable::upgrade(e, &new_wasm_hash)'],
|
|
17
17
|
},
|
|
18
18
|
});
|
|
19
19
|
|
|
20
|
-
c.addUseClause('
|
|
21
|
-
c.addUseClause('
|
|
22
|
-
|
|
23
|
-
c.
|
|
20
|
+
c.addUseClause('soroban_sdk', 'Address');
|
|
21
|
+
c.addUseClause('soroban_sdk', 'BytesN');
|
|
22
|
+
c.addUseClause('stellar_contract_utils::upgradeable', 'self', { alias: 'upgradeable' });
|
|
23
|
+
c.addUseClause('stellar_contract_utils::upgradeable', 'Upgradeable');
|
|
24
24
|
|
|
25
25
|
const upgradeableTrait = {
|
|
26
|
-
traitName: '
|
|
26
|
+
traitName: 'Upgradeable',
|
|
27
27
|
structName: c.name,
|
|
28
|
-
tags: [],
|
|
28
|
+
tags: ['contractimpl'],
|
|
29
29
|
section: 'Utils',
|
|
30
30
|
};
|
|
31
31
|
|
|
32
|
-
const upgradeFn: BaseFunction =
|
|
33
|
-
access === 'ownable' ? functions._require_auth_unused_operator : functions._require_auth;
|
|
32
|
+
const upgradeFn: BaseFunction = access === 'ownable' ? functions.upgrade_unused_operator : functions.upgrade;
|
|
34
33
|
|
|
35
34
|
c.addTraitFunction(upgradeableTrait, upgradeFn);
|
|
36
35
|
|
|
@@ -40,7 +39,7 @@ export function addUpgradeable(c: ContractBuilder, access: Access, explicitImple
|
|
|
40
39
|
upgradeFn,
|
|
41
40
|
access,
|
|
42
41
|
{
|
|
43
|
-
useMacro:
|
|
42
|
+
useMacro: true,
|
|
44
43
|
role: 'upgrader',
|
|
45
44
|
caller: 'operator',
|
|
46
45
|
},
|
package/src/api.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import type { CommonContractOptions } from './common-options';
|
|
1
|
+
import type { CommonContractOptions, CommonOptions } from './common-options';
|
|
2
2
|
import type { FungibleOptions } from './fungible';
|
|
3
|
+
import type { GovernorOptions } from './governor';
|
|
3
4
|
import type { NonFungibleOptions } from './non-fungible';
|
|
4
5
|
import type { StablecoinOptions } from './stablecoin';
|
|
5
6
|
import {
|
|
@@ -12,13 +13,18 @@ import {
|
|
|
12
13
|
defaults as fungibledefaults,
|
|
13
14
|
isAccessControlRequired as fungibleIsAccessControlRequired,
|
|
14
15
|
} from './fungible';
|
|
16
|
+
import {
|
|
17
|
+
printGovernor,
|
|
18
|
+
defaults as governorDefaults,
|
|
19
|
+
isAccessControlRequired as governorIsAccessControlRequired,
|
|
20
|
+
} from './governor';
|
|
15
21
|
import {
|
|
16
22
|
printNonFungible,
|
|
17
23
|
defaults as nonFungibledefaults,
|
|
18
24
|
isAccessControlRequired as nonFungibleIsAccessControlRequired,
|
|
19
25
|
} from './non-fungible';
|
|
20
26
|
|
|
21
|
-
export interface WizardContractAPI<Options extends
|
|
27
|
+
export interface WizardContractAPI<Options extends CommonOptions> {
|
|
22
28
|
/**
|
|
23
29
|
* Returns a string representation of a contract generated using the provided options. If opts is not provided, uses `defaults`.
|
|
24
30
|
*/
|
|
@@ -39,6 +45,7 @@ export interface AccessControlAPI<Options extends CommonContractOptions> {
|
|
|
39
45
|
}
|
|
40
46
|
|
|
41
47
|
export type Fungible = WizardContractAPI<FungibleOptions> & AccessControlAPI<FungibleOptions>;
|
|
48
|
+
export type Governor = WizardContractAPI<GovernorOptions> & AccessControlAPI<GovernorOptions>;
|
|
42
49
|
export type NonFungible = WizardContractAPI<NonFungibleOptions> & AccessControlAPI<NonFungibleOptions>;
|
|
43
50
|
export type Stablecoin = WizardContractAPI<StablecoinOptions> & AccessControlAPI<StablecoinOptions>;
|
|
44
51
|
|
|
@@ -48,6 +55,12 @@ export const fungible: Fungible = {
|
|
|
48
55
|
isAccessControlRequired: fungibleIsAccessControlRequired,
|
|
49
56
|
};
|
|
50
57
|
|
|
58
|
+
export const governor: Governor = {
|
|
59
|
+
print: printGovernor,
|
|
60
|
+
defaults: governorDefaults,
|
|
61
|
+
isAccessControlRequired: governorIsAccessControlRequired,
|
|
62
|
+
};
|
|
63
|
+
|
|
51
64
|
export const nonFungible: NonFungible = {
|
|
52
65
|
print: printNonFungible,
|
|
53
66
|
defaults: nonFungibledefaults,
|
package/src/build-generic.ts
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import type { FungibleOptions } from './fungible';
|
|
2
2
|
import { buildFungible } from './fungible';
|
|
3
|
+
import type { GovernorOptions } from './governor';
|
|
4
|
+
import { buildGovernor } from './governor';
|
|
3
5
|
import type { NonFungibleOptions } from './non-fungible';
|
|
4
6
|
import { buildNonFungible } from './non-fungible';
|
|
5
7
|
import type { StablecoinOptions } from './stablecoin';
|
|
@@ -7,6 +9,7 @@ import { buildStablecoin } from './stablecoin';
|
|
|
7
9
|
|
|
8
10
|
export interface KindedOptions {
|
|
9
11
|
Fungible: { kind: 'Fungible' } & FungibleOptions;
|
|
12
|
+
Governor: { kind: 'Governor' } & GovernorOptions;
|
|
10
13
|
NonFungible: { kind: 'NonFungible' } & NonFungibleOptions;
|
|
11
14
|
Stablecoin: { kind: 'Stablecoin' } & StablecoinOptions;
|
|
12
15
|
}
|
|
@@ -18,6 +21,9 @@ export function buildGeneric(opts: GenericOptions) {
|
|
|
18
21
|
case 'Fungible':
|
|
19
22
|
return buildFungible(opts);
|
|
20
23
|
|
|
24
|
+
case 'Governor':
|
|
25
|
+
return buildGovernor(opts);
|
|
26
|
+
|
|
21
27
|
case 'NonFungible':
|
|
22
28
|
return buildNonFungible(opts);
|
|
23
29
|
|
package/src/contract.ts
CHANGED
|
@@ -10,6 +10,7 @@ export interface Contract {
|
|
|
10
10
|
constructorArgs: Argument[];
|
|
11
11
|
implementedTraits: TraitImplBlock[];
|
|
12
12
|
freeFunctions: ContractFunction[];
|
|
13
|
+
topLevelDeclarations: string[][];
|
|
13
14
|
variables: Variable[];
|
|
14
15
|
errors: Error[];
|
|
15
16
|
ownable: boolean;
|
|
@@ -81,6 +82,7 @@ export class ContractBuilder implements Contract {
|
|
|
81
82
|
|
|
82
83
|
readonly constructorArgs: Argument[] = [];
|
|
83
84
|
readonly constructorCode: string[] = [];
|
|
85
|
+
readonly topLevelDeclarations: string[][] = [];
|
|
84
86
|
|
|
85
87
|
private implementedTraitsMap: Map<string, TraitImplBlock> = new Map();
|
|
86
88
|
private freeFunctionsMap: Map<string, ContractFunction> = new Map();
|
|
@@ -250,6 +252,10 @@ export class ContractBuilder implements Contract {
|
|
|
250
252
|
existingFn.code = [...code];
|
|
251
253
|
}
|
|
252
254
|
|
|
255
|
+
addTopLevelDeclaration(lines: string[]): void {
|
|
256
|
+
this.topLevelDeclarations.push(lines);
|
|
257
|
+
}
|
|
258
|
+
|
|
253
259
|
addConstructorArgument(arg: Argument): void {
|
|
254
260
|
for (const existingArg of this.constructorArgs) {
|
|
255
261
|
if (existingArg.name == arg.name) {
|
package/src/fungible.ts
CHANGED
|
@@ -17,6 +17,7 @@ export const defaults: Required<FungibleOptions> = {
|
|
|
17
17
|
name: 'MyToken',
|
|
18
18
|
symbol: 'MTK',
|
|
19
19
|
burnable: false,
|
|
20
|
+
votes: false,
|
|
20
21
|
pausable: false,
|
|
21
22
|
upgradeable: false,
|
|
22
23
|
premint: '0',
|
|
@@ -34,6 +35,7 @@ export interface FungibleOptions extends CommonContractOptions {
|
|
|
34
35
|
name: string;
|
|
35
36
|
symbol: string;
|
|
36
37
|
burnable?: boolean;
|
|
38
|
+
votes?: boolean;
|
|
37
39
|
pausable?: boolean;
|
|
38
40
|
upgradeable?: boolean;
|
|
39
41
|
premint?: string;
|
|
@@ -45,6 +47,7 @@ export function withDefaults(opts: FungibleOptions): Required<FungibleOptions> {
|
|
|
45
47
|
...opts,
|
|
46
48
|
...withCommonContractDefaults(opts),
|
|
47
49
|
burnable: opts.burnable ?? defaults.burnable,
|
|
50
|
+
votes: opts.votes ?? defaults.votes,
|
|
48
51
|
pausable: opts.pausable ?? defaults.pausable,
|
|
49
52
|
upgradeable: opts.upgradeable ?? defaults.upgradeable,
|
|
50
53
|
premint: opts.premint || defaults.premint,
|
|
@@ -61,10 +64,17 @@ export function buildFungible(opts: FungibleOptions): ContractBuilder {
|
|
|
61
64
|
|
|
62
65
|
const allOpts = withDefaults(opts);
|
|
63
66
|
|
|
64
|
-
addBase(
|
|
67
|
+
addBase(
|
|
68
|
+
c,
|
|
69
|
+
toByteArray(allOpts.name),
|
|
70
|
+
toByteArray(allOpts.symbol),
|
|
71
|
+
allOpts.votes,
|
|
72
|
+
allOpts.pausable,
|
|
73
|
+
allOpts.explicitImplementations,
|
|
74
|
+
);
|
|
65
75
|
|
|
66
76
|
if (allOpts.premint) {
|
|
67
|
-
addPremint(c, allOpts.premint);
|
|
77
|
+
addPremint(c, allOpts.premint, allOpts.votes);
|
|
68
78
|
}
|
|
69
79
|
|
|
70
80
|
if (allOpts.pausable) {
|
|
@@ -76,11 +86,11 @@ export function buildFungible(opts: FungibleOptions): ContractBuilder {
|
|
|
76
86
|
}
|
|
77
87
|
|
|
78
88
|
if (allOpts.burnable) {
|
|
79
|
-
addBurnable(c, allOpts.pausable, allOpts.explicitImplementations);
|
|
89
|
+
addBurnable(c, allOpts.votes, allOpts.pausable, allOpts.explicitImplementations);
|
|
80
90
|
}
|
|
81
91
|
|
|
82
92
|
if (allOpts.mintable) {
|
|
83
|
-
addMintable(c, allOpts.access, allOpts.pausable, allOpts.explicitImplementations);
|
|
93
|
+
addMintable(c, allOpts.access, allOpts.votes, allOpts.pausable, allOpts.explicitImplementations);
|
|
84
94
|
}
|
|
85
95
|
|
|
86
96
|
setAccessControl(c, allOpts.access, allOpts.explicitImplementations);
|
|
@@ -93,6 +103,7 @@ function addBase(
|
|
|
93
103
|
c: ContractBuilder,
|
|
94
104
|
name: string,
|
|
95
105
|
symbol: string,
|
|
106
|
+
votes: boolean,
|
|
96
107
|
pausable: boolean,
|
|
97
108
|
explicitImplementations: boolean,
|
|
98
109
|
) {
|
|
@@ -102,6 +113,11 @@ function addBase(
|
|
|
102
113
|
// Set token functions
|
|
103
114
|
c.addUseClause('stellar_tokens::fungible', 'Base');
|
|
104
115
|
c.addUseClause('stellar_tokens::fungible', 'FungibleToken');
|
|
116
|
+
if (votes) {
|
|
117
|
+
c.addUseClause('stellar_tokens::fungible', 'ContractOverrides');
|
|
118
|
+
c.addUseClause('stellar_governance::votes', 'Votes');
|
|
119
|
+
c.addUseClause('stellar_tokens::fungible', 'votes::FungibleVotes');
|
|
120
|
+
}
|
|
105
121
|
c.addUseClause('soroban_sdk', 'contract');
|
|
106
122
|
c.addUseClause('soroban_sdk', 'contractimpl');
|
|
107
123
|
c.addUseClause('soroban_sdk', 'String');
|
|
@@ -115,7 +131,7 @@ function addBase(
|
|
|
115
131
|
traitName: 'FungibleToken',
|
|
116
132
|
structName: c.name,
|
|
117
133
|
tags: explicitImplementations ? ['contractimpl'] : ['contractimpl(contracttrait)'],
|
|
118
|
-
assocType:
|
|
134
|
+
assocType: `type ContractType = ${votes ? 'FungibleVotes' : 'Base'};`,
|
|
119
135
|
};
|
|
120
136
|
|
|
121
137
|
c.addTraitImplBlock(fungibleTokenTrait);
|
|
@@ -131,29 +147,47 @@ function addBase(
|
|
|
131
147
|
c.addTraitFunction(fungibleTokenTrait, functions.transfer_from);
|
|
132
148
|
c.addFunctionTag(functions.transfer_from, 'when_not_paused', fungibleTokenTrait);
|
|
133
149
|
}
|
|
150
|
+
|
|
151
|
+
if (votes) {
|
|
152
|
+
c.addTraitImplBlock({
|
|
153
|
+
traitName: 'Votes',
|
|
154
|
+
structName: c.name,
|
|
155
|
+
tags: explicitImplementations ? ['contractimpl'] : ['contractimpl(contracttrait)'],
|
|
156
|
+
section: 'Extensions',
|
|
157
|
+
});
|
|
158
|
+
}
|
|
134
159
|
}
|
|
135
160
|
|
|
136
|
-
function addMintable(
|
|
161
|
+
function addMintable(
|
|
162
|
+
c: ContractBuilder,
|
|
163
|
+
access: Access,
|
|
164
|
+
votes: boolean,
|
|
165
|
+
pausable: boolean,
|
|
166
|
+
explicitImplementations: boolean,
|
|
167
|
+
) {
|
|
168
|
+
const mintFn = votes ? votesFunctions.mint : functions.mint;
|
|
169
|
+
const mintWithCallerFn = votes ? votesFunctions.mint_with_caller : functions.mint_with_caller;
|
|
170
|
+
|
|
137
171
|
switch (access) {
|
|
138
172
|
case false:
|
|
139
173
|
break;
|
|
140
174
|
case 'ownable': {
|
|
141
|
-
c.addFreeFunction(
|
|
175
|
+
c.addFreeFunction(mintFn);
|
|
142
176
|
|
|
143
|
-
requireAccessControl(c, undefined,
|
|
177
|
+
requireAccessControl(c, undefined, mintFn, access, undefined, explicitImplementations);
|
|
144
178
|
|
|
145
179
|
if (pausable) {
|
|
146
|
-
c.addFunctionTag(
|
|
180
|
+
c.addFunctionTag(mintFn, 'when_not_paused');
|
|
147
181
|
}
|
|
148
182
|
break;
|
|
149
183
|
}
|
|
150
184
|
case 'roles': {
|
|
151
|
-
c.addFreeFunction(
|
|
185
|
+
c.addFreeFunction(mintWithCallerFn);
|
|
152
186
|
|
|
153
187
|
requireAccessControl(
|
|
154
188
|
c,
|
|
155
189
|
undefined,
|
|
156
|
-
|
|
190
|
+
mintWithCallerFn,
|
|
157
191
|
access,
|
|
158
192
|
{
|
|
159
193
|
useMacro: true,
|
|
@@ -164,7 +198,7 @@ function addMintable(c: ContractBuilder, access: Access, pausable: boolean, expl
|
|
|
164
198
|
);
|
|
165
199
|
|
|
166
200
|
if (pausable) {
|
|
167
|
-
c.addFunctionTag(
|
|
201
|
+
c.addFunctionTag(mintWithCallerFn, 'when_not_paused');
|
|
168
202
|
}
|
|
169
203
|
break;
|
|
170
204
|
}
|
|
@@ -175,7 +209,7 @@ function addMintable(c: ContractBuilder, access: Access, pausable: boolean, expl
|
|
|
175
209
|
}
|
|
176
210
|
}
|
|
177
211
|
|
|
178
|
-
function addBurnable(c: ContractBuilder, pausable: boolean, explicitImplementations: boolean) {
|
|
212
|
+
function addBurnable(c: ContractBuilder, votes: boolean, pausable: boolean, explicitImplementations: boolean) {
|
|
179
213
|
c.addUseClause('stellar_tokens::fungible', 'burnable::FungibleBurnable');
|
|
180
214
|
|
|
181
215
|
const fungibleBurnableTrait = {
|
|
@@ -185,23 +219,29 @@ function addBurnable(c: ContractBuilder, pausable: boolean, explicitImplementati
|
|
|
185
219
|
section: 'Extensions',
|
|
186
220
|
};
|
|
187
221
|
|
|
188
|
-
|
|
189
|
-
|
|
222
|
+
const burnFn = votes ? votesFunctions.burn : functions.burn;
|
|
223
|
+
const burnFromFn = votes ? votesFunctions.burn_from : functions.burn_from;
|
|
190
224
|
|
|
191
|
-
|
|
192
|
-
|
|
225
|
+
if (pausable || votes || explicitImplementations) {
|
|
226
|
+
if (pausable) {
|
|
227
|
+
c.addUseClause('stellar_macros', 'when_not_paused');
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
c.addTraitFunction(fungibleBurnableTrait, burnFn);
|
|
231
|
+
c.addTraitFunction(fungibleBurnableTrait, burnFromFn);
|
|
193
232
|
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
233
|
+
if (pausable) {
|
|
234
|
+
c.addFunctionTag(burnFn, 'when_not_paused', fungibleBurnableTrait);
|
|
235
|
+
c.addFunctionTag(burnFromFn, 'when_not_paused', fungibleBurnableTrait);
|
|
236
|
+
}
|
|
237
|
+
} else {
|
|
198
238
|
c.addTraitImplBlock(fungibleBurnableTrait);
|
|
199
239
|
}
|
|
200
240
|
}
|
|
201
241
|
|
|
202
242
|
export const premintPattern = /^(\d*\.?\d*)$/;
|
|
203
243
|
|
|
204
|
-
function addPremint(c: ContractBuilder, amount: string) {
|
|
244
|
+
function addPremint(c: ContractBuilder, amount: string, votes: boolean) {
|
|
205
245
|
if (amount !== undefined && amount !== '0') {
|
|
206
246
|
if (!premintPattern.test(amount)) {
|
|
207
247
|
throw new OptionsError({
|
|
@@ -213,7 +253,7 @@ function addPremint(c: ContractBuilder, amount: string) {
|
|
|
213
253
|
const premintAbsolute = toUint(getInitialSupply(amount, 7), 'premint', 'u128');
|
|
214
254
|
|
|
215
255
|
c.addConstructorArgument({ name: 'recipient', type: 'Address' });
|
|
216
|
-
c.addConstructorCode(
|
|
256
|
+
c.addConstructorCode(`${votes ? 'FungibleVotes' : 'Base'}::mint(e, &recipient, ${premintAbsolute});`);
|
|
217
257
|
}
|
|
218
258
|
}
|
|
219
259
|
|
|
@@ -350,6 +390,36 @@ export const functions = defineFunctions({
|
|
|
350
390
|
},
|
|
351
391
|
});
|
|
352
392
|
|
|
393
|
+
const votesFunctions = defineFunctions({
|
|
394
|
+
burn: {
|
|
395
|
+
args: [getSelfArg(), { name: 'from', type: 'Address' }, { name: 'amount', type: 'i128' }],
|
|
396
|
+
code: ['FungibleVotes::burn(e, &from, amount)'],
|
|
397
|
+
},
|
|
398
|
+
burn_from: {
|
|
399
|
+
args: [
|
|
400
|
+
getSelfArg(),
|
|
401
|
+
{ name: 'spender', type: 'Address' },
|
|
402
|
+
{ name: 'from', type: 'Address' },
|
|
403
|
+
{ name: 'amount', type: 'i128' },
|
|
404
|
+
],
|
|
405
|
+
code: ['FungibleVotes::burn_from(e, &spender, &from, amount)'],
|
|
406
|
+
},
|
|
407
|
+
mint: {
|
|
408
|
+
args: [getSelfArg(), { name: 'account', type: 'Address' }, { name: 'amount', type: 'i128' }],
|
|
409
|
+
code: ['FungibleVotes::mint(e, &account, amount);'],
|
|
410
|
+
},
|
|
411
|
+
mint_with_caller: {
|
|
412
|
+
name: 'mint',
|
|
413
|
+
args: [
|
|
414
|
+
getSelfArg(),
|
|
415
|
+
{ name: 'account', type: 'Address' },
|
|
416
|
+
{ name: 'amount', type: 'i128' },
|
|
417
|
+
{ name: 'caller', type: 'Address' },
|
|
418
|
+
],
|
|
419
|
+
code: ['FungibleVotes::mint(e, &account, amount);'],
|
|
420
|
+
},
|
|
421
|
+
});
|
|
422
|
+
|
|
353
423
|
const fungibleTokenTraitFunctions = pickKeys(functions, [
|
|
354
424
|
'total_supply',
|
|
355
425
|
'balance',
|
|
@@ -361,5 +431,3 @@ const fungibleTokenTraitFunctions = pickKeys(functions, [
|
|
|
361
431
|
'name',
|
|
362
432
|
'symbol',
|
|
363
433
|
]);
|
|
364
|
-
|
|
365
|
-
const fungibleBurnableFunctions = pickKeys(functions, ['burn', 'burn_from']);
|
package/src/generate/fungible.ts
CHANGED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import type { GovernorOptions } from '../governor';
|
|
2
|
+
import { accessOptions } from '../set-access-control';
|
|
3
|
+
import { infoOptions } from '../set-info';
|
|
4
|
+
import { generateAlternatives } from './alternatives';
|
|
5
|
+
|
|
6
|
+
const booleans = [true, false];
|
|
7
|
+
|
|
8
|
+
const blueprint = {
|
|
9
|
+
name: ['MyGovernor'],
|
|
10
|
+
version: ['1.0.0'],
|
|
11
|
+
votingDelay: ['10'],
|
|
12
|
+
votingPeriod: ['100'],
|
|
13
|
+
proposalThreshold: ['100'],
|
|
14
|
+
quorum: ['500'],
|
|
15
|
+
upgradeable: booleans,
|
|
16
|
+
timelock: booleans,
|
|
17
|
+
access: accessOptions,
|
|
18
|
+
info: infoOptions,
|
|
19
|
+
explicitImplementations: booleans,
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
export function* generateGovernorOptions(): Generator<Required<GovernorOptions>> {
|
|
23
|
+
yield* generateAlternatives(blueprint);
|
|
24
|
+
}
|
package/src/generate/sources.ts
CHANGED
|
@@ -3,6 +3,7 @@ import path from 'path';
|
|
|
3
3
|
import crypto from 'crypto';
|
|
4
4
|
|
|
5
5
|
import { generateFungibleOptions } from './fungible';
|
|
6
|
+
import { generateGovernorOptions } from './governor';
|
|
6
7
|
import { generateNonFungibleOptions } from './non-fungible';
|
|
7
8
|
import { generateStablecoinOptions } from './stablecoin';
|
|
8
9
|
import type { GenericOptions, KindedOptions } from '../build-generic';
|
|
@@ -20,6 +21,12 @@ export function* generateOptions(kind?: Kind): Generator<GenericOptions> {
|
|
|
20
21
|
}
|
|
21
22
|
}
|
|
22
23
|
|
|
24
|
+
if (!kind || kind === 'Governor') {
|
|
25
|
+
for (const kindOpts of generateGovernorOptions()) {
|
|
26
|
+
yield { kind: 'Governor', ...kindOpts };
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
|
|
23
30
|
if (!kind || kind === 'NonFungible') {
|
|
24
31
|
for (const kindOpts of generateNonFungibleOptions()) {
|
|
25
32
|
yield { kind: 'NonFungible', ...kindOpts };
|