@totems/evm 1.0.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.
@@ -0,0 +1,153 @@
1
+ // SPDX-License-Identifier: MIT
2
+ // AUTO-GENERATED - DO NOT EDIT
3
+ // Generated from ModMarket
4
+ pragma solidity ^0.8.28;
5
+
6
+ import "../library/ITotemTypes.sol";
7
+
8
+ interface IMarket {
9
+ // ==================== FUNCTIONS ====================
10
+
11
+ /**
12
+ * @notice Set your referrer fee for mod publishing
13
+ * @dev Referrers earn fees when users publish mods using their address. Fee must be at least minBaseFee. The referrer receives (fee - burnedFee).
14
+ * @param fee The fee amount in wei (must be >= minBaseFee)
15
+ */
16
+ function setReferrerFee(uint256 fee) external;
17
+
18
+ /**
19
+ * @notice Get the fee for creating a totem or publishing a mod
20
+ * @param referrer The referrer address (or zero address for no referrer)
21
+ * @return The total fee required (at least minBaseFee)
22
+ */
23
+ function getFee(address referrer) external view returns (uint256);
24
+
25
+ /**
26
+ * @notice Publish a mod to the marketplace
27
+ * @dev Only the mod's seller (returned by mod.getSeller()) can publish. Validates: contract exists, not already published, name 3-100 chars, summary 10-150 chars, image URL present, valid hooks with no duplicates. Excess payment is refunded to sender.
28
+ * @param mod Deployed mod contract address
29
+ * @param hooks Array of supported hook identifiers (Created, Mint, Burn, Transfer, TransferOwnership)
30
+ * @param price Price in wei to use this mod (paid when totem creator adds the mod)
31
+ * @param details Mod display details (name, summary, image, website, etc.)
32
+ * @param requiredActions Setup actions users must call after totem creation
33
+ * @param referrer Optional referrer address (receives fee minus burned amount)
34
+ */
35
+ function publish(address mod, ITotemTypes.Hook[] calldata hooks, uint256 price, ITotemTypes.ModDetails calldata details, ITotemTypes.ModRequiredAction[] calldata requiredActions, address payable referrer) external payable;
36
+
37
+ /**
38
+ * @notice Update mod price and details
39
+ * @param mod Mod contract address
40
+ * @param newPrice New price in wei
41
+ * @param details New mod details
42
+ */
43
+ function update(address mod, uint256 newPrice, ITotemTypes.ModDetails calldata details) external;
44
+
45
+ /**
46
+ * @notice Update required actions for a mod
47
+ * @param mod Mod contract address
48
+ * @param requiredActions New required setup actions
49
+ */
50
+ function updateRequiredActions(address mod, ITotemTypes.ModRequiredAction[] calldata requiredActions) external;
51
+
52
+ /**
53
+ * @notice Get a single mod by address
54
+ * @param mod Mod contract address
55
+ * @return Mod struct
56
+ */
57
+ function getMod(address mod) external view returns (ITotemTypes.Mod memory);
58
+
59
+ /**
60
+ * @notice Get the usage price for a single mod
61
+ * @param mod Mod contract address
62
+ * @return The price in wei to use this mod
63
+ */
64
+ function getModFee(address mod) external view returns (uint256);
65
+
66
+ /**
67
+ * @notice Get required actions for a mod (setup actions called after totem creation)
68
+ * @param mod Mod contract address
69
+ * @return Array of required actions
70
+ */
71
+ function getModRequiredActions(address mod) external view returns (ITotemTypes.ModRequiredAction[] memory);
72
+
73
+ /**
74
+ * @notice Get multiple mods by their addresses
75
+ * @param contracts Array of mod contract addresses
76
+ * @return Array of Mod structs
77
+ */
78
+ function getMods(address[] calldata contracts) external view returns (ITotemTypes.Mod[] memory);
79
+
80
+ /**
81
+ * @notice Get the total usage price for multiple mods
82
+ * @dev Useful for calculating total cost when creating a totem with multiple mods
83
+ * @param contracts Array of mod contract addresses
84
+ * @return Total price in wei for all mods combined
85
+ */
86
+ function getModsFee(address[] calldata contracts) external view returns (uint256);
87
+
88
+ /**
89
+ * @notice Get the hooks supported by a mod
90
+ * @dev Hooks determine when the mod is called (Created, Mint, Burn, Transfer, TransferOwnership)
91
+ * @param mod Mod contract address
92
+ * @return Array of Hook enum values
93
+ */
94
+ function getSupportedHooks(address mod) external view returns (ITotemTypes.Hook[] memory);
95
+
96
+ /**
97
+ * @notice Check if a mod requires unlimited minting capability
98
+ * @dev Mods with needsUnlimited=true can mint tokens without supply cap restrictions. Returns false for unpublished mods.
99
+ * @param mod Mod contract address
100
+ * @return True if the mod needs unlimited minting capability
101
+ */
102
+ function isUnlimitedMinter(address mod) external view returns (bool);
103
+
104
+ /**
105
+ * @notice List mods with pagination
106
+ * @param perPage Number of results per page
107
+ * @param cursor Index to start from (for pagination)
108
+ * @return mods_ Array of Mod structs
109
+ * @return nextCursor Next cursor value
110
+ * @return hasMore Whether more results exist
111
+ */
112
+ function listMods(uint32 perPage, uint256 cursor) external view returns (ITotemTypes.Mod[] memory mods_, uint256 nextCursor, bool hasMore);
113
+
114
+ /**
115
+ * @notice Ordered list of all published mod addresses (for pagination)
116
+ */
117
+ function modList(uint256) external view returns (address);
118
+
119
+ /**
120
+ * @notice Fee amount that is always burned (set once in constructor, never changed)
121
+ */
122
+ function burnedFee() external view returns (uint256);
123
+
124
+ /**
125
+ * @notice Minimum base fee for mod publishing (set once in constructor, never changed)
126
+ */
127
+ function minBaseFee() external view returns (uint256);
128
+
129
+ // ==================== EVENTS ====================
130
+
131
+ event ModPublished(address indexed mod);
132
+ event ModUpdated(address indexed mod);
133
+
134
+ // ==================== ERRORS ====================
135
+
136
+ error DuplicateHook(ITotemTypes.Hook hook);
137
+ error EmptyModImage();
138
+ error EmptyModName();
139
+ error EmptyModSummary();
140
+ error InsufficientFee(uint256 required, uint256 provided);
141
+ error InvalidContractAddress();
142
+ error InvalidHook(ITotemTypes.Hook hook);
143
+ error ModAlreadyPublished(address mod);
144
+ error ModNameTooLong(uint256 length);
145
+ error ModNameTooShort(uint256 length);
146
+ error ModNotFound(address mod);
147
+ error ModSummaryTooLong(uint256 length);
148
+ error ModSummaryTooShort(uint256 length);
149
+ error NoHooksSpecified();
150
+ error ReferrerFeeTooLow(uint256 minFee);
151
+ error TransferFailed();
152
+ error Unauthorized();
153
+ }
@@ -0,0 +1,13 @@
1
+ // SPDX-License-Identifier: MIT
2
+ pragma solidity ^0.8.28;
3
+
4
+ interface IRelayFactory {
5
+ event RelayCreated(
6
+ string indexed ticker,
7
+ address indexed relayContract
8
+ );
9
+
10
+ function createRelay(
11
+ string calldata ticker
12
+ ) external returns (address);
13
+ }
@@ -0,0 +1,200 @@
1
+ // SPDX-License-Identifier: MIT
2
+ pragma solidity ^0.8.28;
3
+
4
+ /**
5
+ * @title ITotemTypes
6
+ * @notice Interface and types for the Totems ecosystem
7
+ * @dev This library provides core types and structures for Totems and Mods
8
+ */
9
+ interface ITotemTypes {
10
+
11
+ struct RelayInfo {
12
+ address relay;
13
+ string standard;
14
+ }
15
+
16
+ /// @notice Valid hook identifiers
17
+ enum Hook {
18
+ Created,
19
+ Mint,
20
+ Burn,
21
+ Transfer,
22
+ TransferOwnership
23
+ }
24
+
25
+ /**
26
+ * @notice Display details for a mod
27
+ * @param name Mod name
28
+ * @param summary Short description
29
+ * @param markdown Detailed markdown description
30
+ * @param image Image URL or IPFS hash
31
+ * @param website Website URL
32
+ * @param websiteTickerPath Path template for token-specific pages
33
+ * @param isMinter Whether this mod is a token minter
34
+ */
35
+ struct ModDetails {
36
+ string name;
37
+ string summary;
38
+ string markdown;
39
+ string image;
40
+ string website;
41
+ string websiteTickerPath;
42
+ bool isMinter;
43
+ bool needsUnlimited;
44
+ }
45
+
46
+ // Input mode for mod action fields
47
+ enum ModActionFieldInputMode {
48
+ // Request input from the user
49
+ DYNAMIC,
50
+ // Predefined static value
51
+ STATIC,
52
+ // Auto-fill with the current totem ticker
53
+ TOTEM
54
+ }
55
+
56
+ struct ModActionField {
57
+ // ex: "totem, mintPerMine"
58
+ string name;
59
+ ModActionFieldInputMode mode;
60
+ // only used for STATIC mode
61
+ string value;
62
+ // Human-readable description of this field for UIs (optional)
63
+ string description;
64
+ // Minimum value constraint for numeric inputs (0 = no minimum)
65
+ uint256 min;
66
+ // Maximum value constraint for numeric inputs (0 = no maximum)
67
+ uint256 max;
68
+ // Is this field expecting to receive totem amounts?
69
+ bool isTotems;
70
+ }
71
+
72
+ struct ModRequiredAction {
73
+ // ex: "setup(string totem, uint256 mintPerMine)"
74
+ // (only the ~canonical function signature, no "function" keyword, modifiers, or mutability)
75
+ // Also no return types!
76
+ string signature;
77
+ ModActionField[] inputFields;
78
+ // Is there a msg.value required to perform this action?
79
+ // If > 0 this will make the function payable
80
+ uint256 cost;
81
+ // Explain to users why this action is required for UIs
82
+ string reason;
83
+ }
84
+
85
+ /**
86
+ * @notice On-chain Mod entry in the marketplace
87
+ * @param mod The deployed mod contract address
88
+ * @param seller Address that receives payments for this mod
89
+ * @param price Price in wei to use this mod
90
+ * @param details Display details
91
+ * @param hooks Array of supported hook names
92
+ * @param publishedAt Timestamp of publication
93
+ * @param updatedAt Timestamp of last update
94
+ */
95
+ struct Mod {
96
+ address mod;
97
+ address payable seller;
98
+ uint64 publishedAt;
99
+ uint64 updatedAt;
100
+ uint256 price;
101
+ Hook[] hooks;
102
+ ModDetails details;
103
+ }
104
+
105
+ /**
106
+ * @notice Allocation of tokens at creation time
107
+ * @param label Human-readable label
108
+ * @param recipient Address to receive tokens
109
+ * @param amount Amount of tokens
110
+ * @param isMinter Whether this recipient is a minter mod
111
+ */
112
+ struct MintAllocation {
113
+ address payable recipient;
114
+ bool isMinter;
115
+ uint256 amount;
116
+ string label;
117
+ }
118
+
119
+ /**
120
+ * @notice Display details for a totem
121
+ * @param name Totem name
122
+ * @param description Detailed description
123
+ * @param image Image URL or IPFS hash
124
+ * @param website Website URL
125
+ * @param seed Generative seed for totem properties
126
+ */
127
+ struct TotemDetails {
128
+ bytes32 seed;
129
+ uint8 decimals;
130
+ string ticker;
131
+ string name;
132
+ string description;
133
+ string image;
134
+ string website;
135
+ }
136
+
137
+ /**
138
+ * @notice Mods assigned to each hook type
139
+ * @param transfer Mods for transfer hook
140
+ * @param mint Mods for mint hook
141
+ * @param burn Mods for burn hook
142
+ * @param created Mods for created hook
143
+ * @param transferOwnership Mods for transfer ownership hook
144
+ */
145
+ struct TotemMods {
146
+ address[] transfer;
147
+ address[] mint;
148
+ address[] burn;
149
+ address[] created;
150
+ address[] transferOwnership;
151
+ }
152
+
153
+ /**
154
+ * @notice Complete totem information
155
+ * @param creator Address that created the totem
156
+ * @param supply Current circulating supply
157
+ * @param maxSupply Maximum possible supply
158
+ * @param allocations Initial token allocations
159
+ * @param mods Mods for each hook type
160
+ * @param details Display information
161
+ * @param createdAt Creation timestamp
162
+ * @param updatedAt Last update timestamp
163
+ */
164
+ struct Totem {
165
+ address payable creator;
166
+ uint64 createdAt;
167
+ uint64 updatedAt;
168
+ bool isActive;
169
+ uint256 supply;
170
+ uint256 maxSupply;
171
+ MintAllocation[] allocations;
172
+ TotemMods mods;
173
+ TotemDetails details;
174
+ }
175
+
176
+ /**
177
+ * @notice Statistics for a totem
178
+ * @param ticker Token symbol
179
+ * @param mints Total number of mint operations
180
+ * @param burns Total number of burn operations
181
+ * @param transfers Total number of transfers
182
+ * @param holders Total number of unique holders
183
+ */
184
+ struct TotemStats {
185
+ uint64 mints;
186
+ uint64 burns;
187
+ uint64 transfers;
188
+ uint64 holders;
189
+ }
190
+
191
+ /**
192
+ * @notice Fee disbursement information
193
+ * @param recipient Address to receive funds
194
+ * @param amount Amount in wei
195
+ */
196
+ struct FeeDisbursement {
197
+ address payable recipient;
198
+ uint256 amount;
199
+ }
200
+ }
@@ -0,0 +1,178 @@
1
+ // SPDX-License-Identifier: MIT
2
+ // AUTO-GENERATED - DO NOT EDIT
3
+ // Generated from Totems
4
+ pragma solidity ^0.8.28;
5
+
6
+ import "../library/ITotemTypes.sol";
7
+
8
+ interface ITotems {
9
+ // ==================== FUNCTIONS ====================
10
+
11
+ /**
12
+ * @notice Creates a new totem with the specified details, allocations, and mods
13
+ */
14
+ function create(ITotemTypes.TotemDetails calldata details, ITotemTypes.MintAllocation[] calldata allocations, ITotemTypes.TotemMods calldata mods, address payable referrer) external payable;
15
+
16
+ /**
17
+ * @notice Burns tokens from a totem, permanently reducing supply
18
+ */
19
+ function burn(string calldata ticker, address owner, uint256 amount, string calldata memo) external;
20
+
21
+ /**
22
+ * @notice Mints tokens for a totem using an authorized minter mod
23
+ */
24
+ function mint(address mod, address minter, string calldata ticker, uint256 amount, string calldata memo) external payable;
25
+
26
+ /**
27
+ * @notice Transfers tokens between addresses
28
+ */
29
+ function transfer(string calldata ticker, address from, address to, uint256 amount, string calldata memo) external;
30
+
31
+ /**
32
+ * @notice Transfers ownership of a totem to a new address
33
+ */
34
+ function transferOwnership(string calldata ticker, address payable newOwner) external;
35
+
36
+ /**
37
+ * @notice Authorizes an existing relay address for a totem
38
+ */
39
+ function addRelay(string calldata ticker, address relay, string calldata standard) external;
40
+
41
+ /**
42
+ * @notice Creates a new relay for a totem using a relay factory
43
+ */
44
+ function createRelay(string calldata ticker, address relayFactory, string calldata standard) external returns (address relay);
45
+
46
+ /**
47
+ * @notice Revokes authorization for a relay from a totem
48
+ */
49
+ function removeRelay(string calldata ticker, address relay) external;
50
+
51
+ /**
52
+ * @notice Gets the relay address for a specific standard on a totem
53
+ */
54
+ function getRelayOfStandard(string calldata ticker, string calldata standard) external view returns (address);
55
+
56
+ /**
57
+ * @notice Gets all authorized relays for a totem
58
+ */
59
+ function getRelays(string calldata ticker) external view returns (ITotemTypes.RelayInfo[] memory);
60
+
61
+ /**
62
+ * @notice Grants a mod license for a totem, callable only by the proxy mod
63
+ */
64
+ function setLicenseFromProxy(bytes32 tickerBytes, address mod) external;
65
+
66
+ /**
67
+ * @notice Checks if a mod is licensed for a specific totem
68
+ */
69
+ function isLicensed(string calldata ticker, address mod) external view returns (bool);
70
+
71
+ /**
72
+ * @notice Sets the referrer fee for the caller
73
+ */
74
+ function setReferrerFee(uint256 fee) external;
75
+
76
+ /**
77
+ * @notice Gets the fee for creating a totem
78
+ */
79
+ function getFee(address referrer) external view returns (uint256);
80
+
81
+ /**
82
+ * @notice Retrieves a totem by its ticker symbol
83
+ */
84
+ function getTotem(string calldata ticker) external view returns (ITotemTypes.Totem memory);
85
+
86
+ /**
87
+ * @notice Retrieves multiple totems by their ticker symbols
88
+ */
89
+ function getTotems(string[] calldata tickers) external view returns (ITotemTypes.Totem[] memory);
90
+
91
+ /**
92
+ * @notice Lists totems with pagination support
93
+ */
94
+ function listTotems(uint32 perPage, uint256 cursor) external view returns (ITotemTypes.Totem[] memory, uint256, bool);
95
+
96
+ /**
97
+ * @notice Gets the token balance for an account on a specific totem
98
+ */
99
+ function getBalance(string calldata ticker, address account) external view returns (uint256);
100
+
101
+ /**
102
+ * @notice Gets the statistics for a totem
103
+ */
104
+ function getStats(string calldata ticker) external view returns (ITotemTypes.TotemStats memory);
105
+
106
+ /**
107
+ * @notice Gets the proxy mod address
108
+ */
109
+ function getProxyMod() external view returns (address);
110
+
111
+ /**
112
+ * @notice Converts a ticker string to its normalized bytes32 representation
113
+ */
114
+ function tickerToBytes(string calldata ticker) external pure returns (bytes32);
115
+
116
+ /**
117
+ * @notice Fee amount that is always burned (set once in constructor, never changed)
118
+ */
119
+ function burnedFee() external view returns (uint256);
120
+
121
+ /**
122
+ * @notice Address of the mod market contract
123
+ */
124
+ function marketContract() external view returns (address);
125
+
126
+ /**
127
+ * @notice Minimum base fee for totem creation (set once in constructor, never changed)
128
+ */
129
+ function minBaseFee() external view returns (uint256);
130
+
131
+ /**
132
+ * @notice Address of the proxy mod for license delegation
133
+ */
134
+ function proxyMod() external view returns (address);
135
+
136
+ /**
137
+ * @notice Array of all totem ticker bytes for enumeration
138
+ */
139
+ function totemList(uint256) external view returns (bytes32);
140
+
141
+ // ==================== EVENTS ====================
142
+
143
+ event RelayAuthorized(string ticker, address indexed relay);
144
+ event RelayRevoked(string ticker, address indexed relay);
145
+ event TotemBurned(string ticker, address indexed owner, uint256 amount);
146
+ event TotemCreated(string ticker, address indexed creator);
147
+ event TotemMinted(string ticker, address indexed minter, address mod, uint256 minted, uint256 payment);
148
+ event TotemOwnershipTransferred(string ticker, address indexed previousOwner, address indexed newOwner);
149
+ event TotemTransferred(string ticker, address indexed from, address indexed to, uint256 amount);
150
+
151
+ // ==================== ERRORS ====================
152
+
153
+ error CannotTransferToUnlimitedMinter();
154
+ error CantSetLicense();
155
+ error DescriptionTooLong(uint256 length);
156
+ error EmptyImage();
157
+ error InsufficientBalance(uint256 required, uint256 available);
158
+ error InsufficientFee(uint256 required, uint256 provided);
159
+ error InvalidAllocation(string message);
160
+ error InvalidCursor();
161
+ error InvalidSeed();
162
+ error InvalidTickerChar(uint8 char);
163
+ error InvalidTickerLength(uint256 length);
164
+ error ModDoesntSupportHook(address mod, ITotemTypes.Hook hook);
165
+ error ModMustSupportUnlimitedMinting(address mod);
166
+ error ModNotMinter(address mod);
167
+ error NameTooLong(uint256 length);
168
+ error NameTooShort(uint256 length);
169
+ error ReferrerFeeTooLow(uint256 minFee);
170
+ error TooManyAllocations();
171
+ error TooManyMods();
172
+ error TotemAlreadyExists(string ticker);
173
+ error TotemNotActive();
174
+ error TotemNotFound(string ticker);
175
+ error TransferFailed();
176
+ error Unauthorized();
177
+ error ZeroSupply();
178
+ }
@@ -0,0 +1,136 @@
1
+ // SPDX-License-Identifier: MIT
2
+ pragma solidity ^0.8.28;
3
+
4
+ import "../library/ITotemTypes.sol";
5
+ import {TotemsLibrary} from "../library/TotemsLibrary.sol";
6
+
7
+ interface ITotemsProxyModGetter {
8
+ function getProxyMod() external view returns (address);
9
+ }
10
+
11
+ interface IMod {
12
+ function getSeller() external view returns (address payable);
13
+ }
14
+
15
+ interface IModTransfer {
16
+ function onTransfer(
17
+ string calldata ticker,
18
+ address from,
19
+ address to,
20
+ uint256 amount,
21
+ string calldata memo
22
+ ) external;
23
+ }
24
+
25
+ interface IModMint {
26
+ function onMint(
27
+ string calldata ticker,
28
+ address minter,
29
+ uint256 amount,
30
+ uint256 payment,
31
+ string calldata memo
32
+ ) external;
33
+ }
34
+
35
+ interface IModMinter {
36
+ function mint(
37
+ string calldata ticker,
38
+ address minter,
39
+ uint256 amount,
40
+ string calldata memo
41
+ ) external payable;
42
+ }
43
+
44
+ interface IModBurn {
45
+ function onBurn(
46
+ string calldata ticker,
47
+ address owner,
48
+ uint256 amount,
49
+ string calldata memo
50
+ ) external;
51
+ }
52
+
53
+ interface IModCreated {
54
+ function onCreated(
55
+ string calldata ticker,
56
+ address creator
57
+ ) external;
58
+ }
59
+
60
+ interface IModTransferOwnership {
61
+ function onTransferOwnership(
62
+ string calldata ticker,
63
+ address previousOwner,
64
+ address newOwner
65
+ ) external;
66
+ }
67
+
68
+ /**
69
+ * @title TotemMod
70
+ * @notice Base contract for building mods
71
+ */
72
+ abstract contract TotemMod {
73
+
74
+ address payable private seller;
75
+ function getSeller() external view returns (address payable) {
76
+ return seller != address(0) ? payable(address(seller)) : payable(address(this));
77
+ }
78
+
79
+ function isSetupFor(string calldata ticker) virtual external view returns (bool);
80
+
81
+ error InvalidModEventOrigin();
82
+ error NotLicensed();
83
+
84
+
85
+
86
+ /// @notice Address of the Totems contract
87
+ address public immutable totemsContract;
88
+
89
+ /**
90
+ * @notice Constructor
91
+ * @param _totemsContract Totems contract address
92
+ * @param _seller The seller that will publish this mod (gets paid)
93
+ */
94
+ constructor(address _totemsContract, address payable _seller) {
95
+ totemsContract = _totemsContract;
96
+ seller = _seller;
97
+ }
98
+
99
+ /**
100
+ * @notice Ensure caller is the Totems contract
101
+ */
102
+ modifier onlyTotems() {
103
+ // sender must be either the totems contract or the proxy mod
104
+ if(msg.sender != totemsContract){
105
+ if(msg.sender != ITotemsProxyModGetter(totemsContract).getProxyMod()){
106
+ revert InvalidModEventOrigin();
107
+ }
108
+ }
109
+ _;
110
+ }
111
+
112
+ /**
113
+ * @notice Ensure the mod is licensed for the given ticker
114
+ */
115
+ modifier onlyLicensed(string calldata ticker) {
116
+ if (!TotemsLibrary.hasLicense(totemsContract, ticker, address(this))) {
117
+ revert NotLicensed();
118
+ }
119
+ _;
120
+ }
121
+
122
+ modifier onlyCreator(string calldata ticker) {
123
+ address creator = TotemsLibrary.getCreator(totemsContract, ticker);
124
+ if (msg.sender != creator) {
125
+ revert("Only totem creator can call this");
126
+ }
127
+ _;
128
+ }
129
+
130
+ modifier onlySetup(string calldata ticker) {
131
+ if (!this.isSetupFor(ticker)) {
132
+ revert("Mod is not setup for this totem");
133
+ }
134
+ _;
135
+ }
136
+ }