@openzeppelin/wizard-stellar 0.5.0 → 0.6.1
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 +3 -1
- package/dist/fungible.d.ts.map +1 -1
- package/dist/fungible.js +80 -27
- package/dist/fungible.js.map +1 -1
- package/dist/generate/fungible.d.ts.map +1 -1
- package/dist/generate/fungible.js +2 -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 +2 -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 +106 -27
- package/src/generate/fungible.ts +2 -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 +2 -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.1",
|
|
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
|
@@ -13,10 +13,14 @@ import { printContract } from './print';
|
|
|
13
13
|
import { toByteArray, toUint } from './utils/convert-strings';
|
|
14
14
|
import { pickKeys } from '@openzeppelin/wizard-common';
|
|
15
15
|
|
|
16
|
+
const DEFAULT_DECIMALS = 7;
|
|
17
|
+
|
|
16
18
|
export const defaults: Required<FungibleOptions> = {
|
|
17
19
|
name: 'MyToken',
|
|
18
20
|
symbol: 'MTK',
|
|
21
|
+
decimals: DEFAULT_DECIMALS.toString(),
|
|
19
22
|
burnable: false,
|
|
23
|
+
votes: false,
|
|
20
24
|
pausable: false,
|
|
21
25
|
upgradeable: false,
|
|
22
26
|
premint: '0',
|
|
@@ -33,7 +37,9 @@ export function printFungible(opts: FungibleOptions = defaults): string {
|
|
|
33
37
|
export interface FungibleOptions extends CommonContractOptions {
|
|
34
38
|
name: string;
|
|
35
39
|
symbol: string;
|
|
40
|
+
decimals?: string;
|
|
36
41
|
burnable?: boolean;
|
|
42
|
+
votes?: boolean;
|
|
37
43
|
pausable?: boolean;
|
|
38
44
|
upgradeable?: boolean;
|
|
39
45
|
premint?: string;
|
|
@@ -44,7 +50,9 @@ export function withDefaults(opts: FungibleOptions): Required<FungibleOptions> {
|
|
|
44
50
|
return {
|
|
45
51
|
...opts,
|
|
46
52
|
...withCommonContractDefaults(opts),
|
|
53
|
+
decimals: opts.decimals ?? defaults.decimals,
|
|
47
54
|
burnable: opts.burnable ?? defaults.burnable,
|
|
55
|
+
votes: opts.votes ?? defaults.votes,
|
|
48
56
|
pausable: opts.pausable ?? defaults.pausable,
|
|
49
57
|
upgradeable: opts.upgradeable ?? defaults.upgradeable,
|
|
50
58
|
premint: opts.premint || defaults.premint,
|
|
@@ -61,10 +69,20 @@ export function buildFungible(opts: FungibleOptions): ContractBuilder {
|
|
|
61
69
|
|
|
62
70
|
const allOpts = withDefaults(opts);
|
|
63
71
|
|
|
64
|
-
|
|
72
|
+
const decimals = toUint(allOpts.decimals, 'decimals', 'u32');
|
|
73
|
+
|
|
74
|
+
addBase(
|
|
75
|
+
c,
|
|
76
|
+
toByteArray(allOpts.name),
|
|
77
|
+
toByteArray(allOpts.symbol),
|
|
78
|
+
decimals,
|
|
79
|
+
allOpts.votes,
|
|
80
|
+
allOpts.pausable,
|
|
81
|
+
allOpts.explicitImplementations,
|
|
82
|
+
);
|
|
65
83
|
|
|
66
84
|
if (allOpts.premint) {
|
|
67
|
-
addPremint(c, allOpts.premint);
|
|
85
|
+
addPremint(c, allOpts.premint, decimals, allOpts.votes);
|
|
68
86
|
}
|
|
69
87
|
|
|
70
88
|
if (allOpts.pausable) {
|
|
@@ -76,11 +94,11 @@ export function buildFungible(opts: FungibleOptions): ContractBuilder {
|
|
|
76
94
|
}
|
|
77
95
|
|
|
78
96
|
if (allOpts.burnable) {
|
|
79
|
-
addBurnable(c, allOpts.pausable, allOpts.explicitImplementations);
|
|
97
|
+
addBurnable(c, allOpts.votes, allOpts.pausable, allOpts.explicitImplementations);
|
|
80
98
|
}
|
|
81
99
|
|
|
82
100
|
if (allOpts.mintable) {
|
|
83
|
-
addMintable(c, allOpts.access, allOpts.pausable, allOpts.explicitImplementations);
|
|
101
|
+
addMintable(c, allOpts.access, allOpts.votes, allOpts.pausable, allOpts.explicitImplementations);
|
|
84
102
|
}
|
|
85
103
|
|
|
86
104
|
setAccessControl(c, allOpts.access, allOpts.explicitImplementations);
|
|
@@ -93,15 +111,24 @@ function addBase(
|
|
|
93
111
|
c: ContractBuilder,
|
|
94
112
|
name: string,
|
|
95
113
|
symbol: string,
|
|
114
|
+
decimals: bigint,
|
|
115
|
+
votes: boolean,
|
|
96
116
|
pausable: boolean,
|
|
97
117
|
explicitImplementations: boolean,
|
|
98
118
|
) {
|
|
99
119
|
// Set metadata
|
|
100
|
-
c.addConstructorCode(
|
|
120
|
+
c.addConstructorCode(
|
|
121
|
+
`Base::set_metadata(e, ${decimals}, String::from_str(e, "${name}"), String::from_str(e, "${symbol}"));`,
|
|
122
|
+
);
|
|
101
123
|
|
|
102
124
|
// Set token functions
|
|
103
125
|
c.addUseClause('stellar_tokens::fungible', 'Base');
|
|
104
126
|
c.addUseClause('stellar_tokens::fungible', 'FungibleToken');
|
|
127
|
+
if (votes) {
|
|
128
|
+
c.addUseClause('stellar_tokens::fungible', 'ContractOverrides');
|
|
129
|
+
c.addUseClause('stellar_governance::votes', 'Votes');
|
|
130
|
+
c.addUseClause('stellar_tokens::fungible', 'votes::FungibleVotes');
|
|
131
|
+
}
|
|
105
132
|
c.addUseClause('soroban_sdk', 'contract');
|
|
106
133
|
c.addUseClause('soroban_sdk', 'contractimpl');
|
|
107
134
|
c.addUseClause('soroban_sdk', 'String');
|
|
@@ -115,7 +142,7 @@ function addBase(
|
|
|
115
142
|
traitName: 'FungibleToken',
|
|
116
143
|
structName: c.name,
|
|
117
144
|
tags: explicitImplementations ? ['contractimpl'] : ['contractimpl(contracttrait)'],
|
|
118
|
-
assocType:
|
|
145
|
+
assocType: `type ContractType = ${votes ? 'FungibleVotes' : 'Base'};`,
|
|
119
146
|
};
|
|
120
147
|
|
|
121
148
|
c.addTraitImplBlock(fungibleTokenTrait);
|
|
@@ -131,29 +158,47 @@ function addBase(
|
|
|
131
158
|
c.addTraitFunction(fungibleTokenTrait, functions.transfer_from);
|
|
132
159
|
c.addFunctionTag(functions.transfer_from, 'when_not_paused', fungibleTokenTrait);
|
|
133
160
|
}
|
|
161
|
+
|
|
162
|
+
if (votes) {
|
|
163
|
+
c.addTraitImplBlock({
|
|
164
|
+
traitName: 'Votes',
|
|
165
|
+
structName: c.name,
|
|
166
|
+
tags: explicitImplementations ? ['contractimpl'] : ['contractimpl(contracttrait)'],
|
|
167
|
+
section: 'Extensions',
|
|
168
|
+
});
|
|
169
|
+
}
|
|
134
170
|
}
|
|
135
171
|
|
|
136
|
-
function addMintable(
|
|
172
|
+
function addMintable(
|
|
173
|
+
c: ContractBuilder,
|
|
174
|
+
access: Access,
|
|
175
|
+
votes: boolean,
|
|
176
|
+
pausable: boolean,
|
|
177
|
+
explicitImplementations: boolean,
|
|
178
|
+
) {
|
|
179
|
+
const mintFn = votes ? votesFunctions.mint : functions.mint;
|
|
180
|
+
const mintWithCallerFn = votes ? votesFunctions.mint_with_caller : functions.mint_with_caller;
|
|
181
|
+
|
|
137
182
|
switch (access) {
|
|
138
183
|
case false:
|
|
139
184
|
break;
|
|
140
185
|
case 'ownable': {
|
|
141
|
-
c.addFreeFunction(
|
|
186
|
+
c.addFreeFunction(mintFn);
|
|
142
187
|
|
|
143
|
-
requireAccessControl(c, undefined,
|
|
188
|
+
requireAccessControl(c, undefined, mintFn, access, undefined, explicitImplementations);
|
|
144
189
|
|
|
145
190
|
if (pausable) {
|
|
146
|
-
c.addFunctionTag(
|
|
191
|
+
c.addFunctionTag(mintFn, 'when_not_paused');
|
|
147
192
|
}
|
|
148
193
|
break;
|
|
149
194
|
}
|
|
150
195
|
case 'roles': {
|
|
151
|
-
c.addFreeFunction(
|
|
196
|
+
c.addFreeFunction(mintWithCallerFn);
|
|
152
197
|
|
|
153
198
|
requireAccessControl(
|
|
154
199
|
c,
|
|
155
200
|
undefined,
|
|
156
|
-
|
|
201
|
+
mintWithCallerFn,
|
|
157
202
|
access,
|
|
158
203
|
{
|
|
159
204
|
useMacro: true,
|
|
@@ -164,7 +209,7 @@ function addMintable(c: ContractBuilder, access: Access, pausable: boolean, expl
|
|
|
164
209
|
);
|
|
165
210
|
|
|
166
211
|
if (pausable) {
|
|
167
|
-
c.addFunctionTag(
|
|
212
|
+
c.addFunctionTag(mintWithCallerFn, 'when_not_paused');
|
|
168
213
|
}
|
|
169
214
|
break;
|
|
170
215
|
}
|
|
@@ -175,7 +220,7 @@ function addMintable(c: ContractBuilder, access: Access, pausable: boolean, expl
|
|
|
175
220
|
}
|
|
176
221
|
}
|
|
177
222
|
|
|
178
|
-
function addBurnable(c: ContractBuilder, pausable: boolean, explicitImplementations: boolean) {
|
|
223
|
+
function addBurnable(c: ContractBuilder, votes: boolean, pausable: boolean, explicitImplementations: boolean) {
|
|
179
224
|
c.addUseClause('stellar_tokens::fungible', 'burnable::FungibleBurnable');
|
|
180
225
|
|
|
181
226
|
const fungibleBurnableTrait = {
|
|
@@ -185,23 +230,29 @@ function addBurnable(c: ContractBuilder, pausable: boolean, explicitImplementati
|
|
|
185
230
|
section: 'Extensions',
|
|
186
231
|
};
|
|
187
232
|
|
|
188
|
-
|
|
189
|
-
|
|
233
|
+
const burnFn = votes ? votesFunctions.burn : functions.burn;
|
|
234
|
+
const burnFromFn = votes ? votesFunctions.burn_from : functions.burn_from;
|
|
235
|
+
|
|
236
|
+
if (pausable || votes || explicitImplementations) {
|
|
237
|
+
if (pausable) {
|
|
238
|
+
c.addUseClause('stellar_macros', 'when_not_paused');
|
|
239
|
+
}
|
|
190
240
|
|
|
191
|
-
c.addTraitFunction(fungibleBurnableTrait,
|
|
192
|
-
c.
|
|
241
|
+
c.addTraitFunction(fungibleBurnableTrait, burnFn);
|
|
242
|
+
c.addTraitFunction(fungibleBurnableTrait, burnFromFn);
|
|
193
243
|
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
244
|
+
if (pausable) {
|
|
245
|
+
c.addFunctionTag(burnFn, 'when_not_paused', fungibleBurnableTrait);
|
|
246
|
+
c.addFunctionTag(burnFromFn, 'when_not_paused', fungibleBurnableTrait);
|
|
247
|
+
}
|
|
248
|
+
} else {
|
|
198
249
|
c.addTraitImplBlock(fungibleBurnableTrait);
|
|
199
250
|
}
|
|
200
251
|
}
|
|
201
252
|
|
|
202
253
|
export const premintPattern = /^(\d*\.?\d*)$/;
|
|
203
254
|
|
|
204
|
-
function addPremint(c: ContractBuilder, amount: string) {
|
|
255
|
+
function addPremint(c: ContractBuilder, amount: string, decimals: bigint, votes: boolean) {
|
|
205
256
|
if (amount !== undefined && amount !== '0') {
|
|
206
257
|
if (!premintPattern.test(amount)) {
|
|
207
258
|
throw new OptionsError({
|
|
@@ -210,10 +261,10 @@ function addPremint(c: ContractBuilder, amount: string) {
|
|
|
210
261
|
}
|
|
211
262
|
|
|
212
263
|
// TODO: handle signed int?
|
|
213
|
-
const premintAbsolute = toUint(getInitialSupply(amount,
|
|
264
|
+
const premintAbsolute = toUint(getInitialSupply(amount, Number(decimals)), 'premint', 'u128');
|
|
214
265
|
|
|
215
266
|
c.addConstructorArgument({ name: 'recipient', type: 'Address' });
|
|
216
|
-
c.addConstructorCode(
|
|
267
|
+
c.addConstructorCode(`${votes ? 'FungibleVotes' : 'Base'}::mint(e, &recipient, ${premintAbsolute});`);
|
|
217
268
|
}
|
|
218
269
|
}
|
|
219
270
|
|
|
@@ -350,6 +401,36 @@ export const functions = defineFunctions({
|
|
|
350
401
|
},
|
|
351
402
|
});
|
|
352
403
|
|
|
404
|
+
const votesFunctions = defineFunctions({
|
|
405
|
+
burn: {
|
|
406
|
+
args: [getSelfArg(), { name: 'from', type: 'Address' }, { name: 'amount', type: 'i128' }],
|
|
407
|
+
code: ['FungibleVotes::burn(e, &from, amount)'],
|
|
408
|
+
},
|
|
409
|
+
burn_from: {
|
|
410
|
+
args: [
|
|
411
|
+
getSelfArg(),
|
|
412
|
+
{ name: 'spender', type: 'Address' },
|
|
413
|
+
{ name: 'from', type: 'Address' },
|
|
414
|
+
{ name: 'amount', type: 'i128' },
|
|
415
|
+
],
|
|
416
|
+
code: ['FungibleVotes::burn_from(e, &spender, &from, amount)'],
|
|
417
|
+
},
|
|
418
|
+
mint: {
|
|
419
|
+
args: [getSelfArg(), { name: 'account', type: 'Address' }, { name: 'amount', type: 'i128' }],
|
|
420
|
+
code: ['FungibleVotes::mint(e, &account, amount);'],
|
|
421
|
+
},
|
|
422
|
+
mint_with_caller: {
|
|
423
|
+
name: 'mint',
|
|
424
|
+
args: [
|
|
425
|
+
getSelfArg(),
|
|
426
|
+
{ name: 'account', type: 'Address' },
|
|
427
|
+
{ name: 'amount', type: 'i128' },
|
|
428
|
+
{ name: 'caller', type: 'Address' },
|
|
429
|
+
],
|
|
430
|
+
code: ['FungibleVotes::mint(e, &account, amount);'],
|
|
431
|
+
},
|
|
432
|
+
});
|
|
433
|
+
|
|
353
434
|
const fungibleTokenTraitFunctions = pickKeys(functions, [
|
|
354
435
|
'total_supply',
|
|
355
436
|
'balance',
|
|
@@ -361,5 +442,3 @@ const fungibleTokenTraitFunctions = pickKeys(functions, [
|
|
|
361
442
|
'name',
|
|
362
443
|
'symbol',
|
|
363
444
|
]);
|
|
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 };
|