4
4
// To view a copy of this license, visit https://creativecommons.org/licenses/by/4.0/
5
5
// Author: Andreas Timm
6
6
// Repository: https://github.com/andreas-timm/code-signature-ts
7
- // Version: 0.3 .0
8
- // @sha 256sum 0x904d8038d8a3ae6144e5b4275c5f5c76b3d28bddf574ada8cc394fb091a3e2c5
9
- // @eip 191signature 0x6b55e4c5241cf7824a70f3f971b16be497ad5e2d808daca00280c975a5604a396a2fdfcf5d30d6f7c15c84a4f5a44d813311d7231acc7b2041a1aa20574e8c851b
7
+ // Version: 0.4 .0
8
+ // @sha 256sum 0xe901425d12469ef7e0fdd010e2d158d5398a8a6ae7e1a79bce1f77a6b9d3237b
9
+ // @eip 191signature 0x3b08f924e994205005312fec95c30e181fb066744ca51a17d122221953cda7e37abec4184e1755385cae7837cea1a6e6f74b3d336484026338bf6d2426e9f9be1c
10
10
11
11
import { parseArgs } from 'util'
12
12
import { hashMessage , recoverAddress , sha256 } from 'viem'
13
13
import { english , generateMnemonic , mnemonicToAccount } from 'viem/accounts'
14
14
import type { Options , SignResult , VerifyResult , CliOptions } from './types.ts'
15
15
16
- export function splitIndexLines ( content : string ) {
17
- return content . split ( / ( \n + ) / ) . reduce ( ( acc : string [ ] [ ] , part : string , index : number ) => {
18
- if ( index % 2 === 0 ) {
19
- acc . push ( [ part ] )
20
- } else {
21
- acc [ acc . length - 1 ] . push ( part )
22
- }
23
- return acc
24
- } , [ ] )
25
- }
26
-
27
16
export function getFilteredContent ( content : string , key : string , prefix : string , replace ?: string ) {
28
- const lines = splitIndexLines ( content )
29
17
let filtered = [ ]
30
18
let value : null | `0x${string } ` = null
19
+ const lines = content . split ( '\n' )
31
20
let index
21
+ let line : string
32
22
33
23
for ( index = 0 ; index < lines . length ; index ++ ) {
34
- if ( lines [ index ] [ 0 ] . match ( new RegExp ( `^\\s*([*#;"]|${ prefix } )?\\s*` + key ) ) ) {
35
- value = lines [ index ] [ 0 ] . match ( new RegExp ( `${ key } \\s+(\\S+)` ) ) ! [ 1 ] as `0x${string } `
24
+ line = lines [ index ]
25
+
26
+ if ( value === null && line . match ( new RegExp ( `^\\s*([*#;"]|${ prefix } )?\\s*${ key } 0x\\S+` ) ) ) {
27
+ value = line . match ( new RegExp ( `${ key } \\s+(0x\\S+)` ) ) ! [ 1 ] as `0x${string } `
36
28
if ( replace !== undefined ) {
37
- filtered . push (
38
- [
39
- lines [ index ] [ 0 ] . replace ( new RegExp ( `(${ key } \\s+)\\S+` ) , `\$1${ replace } ` ) ,
40
- lines [ index ] [ 1 ] ,
41
- ] . join ( '' ) ,
42
- )
29
+ line = line . replace ( new RegExp ( `(${ key } \\s+)\\S+` ) , `\$1${ replace } ` )
30
+ } else {
31
+ continue
43
32
}
44
- filtered = filtered . concat ( lines . splice ( index + 1 ) . map ( ( line ) => line . join ( '' ) ) )
45
- break
46
33
}
47
34
48
- filtered . push ( lines [ index ] . join ( '' ) )
35
+ filtered . push ( line )
49
36
}
50
37
51
- return { content : filtered . join ( '' ) , value }
38
+ return { content : filtered . join ( '\n ' ) , value }
52
39
}
53
40
54
41
export async function verify ( content : string , prefix : string ) : Promise < VerifyResult > {
@@ -87,30 +74,32 @@ export async function sign(verifyResult: VerifyResult, options: Options): Promis
87
74
console . log ( 'Address:' , account . address )
88
75
}
89
76
90
- let valid = account . address === verifyResult . address
91
- let signature : null | `0x${string } ` = null
92
- let toSha256Content : null | string = null
93
- let sha256sum : null | `0x${string } ` = null
94
- let signedContent : null | string = null
77
+ let signature : null | `0x${string } `
78
+ let toSha256Content : null | string
79
+ let sha256sum : null | `0x${string } `
80
+ let signedContent : null | string
95
81
96
- if ( ! valid || ! verifyResult . sha256Valid ) {
97
- signature = await account . signMessage ( { message : verifyResult . signFiltered . content } )
82
+ signature = await account . signMessage ( { message : verifyResult . signFiltered . content } )
98
83
99
- if ( verifyResult . signFiltered . value !== null ) {
100
- toSha256Content = getFilteredContent ( verifyResult . content , '@eip191signature' , options . prefix , signature ) . content
101
- } else {
102
- toSha256Content = [ `${ options . prefix } @eip191signature ` + signature , verifyResult . content ] . join ( '\n' )
103
- }
84
+ if ( verifyResult . signFiltered . value !== null ) {
85
+ toSha256Content = getFilteredContent (
86
+ verifyResult . content ,
87
+ '@eip191signature' ,
88
+ options . prefix ,
89
+ signature ,
90
+ ) . content
91
+ } else {
92
+ toSha256Content = [ `${ options . prefix } @eip191signature ` + signature , verifyResult . content ] . join ( '\n' )
93
+ }
104
94
105
- sha256sum = sha256 (
106
- new TextEncoder ( ) . encode ( getFilteredContent ( toSha256Content , '@sha256sum' , options . prefix ) . content ) ,
107
- )
95
+ sha256sum = sha256 (
96
+ new TextEncoder ( ) . encode ( getFilteredContent ( toSha256Content , '@sha256sum' , options . prefix ) . content ) ,
97
+ )
108
98
109
- if ( verifyResult . sha256Filtered . value !== null ) {
110
- signedContent = getFilteredContent ( toSha256Content , '@sha256sum' , options . prefix , sha256sum ) . content
111
- } else {
112
- signedContent = [ `${ options . prefix } @sha256sum ` + sha256sum , toSha256Content ] . join ( '\n' )
113
- }
99
+ if ( verifyResult . sha256Filtered . value !== null ) {
100
+ signedContent = getFilteredContent ( toSha256Content , '@sha256sum' , options . prefix , sha256sum ) . content
101
+ } else {
102
+ signedContent = [ `${ options . prefix } @sha256sum ` + sha256sum , toSha256Content ] . join ( '\n' )
114
103
}
115
104
116
105
return {
@@ -126,7 +115,7 @@ function printHelp() {
126
115
console . log ( 'Usage: code-signature-ts [OPTIONS] <FILE|->' )
127
116
console . log ( 'OPTIONS:' )
128
117
console . log ( ' --verify, -v — only verify' )
129
- console . log ( ' --write, -f — write file' )
118
+ console . log ( ' --write, -w — write file' )
130
119
console . log ( ' --silent, -s — silent' )
131
120
console . log ( ' --prefix, -p — commented line prefix' )
132
121
console . log ( ' --out, -o — output file' )
@@ -159,42 +148,48 @@ export async function codeSignature(options: Options) {
159
148
160
149
const verifyResult = await verify ( content , options . prefix )
161
150
let signResult : null | SignResult = null
162
- let fail = false
151
+ let fail = true
163
152
164
153
if ( verifyResult . sha256Valid ) {
165
154
if ( ! options . silent ) {
166
155
console . log ( `OK: ${ verifyResult . address } ` )
167
156
}
168
- } else if ( ! options . verify ) {
157
+ fail = false
158
+ }
159
+
160
+ if ( ! options . verify ) {
169
161
signResult = await sign ( verifyResult , options )
170
162
171
- if ( signResult . signedContent === null ) {
163
+ if ( signResult . signedContent !== null ) {
164
+ if ( options . write && fail ) {
165
+ await write ( options , signResult . signedContent )
166
+ }
167
+
168
+ if ( fail && ! options . write && ! options . silent ) {
169
+ console . log ( `${ options . prefix } @sha256sum ${ signResult . sha256sum } ` )
170
+ console . log ( `${ options . prefix } @eip191signature ${ signResult . signature } ` )
171
+ }
172
+ } else {
172
173
console . log ( 'ERROR: no signed content' )
173
174
fail = true
174
- } else if ( options . write ) {
175
- await write ( options , signResult . signedContent )
176
- } else if ( ! options . silent ) {
177
- console . log ( `${ options . prefix } @sha256sum ${ signResult . sha256sum } ` )
178
- console . log ( `${ options . prefix } @eip191signature ${ signResult . signature } ` )
179
175
}
180
- } else {
181
- if ( ! options . silent ) {
182
- console . log ( 'SHA256: ERROR' )
183
- }
184
- fail = true
176
+ }
177
+
178
+ if ( fail && ! options . silent ) {
179
+ console . log ( 'SHA256: ERROR' )
185
180
}
186
181
187
182
return { verifyResult, signResult, fail }
188
183
}
189
184
190
185
if ( import . meta. main ) {
191
- const { values, positionals} = parseArgs ( {
186
+ const { values, positionals } = parseArgs ( {
192
187
args : Bun . argv ,
193
188
options : {
194
- help : { type : 'boolean' , short : 'h' } ,
195
- write : { type : 'boolean' , short : 'w' } ,
196
- verify : { type : 'boolean' , short : 'v' } ,
197
- silent : { type : 'boolean' , short : 's' } ,
189
+ help : { type : 'boolean' , short : 'h' , default : false } ,
190
+ write : { type : 'boolean' , short : 'w' , default : false } ,
191
+ verify : { type : 'boolean' , short : 'v' , default : false } ,
192
+ silent : { type : 'boolean' , short : 's' , default : false } ,
198
193
prefix : { type : 'string' , short : 'p' , default : '//' } ,
199
194
out : { type : 'string' , short : 'o' } ,
200
195
} ,
0 commit comments