@@ -12,6 +12,8 @@ type AddressObject = {
12
12
const indexerToNetwork : Record < string , string > = {
13
13
ada_balance : 'cardano' ,
14
14
eth_balance : 'ethereum' ,
15
+ eth_beacon : 'beacon' ,
16
+ avalanche_platform : 'avalanche' ,
15
17
bitcoin_json_rpc : 'bitcoin' ,
16
18
lotus : 'filecoin' ,
17
19
}
@@ -44,9 +46,12 @@ export const validateAddresses = (
44
46
) : AddressObject [ ] => {
45
47
const validatedAddresses : AddressObject [ ] = [ ]
46
48
for ( const addressObj of addresses ) {
47
- const { address, network } = addressObj
49
+ const { address, network, chainId } = addressObj
48
50
let validatedAddress : string | undefined = undefined
49
- const validationNetwork = network || indexerToNetwork [ indexer ]
51
+ let validationNetwork = network || indexerToNetwork [ indexer ]
52
+ // If the indexer is eth_beacon, override the validationNetwork as it might contain a different value (goerli, ethereum, mainnet...)
53
+ validationNetwork = indexer === 'eth_beacon' ? 'beacon' : validationNetwork
54
+
50
55
switch ( validationNetwork . toLowerCase ( ) ) {
51
56
case 'ethereum' :
52
57
validatedAddress = getValidEvmAddress ( id , address )
@@ -58,11 +63,18 @@ export const validateAddresses = (
58
63
validatedAddress = getValidDogeAddress ( id , address )
59
64
break
60
65
case 'cardano' :
61
- validatedAddress = getValidCardanoAddress ( id , address )
66
+ validatedAddress = getValidCardanoAddress ( id , address , chainId )
62
67
break
63
68
case 'filecoin' :
64
69
validatedAddress = getValidFilecoinAddress ( id , address )
65
70
break
71
+ case 'beacon' :
72
+ validatedAddress = getValidBeaconValidatorAddress ( id , address )
73
+ break
74
+ case 'avalanche' :
75
+ case 'avalanche-fuji' :
76
+ validatedAddress = getValidAvalancheAddress ( id , address )
77
+ break
66
78
default :
67
79
Logger . debug (
68
80
`JobId ${ id } : There is no address validation procedure defined for the "${ network } " network.` ,
@@ -138,13 +150,32 @@ const getValidDogeAddress = (id: string, address: string): string | undefined =>
138
150
return
139
151
}
140
152
141
- const getValidCardanoAddress = ( id : string , address : string ) : string | undefined => {
142
- if ( address . slice ( 0 , 4 ) . toLowerCase ( ) === 'addr' && isBech32 ( address . slice ( 5 ) . toLowerCase ( ) ) )
153
+ const getValidCardanoAddress = (
154
+ id : string ,
155
+ address : string ,
156
+ chain = 'mainnet' ,
157
+ ) : string | undefined => {
158
+ if ( chain === 'mainnet' ) {
159
+ // Validation for 'shelley' addresses
160
+ if ( address . slice ( 0 , 4 ) . toLowerCase ( ) === 'addr' && isBech32 ( address . slice ( 5 ) . toLowerCase ( ) ) ) {
161
+ return address . toLowerCase ( )
162
+ }
163
+ // Validation for legacy 'byron' addresses
164
+ if ( isBase58 ( address ) ) {
165
+ return address
166
+ }
167
+ }
168
+ // Validation for testnet addresses
169
+ else if (
170
+ chain === 'testnet' &&
171
+ address . slice ( 0 , 10 ) . toLowerCase ( ) === 'addr_test1' &&
172
+ isBech32 ( address . slice ( 10 ) . toLowerCase ( ) )
173
+ ) {
143
174
return address . toLowerCase ( )
144
- if ( isBase58 ( address ) ) return address
175
+ }
145
176
Logger . warn (
146
177
{ warning : 'Invalid address detected' } ,
147
- `JobId ${ id } : The address "${ address } " is not a valid Dogecoin address and has been removed.` ,
178
+ `JobId ${ id } : The address "${ address } " is not a valid Cardano ${ chain } address and has been removed.` ,
148
179
)
149
180
return
150
181
}
@@ -170,6 +201,53 @@ const getValidFilecoinAddress = (id: string, address: string): string | undefine
170
201
return
171
202
}
172
203
204
+ const getValidAvalancheAddress = ( id : string , address : string ) : string | undefined => {
205
+ if ( address . substring ( 0 , 2 ) === '0x' ) {
206
+ // Validation for C-chain address
207
+ return getValidEvmAddress ( id , address )
208
+ }
209
+
210
+ // Validation for P nd X chain addresses
211
+ if ( ! address . startsWith ( 'X-' ) && ! address . startsWith ( 'P-' ) ) {
212
+ Logger . warn (
213
+ { warning : 'Invalid address detected' } ,
214
+ `JobId ${ id } : The address "${ address } " is not a valid Avalanche address and has been removed.` ,
215
+ )
216
+ return
217
+ }
218
+
219
+ const addressKey = address . substring ( 2 )
220
+ const addressParts = addressKey . split ( '1' )
221
+ const [ , bech32Part ] = [ addressParts . shift ( ) as string , addressParts . join ( '1' ) ]
222
+ if ( ! bech32Part . length || ! isBech32 ( bech32Part . toLowerCase ( ) ) ) {
223
+ Logger . warn (
224
+ { warning : 'Invalid address detected' } ,
225
+ `JobId ${ id } : The address "${ address } " is not a valid Avalanche address and has been removed.` ,
226
+ )
227
+ return
228
+ }
229
+
230
+ return address
231
+ }
232
+
233
+ const getValidBeaconValidatorAddress = ( id : string , address : string ) : string | undefined => {
234
+ try {
235
+ const parsedKey = utils . hexlify ( address )
236
+ // Validator address is 48 bytes + '0x' prefix
237
+ if ( parsedKey === '0x' . padEnd ( 98 , '0' ) || ! utils . isHexString ( parsedKey , 48 ) ) {
238
+ throw 'Invalid Address'
239
+ }
240
+ } catch ( e ) {
241
+ Logger . warn (
242
+ { warning : 'Invalid address detected' } ,
243
+ `JobId ${ id } : The address "${ address } " is not a valid Beacon validator address and has been removed.` ,
244
+ )
245
+ return
246
+ }
247
+
248
+ return address
249
+ }
250
+
173
251
export const filterDuplicates = ( id : string , addresses : AddressObject [ ] ) : AddressObject [ ] => {
174
252
const uniqueMap : Record < string , boolean > = { }
175
253
const uniqueAddresses : AddressObject [ ] = [ ]
0 commit comments