@totems/evm 1.0.7 → 1.0.8

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@totems/evm",
3
- "version": "1.0.7",
3
+ "version": "1.0.8",
4
4
  "type": "module",
5
5
  "description": "Totems EVM smart contracts for building modular token systems",
6
6
  "author": "nsjames",
@@ -29,9 +29,7 @@
29
29
  "exports": {
30
30
  "./test/helpers": {
31
31
  "types": "./test/helpers.d.ts",
32
- "import": "./test/helpers.js",
33
- "require": "./test/helpers.js",
34
- "default": "./test/helpers.js"
32
+ "default": "./test/helpers.ts"
35
33
  },
36
34
  "./contracts/*": "./contracts/*",
37
35
  "./interfaces/*": "./interfaces/*",
@@ -0,0 +1,467 @@
1
+ import {network} from "hardhat";
2
+ import { keccak256, toBytes, decodeErrorResult, Abi } from "viem";
3
+
4
+ export const ZERO_ADDRESS = '0x0000000000000000000000000000000000000000';
5
+
6
+ /**
7
+ * Computes the 4-byte selector for a custom error signature
8
+ * @param signature Error signature like "NotLicensed()" or "InsufficientBalance(uint256,uint256)"
9
+ */
10
+ export function errorSelector(signature: string): string {
11
+ return keccak256(toBytes(signature)).slice(0, 10); // 0x + 8 hex chars = 4 bytes
12
+ }
13
+
14
+ /**
15
+ * Extracts the error selector from a caught error's revert data
16
+ */
17
+ function getErrorData(error: any): string | null {
18
+ // Try common paths where revert data might be
19
+ const data = error?.cause?.cause?.data
20
+ || error?.cause?.data
21
+ || error?.data
22
+ || error?.message?.match(/return data: (0x[a-fA-F0-9]+)/)?.[1]
23
+ || error?.message?.match(/data: (0x[a-fA-F0-9]+)/)?.[1];
24
+ return data || null;
25
+ }
26
+
27
+ /**
28
+ * Asserts that a promise rejects with a specific custom error
29
+ * @param promise The promise to test
30
+ * @param expectedSelector The expected error selector (use errorSelector() to compute)
31
+ * @param errorName Human-readable error name for assertion messages
32
+ */
33
+ export async function expectCustomError(
34
+ promise: Promise<any>,
35
+ expectedSelector: string,
36
+ errorName: string
37
+ ): Promise<void> {
38
+ try {
39
+ await promise;
40
+ throw new Error(`Expected ${errorName} but transaction succeeded`);
41
+ } catch (e: any) {
42
+ if (e.message?.startsWith(`Expected ${errorName}`)) throw e;
43
+
44
+ const data = getErrorData(e);
45
+ if (!data) {
46
+ throw new Error(`Expected ${errorName} but got error without revert data: ${e.message}`);
47
+ }
48
+
49
+ const actualSelector = data.slice(0, 10).toLowerCase();
50
+ const expected = expectedSelector.toLowerCase();
51
+
52
+ if (actualSelector !== expected) {
53
+ throw new Error(
54
+ `Expected ${errorName} (${expected}) but got selector ${actualSelector}\nFull data: ${data}`
55
+ );
56
+ }
57
+ }
58
+ }
59
+
60
+ /**
61
+ * Asserts that a promise rejects with a string revert message
62
+ * Error(string) selector is 0x08c379a0
63
+ */
64
+ export async function expectRevertMessage(
65
+ promise: Promise<any>,
66
+ expectedMessage: string | RegExp
67
+ ): Promise<void> {
68
+ const ERROR_STRING_SELECTOR = "0x08c379a0";
69
+
70
+ try {
71
+ await promise;
72
+ throw new Error(`Expected revert with "${expectedMessage}" but transaction succeeded`);
73
+ } catch (e: any) {
74
+ if (e.message?.startsWith("Expected revert")) throw e;
75
+
76
+ const data = getErrorData(e);
77
+ if (!data) {
78
+ // Fallback to checking error message directly
79
+ const matches = typeof expectedMessage === 'string'
80
+ ? e.message?.includes(expectedMessage)
81
+ : expectedMessage.test(e.message);
82
+ if (!matches) {
83
+ throw new Error(`Expected revert with "${expectedMessage}" but got: ${e.message}`);
84
+ }
85
+ return;
86
+ }
87
+
88
+ const selector = data.slice(0, 10).toLowerCase();
89
+ if (selector !== ERROR_STRING_SELECTOR) {
90
+ // Not a string error, check if message is in the raw error
91
+ const matches = typeof expectedMessage === 'string'
92
+ ? e.message?.includes(expectedMessage)
93
+ : expectedMessage.test(e.message);
94
+ if (!matches) {
95
+ throw new Error(`Expected string revert but got custom error with selector ${selector}`);
96
+ }
97
+ return;
98
+ }
99
+
100
+ // Decode the string from the ABI-encoded data
101
+ // Format: selector (4 bytes) + offset (32 bytes) + length (32 bytes) + string data
102
+ try {
103
+ const abi: Abi = [{
104
+ type: 'error',
105
+ name: 'Error',
106
+ inputs: [{ name: 'message', type: 'string' }]
107
+ }];
108
+ const decoded = decodeErrorResult({ abi, data: data as `0x${string}` });
109
+ const message = (decoded.args as string[])[0];
110
+
111
+ const matches = typeof expectedMessage === 'string'
112
+ ? message.includes(expectedMessage)
113
+ : expectedMessage.test(message);
114
+
115
+ if (!matches) {
116
+ throw new Error(`Expected revert with "${expectedMessage}" but got "${message}"`);
117
+ }
118
+ } catch (decodeError) {
119
+ // If decoding fails, fall back to checking error message
120
+ const matches = typeof expectedMessage === 'string'
121
+ ? e.message?.includes(expectedMessage)
122
+ : expectedMessage.test(e.message);
123
+ if (!matches) {
124
+ throw new Error(`Expected revert with "${expectedMessage}" but decoding failed: ${e.message}`);
125
+ }
126
+ }
127
+ }
128
+ }
129
+
130
+ // Pre-computed selectors for common errors
131
+ export const ErrorSelectors = {
132
+ // TotemMod errors
133
+ InvalidModEventOrigin: errorSelector("InvalidModEventOrigin()"),
134
+ NotLicensed: errorSelector("NotLicensed()"),
135
+
136
+ // Totems errors
137
+ Unauthorized: errorSelector("Unauthorized()"),
138
+ TotemNotFound: errorSelector("TotemNotFound(string)"),
139
+ TotemNotActive: errorSelector("TotemNotActive()"),
140
+ InsufficientBalance: errorSelector("InsufficientBalance(uint256,uint256)"),
141
+ CantSetLicense: errorSelector("CantSetLicense()"),
142
+ };
143
+
144
+ export const MIN_BASE_FEE = 500000000000000n; // 0.0005 ether
145
+ export const BURNED_FEE = 100000000000000n; // 0.0001 ether
146
+
147
+ export const Hook = {
148
+ Created: 0,
149
+ Mint: 1,
150
+ Burn: 2,
151
+ Transfer: 3,
152
+ TransferOwnership: 4,
153
+ } as const;
154
+
155
+ export const setupTotemsTest = async (minBaseFee: bigint = MIN_BASE_FEE, burnedFee: bigint = BURNED_FEE) => {
156
+ const { viem } = await network.connect() as any;
157
+ const publicClient = await viem.getPublicClient();
158
+ // @ts-ignore
159
+ const walletClient = await viem.getWalletClient();
160
+
161
+ const addresses = await walletClient.getAddresses();
162
+ const proxyModInitializer = addresses[0];
163
+ const proxyMod = await viem.deployContract("ProxyMod", [
164
+ proxyModInitializer
165
+ ]);
166
+
167
+ let market = await viem.deployContract("ModMarket", [minBaseFee, burnedFee]);
168
+ let totems:any = await viem.deployContract("Totems", [
169
+ market.address,
170
+ proxyMod.address,
171
+ minBaseFee,
172
+ burnedFee,
173
+ ]);
174
+
175
+
176
+ // using these to validate the interfaces
177
+ totems = await viem.getContractAt("ITotems", totems.address);
178
+ // @ts-ignore
179
+ market = await viem.getContractAt("IMarket", market.address);
180
+ // initialize proxy mod
181
+ await proxyMod.write.initialize([totems.address, market.address], { account: proxyModInitializer });
182
+
183
+ return {
184
+ viem,
185
+ publicClient,
186
+ market,
187
+ totems,
188
+ accounts: addresses.slice(0, addresses.length),
189
+ proxyModSeller: addresses[0],
190
+ proxyMod,
191
+ }
192
+
193
+ }
194
+
195
+
196
+ export const modDetails = (details?:any) => Object.assign({
197
+ name: "Test Mod",
198
+ summary: "A test mod",
199
+ markdown: "## Test Mod\nThis is a test mod.",
200
+ image: "https://example.com/image.png",
201
+ website: "https://example.com",
202
+ websiteTickerPath: "/path/to/{ticker}",
203
+ isMinter: false,
204
+ needsUnlimited: false,
205
+ }, details || {});
206
+
207
+ export const publishMod = async (
208
+ market:any,
209
+ seller:string,
210
+ contract:string,
211
+ hooks:number[] = [],
212
+ details = modDetails(),
213
+ requiredActions:any[] = [],
214
+ referrer = ZERO_ADDRESS,
215
+ price = 1_000_000n,
216
+ fee = undefined
217
+ ) => {
218
+ fee = fee ?? await market.read.getFee([referrer]);
219
+
220
+ return market.write.publish([
221
+ contract,
222
+ hooks,
223
+ price,
224
+ details,
225
+ requiredActions,
226
+ referrer,
227
+ ], { value: fee, account: seller });
228
+ }
229
+
230
+ export const totemDetails = (ticker:string, decimals:number) => {
231
+ return {
232
+ ticker: ticker,
233
+ decimals: decimals,
234
+ name: `${ticker} Totem`,
235
+ description: `This is the ${ticker} totem.`,
236
+ image: `https://example.com/${ticker.toLowerCase()}.png`,
237
+ website: `https://example.com/${ticker.toLowerCase()}`,
238
+ seed: '0x1110762033e7a10db4502359a19a61eb81312834769b8419047a2c9ae03ee847',
239
+ };
240
+ }
241
+
242
+ export const createTotem = async (
243
+ totems:any,
244
+ market:any,
245
+ creator:string,
246
+ ticker:string,
247
+ decimals:number,
248
+ allocations:any[],
249
+ mods?:{
250
+ transfer?:string[],
251
+ mint?:string[],
252
+ burn?:string[],
253
+ created?:string[],
254
+ transferOwnership?:string[]
255
+ },
256
+ referrer:string = ZERO_ADDRESS,
257
+ details:any = undefined,
258
+ ) => {
259
+ const baseFee = await totems.read.getFee([referrer]);
260
+
261
+ const _mods = Object.assign({
262
+ transfer: [],
263
+ mint: [],
264
+ burn: [],
265
+ created: [],
266
+ transferOwnership: [],
267
+ }, mods || {});
268
+ const uniqueMods = new Set<string>();
269
+ Object.values(_mods).forEach((modList:any[]) => {
270
+ modList.forEach(m => uniqueMods.add(m));
271
+ });
272
+
273
+ const modsFee = await market.read.getModsFee([[...uniqueMods]]);
274
+ return await totems.write.create([
275
+ details ? Object.assign({
276
+ ticker,
277
+ decimals,
278
+ }, details) : totemDetails(ticker, decimals),
279
+ allocations.map(a => ({
280
+ ...a,
281
+ label: a.label || "",
282
+ isMinter: a.hasOwnProperty('isMinter') ? a.isMinter : false,
283
+ })),
284
+ _mods,
285
+ referrer,
286
+ ], { account: creator, value: baseFee + modsFee });
287
+ }
288
+
289
+ export const transfer = async (
290
+ totems:any,
291
+ ticker:string,
292
+ from:string,
293
+ to:string,
294
+ amount:number|bigint,
295
+ memo:string = "",
296
+ ) => {
297
+ return await totems.write.transfer([
298
+ ticker,
299
+ from,
300
+ to,
301
+ amount,
302
+ memo,
303
+ ], { account: from });
304
+ }
305
+
306
+ export const mint = async (
307
+ totems:any,
308
+ mod:string,
309
+ minter:string,
310
+ ticker:string,
311
+ amount:number|bigint,
312
+ memo:string = "",
313
+ payment:number|bigint = 0n,
314
+ ) => {
315
+ return await totems.write.mint([
316
+ mod,
317
+ minter,
318
+ ticker,
319
+ amount,
320
+ memo,
321
+ ], { account: minter, value: payment });
322
+ }
323
+
324
+ export const burn = async (
325
+ totems:any,
326
+ ticker:string,
327
+ owner:string,
328
+ amount:number|bigint,
329
+ memo:string = "",
330
+ ) => {
331
+ return await totems.write.burn([
332
+ ticker,
333
+ owner,
334
+ amount,
335
+ memo,
336
+ ], { account: owner });
337
+ }
338
+
339
+ export const getBalance = async (
340
+ totems:any,
341
+ ticker:string,
342
+ account:string,
343
+ ) => {
344
+ return await totems.read.getBalance([ticker, account]);
345
+ }
346
+
347
+ export const getTotem = async (
348
+ totems:any,
349
+ ticker:string,
350
+ ) => {
351
+ return await totems.read.getTotem([ticker]);
352
+ }
353
+
354
+ export const getTotems = async (
355
+ totems:any,
356
+ tickers:string[],
357
+ ) => {
358
+ return await totems.read.getTotems([tickers]);
359
+ }
360
+
361
+ export const getStats = async (
362
+ totems:any,
363
+ ticker:string,
364
+ ) => {
365
+ return await totems.read.getStats([ticker]);
366
+ }
367
+
368
+ export const transferOwnership = async (
369
+ totems:any,
370
+ ticker:string,
371
+ currentOwner:string,
372
+ newOwner:string,
373
+ ) => {
374
+ return await totems.write.transferOwnership([
375
+ ticker,
376
+ newOwner,
377
+ ], { account: currentOwner });
378
+ }
379
+
380
+ export const getMod = async (
381
+ market:any,
382
+ mod:string,
383
+ ) => {
384
+ return await market.read.getMod([mod]);
385
+ }
386
+
387
+ export const getMods = async (
388
+ market:any,
389
+ mods:string[],
390
+ ) => {
391
+ return await market.read.getMods([mods]);
392
+ }
393
+
394
+ export const getModFee = async (
395
+ market:any,
396
+ mod:string,
397
+ ) => {
398
+ return await market.read.getModFee([mod]);
399
+ }
400
+
401
+ export const getModsFee = async (
402
+ market:any,
403
+ mods:string[],
404
+ ) => {
405
+ return await market.read.getModsFee([mods]);
406
+ }
407
+
408
+ export const isLicensed = async (
409
+ totems:any,
410
+ ticker:string,
411
+ mod:string,
412
+ ) => {
413
+ return await totems.read.isLicensed([ticker, mod]);
414
+ }
415
+
416
+ export const getRelays = async (
417
+ totems:any,
418
+ ticker:string,
419
+ ) => {
420
+ return await totems.read.getRelays([ticker]);
421
+ }
422
+
423
+ export const getSupportedHooks = async (
424
+ market:any,
425
+ mod:string,
426
+ ) => {
427
+ return await market.read.getSupportedHooks([mod]);
428
+ }
429
+
430
+ export const isUnlimitedMinter = async (
431
+ market:any,
432
+ mod:string,
433
+ ) => {
434
+ return await market.read.isUnlimitedMinter([mod]);
435
+ }
436
+
437
+ export const addMod = async (
438
+ proxyMod:any,
439
+ totems:any,
440
+ market:any,
441
+ ticker:string,
442
+ hooks:number[],
443
+ mod:string,
444
+ caller:string,
445
+ referrer:string = ZERO_ADDRESS,
446
+ ) => {
447
+ const modFee = await market.read.getModFee([mod]);
448
+ const referrerFee = await totems.read.getFee([referrer]);
449
+ return await proxyMod.write.addMod([
450
+ ticker,
451
+ hooks,
452
+ mod,
453
+ referrer,
454
+ ], { account: caller, value: modFee + referrerFee });
455
+ }
456
+
457
+ export const removeMod = async (
458
+ proxyMod:any,
459
+ ticker:string,
460
+ mod:string,
461
+ caller:string,
462
+ ) => {
463
+ return await proxyMod.write.removeMod([
464
+ ticker,
465
+ mod,
466
+ ], { account: caller });
467
+ }
package/test/helpers.js DELETED
@@ -1,297 +0,0 @@
1
- // test/helpers.ts
2
- import {network} from "hardhat";
3
- import {keccak256, toBytes, decodeErrorResult} from "viem";
4
- function errorSelector(signature) {
5
- return keccak256(toBytes(signature)).slice(0, 10);
6
- }
7
- var getErrorData = function(error) {
8
- const data = error?.cause?.cause?.data || error?.cause?.data || error?.data || error?.message?.match(/return data: (0x[a-fA-F0-9]+)/)?.[1] || error?.message?.match(/data: (0x[a-fA-F0-9]+)/)?.[1];
9
- return data || null;
10
- };
11
- async function expectCustomError(promise, expectedSelector, errorName) {
12
- try {
13
- await promise;
14
- throw new Error(`Expected ${errorName} but transaction succeeded`);
15
- } catch (e) {
16
- if (e.message?.startsWith(`Expected ${errorName}`))
17
- throw e;
18
- const data = getErrorData(e);
19
- if (!data) {
20
- throw new Error(`Expected ${errorName} but got error without revert data: ${e.message}`);
21
- }
22
- const actualSelector = data.slice(0, 10).toLowerCase();
23
- const expected = expectedSelector.toLowerCase();
24
- if (actualSelector !== expected) {
25
- throw new Error(`Expected ${errorName} (${expected}) but got selector ${actualSelector}\nFull data: ${data}`);
26
- }
27
- }
28
- }
29
- async function expectRevertMessage(promise, expectedMessage) {
30
- const ERROR_STRING_SELECTOR = "0x08c379a0";
31
- try {
32
- await promise;
33
- throw new Error(`Expected revert with "${expectedMessage}" but transaction succeeded`);
34
- } catch (e) {
35
- if (e.message?.startsWith("Expected revert"))
36
- throw e;
37
- const data = getErrorData(e);
38
- if (!data) {
39
- const matches = typeof expectedMessage === "string" ? e.message?.includes(expectedMessage) : expectedMessage.test(e.message);
40
- if (!matches) {
41
- throw new Error(`Expected revert with "${expectedMessage}" but got: ${e.message}`);
42
- }
43
- return;
44
- }
45
- const selector = data.slice(0, 10).toLowerCase();
46
- if (selector !== ERROR_STRING_SELECTOR) {
47
- const matches = typeof expectedMessage === "string" ? e.message?.includes(expectedMessage) : expectedMessage.test(e.message);
48
- if (!matches) {
49
- throw new Error(`Expected string revert but got custom error with selector ${selector}`);
50
- }
51
- return;
52
- }
53
- try {
54
- const abi = [{
55
- type: "error",
56
- name: "Error",
57
- inputs: [{ name: "message", type: "string" }]
58
- }];
59
- const decoded = decodeErrorResult({ abi, data });
60
- const message = decoded.args[0];
61
- const matches = typeof expectedMessage === "string" ? message.includes(expectedMessage) : expectedMessage.test(message);
62
- if (!matches) {
63
- throw new Error(`Expected revert with "${expectedMessage}" but got "${message}"`);
64
- }
65
- } catch (decodeError) {
66
- const matches = typeof expectedMessage === "string" ? e.message?.includes(expectedMessage) : expectedMessage.test(e.message);
67
- if (!matches) {
68
- throw new Error(`Expected revert with "${expectedMessage}" but decoding failed: ${e.message}`);
69
- }
70
- }
71
- }
72
- }
73
- var ZERO_ADDRESS = "0x0000000000000000000000000000000000000000";
74
- var ErrorSelectors = {
75
- InvalidModEventOrigin: errorSelector("InvalidModEventOrigin()"),
76
- NotLicensed: errorSelector("NotLicensed()"),
77
- Unauthorized: errorSelector("Unauthorized()"),
78
- TotemNotFound: errorSelector("TotemNotFound(string)"),
79
- TotemNotActive: errorSelector("TotemNotActive()"),
80
- InsufficientBalance: errorSelector("InsufficientBalance(uint256,uint256)"),
81
- CantSetLicense: errorSelector("CantSetLicense()")
82
- };
83
- var MIN_BASE_FEE = 500000000000000n;
84
- var BURNED_FEE = 100000000000000n;
85
- var Hook = {
86
- Created: 0,
87
- Mint: 1,
88
- Burn: 2,
89
- Transfer: 3,
90
- TransferOwnership: 4
91
- };
92
- var setupTotemsTest = async (minBaseFee = MIN_BASE_FEE, burnedFee = BURNED_FEE) => {
93
- const { viem } = await network.connect();
94
- const publicClient = await viem.getPublicClient();
95
- const walletClient = await viem.getWalletClient();
96
- const addresses = await walletClient.getAddresses();
97
- const proxyModInitializer = addresses[0];
98
- const proxyMod = await viem.deployContract("ProxyMod", [
99
- proxyModInitializer
100
- ]);
101
- let market = await viem.deployContract("ModMarket", [minBaseFee, burnedFee]);
102
- let totems = await viem.deployContract("Totems", [
103
- market.address,
104
- proxyMod.address,
105
- minBaseFee,
106
- burnedFee
107
- ]);
108
- totems = await viem.getContractAt("ITotems", totems.address);
109
- market = await viem.getContractAt("IMarket", market.address);
110
- await proxyMod.write.initialize([totems.address, market.address], { account: proxyModInitializer });
111
- return {
112
- viem,
113
- publicClient,
114
- market,
115
- totems,
116
- accounts: addresses.slice(0, addresses.length),
117
- proxyModSeller: addresses[0],
118
- proxyMod
119
- };
120
- };
121
- var modDetails = (details) => Object.assign({
122
- name: "Test Mod",
123
- summary: "A test mod",
124
- markdown: "## Test Mod\nThis is a test mod.",
125
- image: "https://example.com/image.png",
126
- website: "https://example.com",
127
- websiteTickerPath: "/path/to/{ticker}",
128
- isMinter: false,
129
- needsUnlimited: false
130
- }, details || {});
131
- var publishMod = async (market, seller, contract, hooks = [], details = modDetails(), requiredActions = [], referrer = ZERO_ADDRESS, price = 1000000n, fee = undefined) => {
132
- fee = fee ?? await market.read.getFee([referrer]);
133
- return market.write.publish([
134
- contract,
135
- hooks,
136
- price,
137
- details,
138
- requiredActions,
139
- referrer
140
- ], { value: fee, account: seller });
141
- };
142
- var totemDetails = (ticker, decimals) => {
143
- return {
144
- ticker,
145
- decimals,
146
- name: `${ticker} Totem`,
147
- description: `This is the ${ticker} totem.`,
148
- image: `https://example.com/${ticker.toLowerCase()}.png`,
149
- website: `https://example.com/${ticker.toLowerCase()}`,
150
- seed: "0x1110762033e7a10db4502359a19a61eb81312834769b8419047a2c9ae03ee847"
151
- };
152
- };
153
- var createTotem = async (totems, market, creator, ticker, decimals, allocations, mods, referrer = ZERO_ADDRESS, details = undefined) => {
154
- const baseFee = await totems.read.getFee([referrer]);
155
- const _mods = Object.assign({
156
- transfer: [],
157
- mint: [],
158
- burn: [],
159
- created: [],
160
- transferOwnership: []
161
- }, mods || {});
162
- const uniqueMods = new Set;
163
- Object.values(_mods).forEach((modList) => {
164
- modList.forEach((m) => uniqueMods.add(m));
165
- });
166
- const modsFee = await market.read.getModsFee([[...uniqueMods]]);
167
- return await totems.write.create([
168
- details ? Object.assign({
169
- ticker,
170
- decimals
171
- }, details) : totemDetails(ticker, decimals),
172
- allocations.map((a) => ({
173
- ...a,
174
- label: a.label || "",
175
- isMinter: a.hasOwnProperty("isMinter") ? a.isMinter : false
176
- })),
177
- _mods,
178
- referrer
179
- ], { account: creator, value: baseFee + modsFee });
180
- };
181
- var transfer = async (totems, ticker, from, to, amount, memo = "") => {
182
- return await totems.write.transfer([
183
- ticker,
184
- from,
185
- to,
186
- amount,
187
- memo
188
- ], { account: from });
189
- };
190
- var mint = async (totems, mod, minter, ticker, amount, memo = "", payment = 0n) => {
191
- return await totems.write.mint([
192
- mod,
193
- minter,
194
- ticker,
195
- amount,
196
- memo
197
- ], { account: minter, value: payment });
198
- };
199
- var burn = async (totems, ticker, owner, amount, memo = "") => {
200
- return await totems.write.burn([
201
- ticker,
202
- owner,
203
- amount,
204
- memo
205
- ], { account: owner });
206
- };
207
- var getBalance = async (totems, ticker, account) => {
208
- return await totems.read.getBalance([ticker, account]);
209
- };
210
- var getTotem = async (totems, ticker) => {
211
- return await totems.read.getTotem([ticker]);
212
- };
213
- var getTotems = async (totems, tickers) => {
214
- return await totems.read.getTotems([tickers]);
215
- };
216
- var getStats = async (totems, ticker) => {
217
- return await totems.read.getStats([ticker]);
218
- };
219
- var transferOwnership = async (totems, ticker, currentOwner, newOwner) => {
220
- return await totems.write.transferOwnership([
221
- ticker,
222
- newOwner
223
- ], { account: currentOwner });
224
- };
225
- var getMod = async (market, mod) => {
226
- return await market.read.getMod([mod]);
227
- };
228
- var getMods = async (market, mods) => {
229
- return await market.read.getMods([mods]);
230
- };
231
- var getModFee = async (market, mod) => {
232
- return await market.read.getModFee([mod]);
233
- };
234
- var getModsFee = async (market, mods) => {
235
- return await market.read.getModsFee([mods]);
236
- };
237
- var isLicensed = async (totems, ticker, mod) => {
238
- return await totems.read.isLicensed([ticker, mod]);
239
- };
240
- var getRelays = async (totems, ticker) => {
241
- return await totems.read.getRelays([ticker]);
242
- };
243
- var getSupportedHooks = async (market, mod) => {
244
- return await market.read.getSupportedHooks([mod]);
245
- };
246
- var isUnlimitedMinter = async (market, mod) => {
247
- return await market.read.isUnlimitedMinter([mod]);
248
- };
249
- var addMod = async (proxyMod, totems, market, ticker, hooks, mod, caller, referrer = ZERO_ADDRESS) => {
250
- const modFee = await market.read.getModFee([mod]);
251
- const referrerFee = await totems.read.getFee([referrer]);
252
- return await proxyMod.write.addMod([
253
- ticker,
254
- hooks,
255
- mod,
256
- referrer
257
- ], { account: caller, value: modFee + referrerFee });
258
- };
259
- var removeMod = async (proxyMod, ticker, mod, caller) => {
260
- return await proxyMod.write.removeMod([
261
- ticker,
262
- mod
263
- ], { account: caller });
264
- };
265
- export {
266
- transferOwnership,
267
- transfer,
268
- totemDetails,
269
- setupTotemsTest,
270
- removeMod,
271
- publishMod,
272
- modDetails,
273
- mint,
274
- isUnlimitedMinter,
275
- isLicensed,
276
- getTotems,
277
- getTotem,
278
- getSupportedHooks,
279
- getStats,
280
- getRelays,
281
- getModsFee,
282
- getMods,
283
- getModFee,
284
- getMod,
285
- getBalance,
286
- expectRevertMessage,
287
- expectCustomError,
288
- errorSelector,
289
- createTotem,
290
- burn,
291
- addMod,
292
- ZERO_ADDRESS,
293
- MIN_BASE_FEE,
294
- Hook,
295
- ErrorSelectors,
296
- BURNED_FEE
297
- };