@leofcoin/contracts 0.1.13 → 0.1.15
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/.github/workflows/test.yml +33 -0
- package/.prettierrc +11 -11
- package/.size-log.json +115 -0
- package/LICENSE +20 -20
- package/README.md +27 -1
- package/exports/factory.d.ts +6 -3
- package/exports/factory.js +1 -1
- package/exports/name-service.js +1 -1
- package/exports/native-token.d.ts +1 -0
- package/exports/native-token.js +1 -1
- package/exports/power-token.js +1 -1
- package/exports/validators.d.ts +2 -5
- package/exports/validators.js +1 -1
- package/package.json +42 -43
- package/rollup.config.js +86 -86
- package/scripts/track-size.js +129 -0
- package/src/chat.ts +25 -25
- package/src/factory.ts +79 -73
- package/src/name-service.ts +93 -92
- package/src/native-token.ts +13 -7
- package/src/power-token.ts +7 -7
- package/src/validators.ts +148 -147
- package/test/factory.js +65 -66
- package/test/native-token.js +86 -96
- package/test/validators.js +119 -120
- package/tsconfig.json +14 -13
package/rollup.config.js
CHANGED
|
@@ -1,86 +1,86 @@
|
|
|
1
|
-
import typescript from '@rollup/plugin-typescript'
|
|
2
|
-
import terser from '@rollup/plugin-terser'
|
|
3
|
-
import resolve from '@rollup/plugin-node-resolve'
|
|
4
|
-
|
|
5
|
-
export default [
|
|
6
|
-
{
|
|
7
|
-
input: './src/factory.ts',
|
|
8
|
-
output: {
|
|
9
|
-
dir: './exports',
|
|
10
|
-
format: 'es'
|
|
11
|
-
},
|
|
12
|
-
plugins: [
|
|
13
|
-
resolve({
|
|
14
|
-
mainFields: ['exports']
|
|
15
|
-
}),
|
|
16
|
-
typescript(),
|
|
17
|
-
terser({
|
|
18
|
-
mangle: false
|
|
19
|
-
})
|
|
20
|
-
]
|
|
21
|
-
},
|
|
22
|
-
{
|
|
23
|
-
input: './src/name-service.ts',
|
|
24
|
-
output: {
|
|
25
|
-
dir: './exports',
|
|
26
|
-
format: 'es'
|
|
27
|
-
},
|
|
28
|
-
plugins: [
|
|
29
|
-
resolve({
|
|
30
|
-
mainFields: ['exports']
|
|
31
|
-
}),
|
|
32
|
-
typescript(),
|
|
33
|
-
terser({
|
|
34
|
-
mangle: false
|
|
35
|
-
})
|
|
36
|
-
]
|
|
37
|
-
},
|
|
38
|
-
{
|
|
39
|
-
input: './src/native-token.ts',
|
|
40
|
-
output: {
|
|
41
|
-
dir: './exports',
|
|
42
|
-
format: 'es'
|
|
43
|
-
},
|
|
44
|
-
plugins: [
|
|
45
|
-
resolve({
|
|
46
|
-
mainFields: ['exports']
|
|
47
|
-
}),
|
|
48
|
-
typescript(),
|
|
49
|
-
terser({
|
|
50
|
-
mangle: false
|
|
51
|
-
})
|
|
52
|
-
]
|
|
53
|
-
},
|
|
54
|
-
{
|
|
55
|
-
input: './src/power-token.ts',
|
|
56
|
-
output: {
|
|
57
|
-
dir: './exports',
|
|
58
|
-
format: 'es'
|
|
59
|
-
},
|
|
60
|
-
plugins: [
|
|
61
|
-
resolve({
|
|
62
|
-
mainFields: ['exports']
|
|
63
|
-
}),
|
|
64
|
-
typescript(),
|
|
65
|
-
terser({
|
|
66
|
-
mangle: false
|
|
67
|
-
})
|
|
68
|
-
]
|
|
69
|
-
},
|
|
70
|
-
{
|
|
71
|
-
input: './src/validators.ts',
|
|
72
|
-
output: {
|
|
73
|
-
dir: './exports',
|
|
74
|
-
format: 'es'
|
|
75
|
-
},
|
|
76
|
-
plugins: [
|
|
77
|
-
resolve({
|
|
78
|
-
mainFields: ['exports']
|
|
79
|
-
}),
|
|
80
|
-
typescript(),
|
|
81
|
-
terser({
|
|
82
|
-
mangle: false
|
|
83
|
-
})
|
|
84
|
-
]
|
|
85
|
-
}
|
|
86
|
-
]
|
|
1
|
+
import typescript from '@rollup/plugin-typescript'
|
|
2
|
+
import terser from '@rollup/plugin-terser'
|
|
3
|
+
import resolve from '@rollup/plugin-node-resolve'
|
|
4
|
+
|
|
5
|
+
export default [
|
|
6
|
+
{
|
|
7
|
+
input: './src/factory.ts',
|
|
8
|
+
output: {
|
|
9
|
+
dir: './exports',
|
|
10
|
+
format: 'es'
|
|
11
|
+
},
|
|
12
|
+
plugins: [
|
|
13
|
+
resolve({
|
|
14
|
+
mainFields: ['exports']
|
|
15
|
+
}),
|
|
16
|
+
typescript(),
|
|
17
|
+
terser({
|
|
18
|
+
mangle: false
|
|
19
|
+
})
|
|
20
|
+
]
|
|
21
|
+
},
|
|
22
|
+
{
|
|
23
|
+
input: './src/name-service.ts',
|
|
24
|
+
output: {
|
|
25
|
+
dir: './exports',
|
|
26
|
+
format: 'es'
|
|
27
|
+
},
|
|
28
|
+
plugins: [
|
|
29
|
+
resolve({
|
|
30
|
+
mainFields: ['exports']
|
|
31
|
+
}),
|
|
32
|
+
typescript(),
|
|
33
|
+
terser({
|
|
34
|
+
mangle: false
|
|
35
|
+
})
|
|
36
|
+
]
|
|
37
|
+
},
|
|
38
|
+
{
|
|
39
|
+
input: './src/native-token.ts',
|
|
40
|
+
output: {
|
|
41
|
+
dir: './exports',
|
|
42
|
+
format: 'es'
|
|
43
|
+
},
|
|
44
|
+
plugins: [
|
|
45
|
+
resolve({
|
|
46
|
+
mainFields: ['exports']
|
|
47
|
+
}),
|
|
48
|
+
typescript(),
|
|
49
|
+
terser({
|
|
50
|
+
mangle: false
|
|
51
|
+
})
|
|
52
|
+
]
|
|
53
|
+
},
|
|
54
|
+
{
|
|
55
|
+
input: './src/power-token.ts',
|
|
56
|
+
output: {
|
|
57
|
+
dir: './exports',
|
|
58
|
+
format: 'es'
|
|
59
|
+
},
|
|
60
|
+
plugins: [
|
|
61
|
+
resolve({
|
|
62
|
+
mainFields: ['exports']
|
|
63
|
+
}),
|
|
64
|
+
typescript(),
|
|
65
|
+
terser({
|
|
66
|
+
mangle: false
|
|
67
|
+
})
|
|
68
|
+
]
|
|
69
|
+
},
|
|
70
|
+
{
|
|
71
|
+
input: './src/validators.ts',
|
|
72
|
+
output: {
|
|
73
|
+
dir: './exports',
|
|
74
|
+
format: 'es'
|
|
75
|
+
},
|
|
76
|
+
plugins: [
|
|
77
|
+
resolve({
|
|
78
|
+
mainFields: ['exports']
|
|
79
|
+
}),
|
|
80
|
+
typescript(),
|
|
81
|
+
terser({
|
|
82
|
+
mangle: false
|
|
83
|
+
})
|
|
84
|
+
]
|
|
85
|
+
}
|
|
86
|
+
]
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { readFileSync, writeFileSync, statSync, readdirSync, existsSync } from 'fs'
|
|
3
|
+
import { join } from 'path'
|
|
4
|
+
|
|
5
|
+
function getDirectorySize(dirPath) {
|
|
6
|
+
let totalSize = 0
|
|
7
|
+
|
|
8
|
+
function calculateSize(path) {
|
|
9
|
+
const stats = statSync(path)
|
|
10
|
+
if (stats.isFile()) {
|
|
11
|
+
totalSize += stats.size
|
|
12
|
+
} else if (stats.isDirectory()) {
|
|
13
|
+
const files = readdirSync(path)
|
|
14
|
+
for (const file of files) {
|
|
15
|
+
calculateSize(join(path, file))
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
calculateSize(dirPath)
|
|
21
|
+
return totalSize
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
function formatBytes(bytes) {
|
|
25
|
+
if (bytes === 0) return '0 Bytes'
|
|
26
|
+
const k = 1024
|
|
27
|
+
const sizes = ['Bytes', 'KB', 'MB', 'GB']
|
|
28
|
+
const i = Math.floor(Math.log(bytes) / Math.log(k))
|
|
29
|
+
return Math.round((bytes / Math.pow(k, i)) * 100) / 100 + ' ' + sizes[i]
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
const pkg = JSON.parse(readFileSync('package.json', 'utf-8'))
|
|
33
|
+
const logPath = '.size-log.json'
|
|
34
|
+
|
|
35
|
+
// Calculate package size (exports directory)
|
|
36
|
+
const exportsSize = getDirectorySize('exports')
|
|
37
|
+
|
|
38
|
+
// Calculate node_modules size
|
|
39
|
+
const nodeModulesSize = existsSync('node_modules') ? getDirectorySize('node_modules') : 0
|
|
40
|
+
|
|
41
|
+
// Count dependencies
|
|
42
|
+
const deps = Object.keys(pkg.dependencies || {}).length
|
|
43
|
+
const devDeps = Object.keys(pkg.devDependencies || {}).length
|
|
44
|
+
const totalDeps = deps + devDeps
|
|
45
|
+
|
|
46
|
+
// Create entry
|
|
47
|
+
const entry = {
|
|
48
|
+
version: pkg.version,
|
|
49
|
+
timestamp: new Date().toISOString(),
|
|
50
|
+
size: {
|
|
51
|
+
bytes: exportsSize,
|
|
52
|
+
formatted: formatBytes(exportsSize)
|
|
53
|
+
},
|
|
54
|
+
nodeModules: {
|
|
55
|
+
bytes: nodeModulesSize,
|
|
56
|
+
formatted: formatBytes(nodeModulesSize)
|
|
57
|
+
},
|
|
58
|
+
dependencies: {
|
|
59
|
+
production: deps,
|
|
60
|
+
development: devDeps,
|
|
61
|
+
total: totalDeps
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
// Load existing log or create new one
|
|
66
|
+
let log = { entries: [] }
|
|
67
|
+
if (existsSync(logPath)) {
|
|
68
|
+
try {
|
|
69
|
+
log = JSON.parse(readFileSync(logPath, 'utf-8'))
|
|
70
|
+
} catch (e) {
|
|
71
|
+
console.warn('Could not read existing log, creating new one')
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
// Add new entry
|
|
76
|
+
log.entries.push(entry)
|
|
77
|
+
|
|
78
|
+
// Keep only last 50 entries
|
|
79
|
+
if (log.entries.length > 50) {
|
|
80
|
+
log.entries = log.entries.slice(-50)
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
// Save log
|
|
84
|
+
writeFileSync(logPath, JSON.stringify(log, null, 2))
|
|
85
|
+
|
|
86
|
+
// Display summary
|
|
87
|
+
console.log('\n📦 Package Size Tracking')
|
|
88
|
+
console.log('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━')
|
|
89
|
+
console.log(`Version: ${entry.version}`)
|
|
90
|
+
console.log(`Build Size: ${entry.size.formatted}`)
|
|
91
|
+
console.log(`node_modules: ${entry.nodeModules.formatted}`)
|
|
92
|
+
console.log(
|
|
93
|
+
`Dependencies: ${entry.dependencies.production} prod + ${entry.dependencies.development} dev = ${entry.dependencies.total} total`
|
|
94
|
+
)
|
|
95
|
+
|
|
96
|
+
// Show trend if we have previous entries
|
|
97
|
+
if (log.entries.length > 1) {
|
|
98
|
+
const prev = log.entries[log.entries.length - 2]
|
|
99
|
+
const sizeDiff = entry.size.bytes - prev.size.bytes
|
|
100
|
+
const depDiff = entry.dependencies.total - prev.dependencies.total
|
|
101
|
+
|
|
102
|
+
if (sizeDiff !== 0) {
|
|
103
|
+
const sign = sizeDiff > 0 ? '+' : ''
|
|
104
|
+
console.log(
|
|
105
|
+
`Size Change: ${sign}${formatBytes(Math.abs(sizeDiff))} (${sign}${(
|
|
106
|
+
(sizeDiff / prev.size.bytes) *
|
|
107
|
+
100
|
|
108
|
+
).toFixed(1)}%)`
|
|
109
|
+
)
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
const nodeModulesDiff = entry.nodeModules.bytes - (prev.nodeModules?.bytes || 0)
|
|
113
|
+
if (nodeModulesDiff !== 0 && prev.nodeModules) {
|
|
114
|
+
const sign = nodeModulesDiff > 0 ? '+' : ''
|
|
115
|
+
console.log(
|
|
116
|
+
`node_modules: ${sign}${formatBytes(Math.abs(nodeModulesDiff))} (${sign}${(
|
|
117
|
+
(nodeModulesDiff / prev.nodeModules.bytes) *
|
|
118
|
+
100
|
|
119
|
+
).toFixed(1)}%)`
|
|
120
|
+
)
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
if (depDiff !== 0) {
|
|
124
|
+
const sign = depDiff > 0 ? '+' : ''
|
|
125
|
+
console.log(`Dependency Change: ${sign}${depDiff}`)
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
console.log('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n')
|
package/src/chat.ts
CHANGED
|
@@ -1,25 +1,25 @@
|
|
|
1
|
-
import { TokenReceiver } from '@leofcoin/standards'
|
|
2
|
-
import { TokenReceiverState } from '@leofcoin/standards/token-receiver'
|
|
3
|
-
|
|
4
|
-
export interface chatState extends TokenReceiverState {
|
|
5
|
-
nicknames: { [address: string]: string }
|
|
6
|
-
}
|
|
7
|
-
|
|
8
|
-
export default class Chat extends TokenReceiver {
|
|
9
|
-
#name = 'LeofcoinChat'
|
|
10
|
-
|
|
11
|
-
#nicknames: chatState['nicknames'] = {}
|
|
12
|
-
|
|
13
|
-
constructor(tokenToReceive, tokenAmountToReceive, state) {
|
|
14
|
-
super(tokenToReceive, tokenAmountToReceive, true, state as TokenReceiverState)
|
|
15
|
-
if (state) {
|
|
16
|
-
this.#nicknames = state.nicknames || {}
|
|
17
|
-
}
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
async changeNickName(newName: string) {
|
|
21
|
-
await this.
|
|
22
|
-
await this._payTokenToReceive()
|
|
23
|
-
this.#nicknames[msg.sender] = newName
|
|
24
|
-
}
|
|
25
|
-
}
|
|
1
|
+
import { TokenReceiver } from '@leofcoin/standards'
|
|
2
|
+
import { TokenReceiverState } from '@leofcoin/standards/token-receiver'
|
|
3
|
+
|
|
4
|
+
export interface chatState extends TokenReceiverState {
|
|
5
|
+
nicknames: { [address: string]: string }
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
export default class Chat extends TokenReceiver {
|
|
9
|
+
#name = 'LeofcoinChat'
|
|
10
|
+
|
|
11
|
+
#nicknames: chatState['nicknames'] = {}
|
|
12
|
+
|
|
13
|
+
constructor(tokenToReceive, tokenAmountToReceive, state) {
|
|
14
|
+
super(tokenToReceive, tokenAmountToReceive, true, state as TokenReceiverState)
|
|
15
|
+
if (state) {
|
|
16
|
+
this.#nicknames = state.nicknames || {}
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
async changeNickName(newName: string) {
|
|
21
|
+
await this._canVote()
|
|
22
|
+
await this._payTokenToReceive()
|
|
23
|
+
this.#nicknames[msg.sender] = newName
|
|
24
|
+
}
|
|
25
|
+
}
|
package/src/factory.ts
CHANGED
|
@@ -1,73 +1,79 @@
|
|
|
1
|
-
import { PublicVoting, TokenReceiver } from '@leofcoin/standards'
|
|
2
|
-
|
|
3
|
-
import { TokenReceiverState } from '@leofcoin/standards/token-receiver'
|
|
4
|
-
|
|
5
|
-
export interface FactoryState extends TokenReceiverState {
|
|
6
|
-
contracts: any[]
|
|
7
|
-
totalContracts: bigint
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
export default class Factory extends TokenReceiver {
|
|
11
|
-
/**
|
|
12
|
-
* string
|
|
13
|
-
*/
|
|
14
|
-
#name = 'LeofcoinContractFactory'
|
|
15
|
-
/**
|
|
16
|
-
* uint
|
|
17
|
-
*/
|
|
18
|
-
#totalContracts: bigint = BigInt(0)
|
|
19
|
-
/**
|
|
20
|
-
* Array => string
|
|
21
|
-
*/
|
|
22
|
-
#contracts: address[] = []
|
|
23
|
-
|
|
24
|
-
constructor(tokenToReceive: address, tokenAmountToReceive: bigint, state: FactoryState) {
|
|
25
|
-
super(tokenToReceive, tokenAmountToReceive, true, state as TokenReceiverState)
|
|
26
|
-
if (state) {
|
|
27
|
-
this.#contracts = state.contracts
|
|
28
|
-
this.#totalContracts = state.totalContracts
|
|
29
|
-
}
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
get state():
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
*
|
|
63
|
-
*/
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
1
|
+
import { PublicVoting, TokenReceiver } from '@leofcoin/standards'
|
|
2
|
+
|
|
3
|
+
import { TokenReceiverState } from '@leofcoin/standards/token-receiver.js'
|
|
4
|
+
|
|
5
|
+
export interface FactoryState extends TokenReceiverState {
|
|
6
|
+
contracts: any[]
|
|
7
|
+
totalContracts: bigint
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export default class Factory extends TokenReceiver {
|
|
11
|
+
/**
|
|
12
|
+
* string
|
|
13
|
+
*/
|
|
14
|
+
#name = 'LeofcoinContractFactory'
|
|
15
|
+
/**
|
|
16
|
+
* uint
|
|
17
|
+
*/
|
|
18
|
+
#totalContracts: bigint = BigInt(0)
|
|
19
|
+
/**
|
|
20
|
+
* Array => string
|
|
21
|
+
*/
|
|
22
|
+
#contracts: address[] = []
|
|
23
|
+
|
|
24
|
+
constructor(tokenToReceive: address, tokenAmountToReceive: bigint, state: FactoryState) {
|
|
25
|
+
super(tokenToReceive, tokenAmountToReceive, true, state as TokenReceiverState)
|
|
26
|
+
if (state) {
|
|
27
|
+
this.#contracts = state.contracts
|
|
28
|
+
this.#totalContracts = state.totalContracts
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
get state(): FactoryState {
|
|
33
|
+
const baseState = super.state as TokenReceiverState
|
|
34
|
+
return {
|
|
35
|
+
...baseState,
|
|
36
|
+
totalContracts: this.#totalContracts,
|
|
37
|
+
contracts: this.#contracts
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
get name() {
|
|
42
|
+
return this.#name
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
get contracts() {
|
|
46
|
+
return [...this.#contracts]
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
get totalContracts() {
|
|
50
|
+
return this.#totalContracts
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
isRegistered(address: any) {
|
|
54
|
+
return this.#contracts.includes(address)
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
#isCreator(address: address) {
|
|
58
|
+
return msg.staticCall(address, 'creator', [msg.sender]) as unknown as boolean
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* Public hook for creator check to ease testing/stubbing.
|
|
63
|
+
*/
|
|
64
|
+
isCreator(address: address) {
|
|
65
|
+
return this.#isCreator(address)
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
*
|
|
70
|
+
* @param {Address} address contract address to register
|
|
71
|
+
*/
|
|
72
|
+
async registerContract(address: string) {
|
|
73
|
+
if (!(await this.isCreator(address))) throw new Error(`You don't own that contract`)
|
|
74
|
+
if (this.#contracts.includes(address)) throw new Error('already registered')
|
|
75
|
+
await this._payTokenToReceive()
|
|
76
|
+
this.#totalContracts += 1n
|
|
77
|
+
this.#contracts.push(address)
|
|
78
|
+
}
|
|
79
|
+
}
|