@@ -11,6 +11,7 @@ import type {
11
11
import { NameType } from './types' ;
12
12
13
13
const DEFAULT_UPDATE_DELAY = 60 * 2 ; // 2 Minutes
14
+ const DEFAULT_VARIATION = '' ;
14
15
15
16
const controllerName = 'NameController' ;
16
17
@@ -71,7 +72,6 @@ export type NameControllerMessenger = RestrictedControllerMessenger<
71
72
> ;
72
73
73
74
export type NameControllerOptions = {
74
- getChainId : ( ) => string ;
75
75
messenger : NameControllerMessenger ;
76
76
providers : NameProvider [ ] ;
77
77
state ?: Partial < NameControllerState > ;
@@ -83,6 +83,7 @@ export type UpdateProposedNamesRequest = {
83
83
type : NameType ;
84
84
sourceIds ?: string [ ] ;
85
85
onlyUpdateAfterDelay ?: boolean ;
86
+ variation ?: string ;
86
87
} ;
87
88
88
89
export type UpdateProposedNamesResult = {
@@ -94,6 +95,7 @@ export type SetNameRequest = {
94
95
type : NameType ;
95
96
name : string | null ;
96
97
sourceId ?: string ;
98
+ variation ?: string ;
97
99
} ;
98
100
99
101
/**
@@ -104,8 +106,6 @@ export class NameController extends BaseControllerV2<
104
106
NameControllerState ,
105
107
NameControllerMessenger
106
108
> {
107
- #getChainId: ( ) => string ;
108
-
109
109
#providers: NameProvider [ ] ;
110
110
111
111
#updateDelay: number ;
@@ -114,14 +114,12 @@ export class NameController extends BaseControllerV2<
114
114
* Construct a Name controller.
115
115
*
116
116
* @param options - Controller options.
117
- * @param options.getChainId - Callback that returns the chain ID of the current network.
118
117
* @param options.messenger - Restricted controller messenger for the name controller.
119
118
* @param options.providers - Array of name provider instances to propose names.
120
119
* @param options.state - Initial state to set on the controller.
121
120
* @param options.updateDelay - The delay in seconds before a new request to a source should be made.
122
121
*/
123
122
constructor ( {
124
- getChainId,
125
123
messenger,
126
124
providers,
127
125
state,
@@ -134,7 +132,6 @@ export class NameController extends BaseControllerV2<
134
132
state : { ...getDefaultState ( ) , ...state } ,
135
133
} ) ;
136
134
137
- this . #getChainId = getChainId ;
138
135
this . #providers = providers ;
139
136
this . #updateDelay = updateDelay ?? DEFAULT_UPDATE_DELAY ;
140
137
}
@@ -147,14 +144,15 @@ export class NameController extends BaseControllerV2<
147
144
* @param request.sourceId - Optional ID of the source of the proposed name.
148
145
* @param request.type - Type of value to set the name for.
149
146
* @param request.value - Value to set the name for.
147
+ * @param request.variation - Variation of the raw value to set the name for. The chain ID if the type is Ethereum address.
150
148
*/
151
149
setName ( request : SetNameRequest ) {
152
150
this . #validateSetNameRequest( request ) ;
153
151
154
- const { value, type, name, sourceId : requestSourceId } = request ;
152
+ const { value, type, name, sourceId : requestSourceId , variation } = request ;
155
153
const sourceId = requestSourceId ?? null ;
156
154
157
- this . #updateEntry( value , type , ( entry : NameEntry ) => {
155
+ this . #updateEntry( value , type , variation , ( entry : NameEntry ) => {
158
156
entry . name = name ;
159
157
entry . sourceId = sourceId ;
160
158
} ) ;
@@ -167,19 +165,18 @@ export class NameController extends BaseControllerV2<
167
165
* @param request.value - Value to update the proposed names for.
168
166
* @param request.type - Type of value to update the proposed names for.
169
167
* @param request.sourceIds - Optional array of source IDs to limit which sources are used by the providers. If not provided, all sources in all providers will be used.
168
+ * @param request.variation - Variation of the raw value to update proposed names for. The chain ID if the type is Ethereum address.
170
169
* @returns The updated proposed names for the value.
171
170
*/
172
171
async updateProposedNames (
173
172
request : UpdateProposedNamesRequest ,
174
173
) : Promise < UpdateProposedNamesResult > {
175
174
this . #validateUpdateProposedNamesRequest( request ) ;
176
175
177
- const chainId = this . #getChainId( ) ;
178
-
179
176
const providerResponses = (
180
177
await Promise . all (
181
178
this . #providers. map ( ( provider ) =>
182
- this . #getProviderResponse( request , chainId , provider ) ,
179
+ this . #getProviderResponse( request , provider ) ,
183
180
) ,
184
181
)
185
182
) . filter ( ( response ) => Boolean ( response ) ) as NameProviderResult [ ] ;
@@ -194,10 +191,10 @@ export class NameController extends BaseControllerV2<
194
191
request : UpdateProposedNamesRequest ,
195
192
providerResponses : NameProviderResult [ ] ,
196
193
) {
197
- const { value, type } = request ;
194
+ const { value, type, variation } = request ;
198
195
const currentTime = this . #getCurrentTimeSeconds( ) ;
199
196
200
- this . #updateEntry( value , type , ( entry : NameEntry ) => {
197
+ this . #updateEntry( value , type , variation , ( entry : NameEntry ) => {
201
198
this . #removeDormantProposedNames( entry . proposedNames , type ) ;
202
199
203
200
for ( const providerResponse of providerResponses ) {
@@ -268,27 +265,30 @@ export class NameController extends BaseControllerV2<
268
265
269
266
async #getProviderResponse(
270
267
request : UpdateProposedNamesRequest ,
271
- chainId : string ,
272
268
provider : NameProvider ,
273
269
) : Promise < NameProviderResult | undefined > {
274
270
const {
275
271
value,
276
272
type,
277
273
sourceIds : requestedSourceIds ,
278
274
onlyUpdateAfterDelay,
275
+ variation,
279
276
} = request ;
280
277
281
- const variationKey = this . #getTypeVariationKey( type ) ;
278
+ /* istanbul ignore next */
279
+ const variationKey = variation ?? DEFAULT_VARIATION ;
282
280
const supportedSourceIds = this . #getSourceIds( provider , type ) ;
283
281
const currentTime = this . #getCurrentTimeSeconds( ) ;
282
+ const normalizedValue = this . #normalizeValue( value , type ) ;
284
283
285
284
const matchingSourceIds = supportedSourceIds . filter ( ( sourceId ) => {
286
285
if ( requestedSourceIds && ! requestedSourceIds . includes ( sourceId ) ) {
287
286
return false ;
288
287
}
289
288
290
289
if ( onlyUpdateAfterDelay ) {
291
- const entry = this . state . names [ type ] ?. [ value ] ?. [ variationKey ] ?? { } ;
290
+ const entry =
291
+ this . state . names [ type ] ?. [ normalizedValue ] ?. [ variationKey ] ?? { } ;
292
292
const proposedNamesEntry = entry . proposedNames ?. [ sourceId ] ?? { } ;
293
293
const lastRequestTime = proposedNamesEntry . lastRequestTime ?? 0 ;
294
294
const updateDelay = proposedNamesEntry . updateDelay ?? this . #updateDelay;
@@ -306,10 +306,10 @@ export class NameController extends BaseControllerV2<
306
306
}
307
307
308
308
const providerRequest : NameProviderRequest = {
309
- chainId,
310
- value,
309
+ value : this . #normalizeValue( value , type ) ,
311
310
type,
312
311
sourceIds : requestedSourceIds ? matchingSourceIds : undefined ,
312
+ variation : this . #normalizeVariation( variationKey , type ) ,
313
313
} ;
314
314
315
315
let responseError : unknown | undefined ;
@@ -374,65 +374,85 @@ export class NameController extends BaseControllerV2<
374
374
} ;
375
375
}
376
376
377
+ #normalizeValue( value : string , type : NameType ) : string {
378
+ /* istanbul ignore next */
379
+ switch ( type ) {
380
+ case NameType . ETHEREUM_ADDRESS :
381
+ return value . toLowerCase ( ) ;
382
+
383
+ default :
384
+ return value ;
385
+ }
386
+ }
387
+
388
+ #normalizeVariation( variation : string , type : NameType ) : string {
389
+ /* istanbul ignore next */
390
+ switch ( type ) {
391
+ case NameType . ETHEREUM_ADDRESS :
392
+ return variation . toLowerCase ( ) ;
393
+
394
+ default :
395
+ return variation ;
396
+ }
397
+ }
398
+
377
399
#updateEntry(
378
400
value : string ,
379
401
type : NameType ,
402
+ variation : string | undefined ,
380
403
callback : ( entry : NameEntry ) => void ,
381
404
) {
382
- const variationKey = this . #getTypeVariationKey( type ) ;
405
+ /* istanbul ignore next */
406
+ const variationKey = variation ?? DEFAULT_VARIATION ;
407
+ const normalizedValue = this . #normalizeValue( value , type ) ;
408
+ const normalizedVariation = this . #normalizeVariation( variationKey , type ) ;
383
409
384
410
this . update ( ( state ) => {
385
411
const typeEntries = state . names [ type ] || { } ;
386
412
state . names [ type ] = typeEntries ;
387
413
388
- const variationEntries = typeEntries [ value ] || { } ;
389
- typeEntries [ value ] = variationEntries ;
414
+ const variationEntries = typeEntries [ normalizedValue ] || { } ;
415
+ typeEntries [ normalizedValue ] = variationEntries ;
390
416
391
- const entry = variationEntries [ variationKey ] ?? {
417
+ const entry = variationEntries [ normalizedVariation ] ?? {
392
418
proposedNames : { } ,
393
419
name : null ,
394
420
sourceId : null ,
395
421
} ;
396
- variationEntries [ variationKey ] = entry ;
422
+ variationEntries [ normalizedVariation ] = entry ;
397
423
398
424
callback ( entry ) ;
399
425
} ) ;
400
426
}
401
427
402
- #getTypeVariationKey( type : NameType ) : string {
403
- switch ( type ) {
404
- default : {
405
- return this . #getChainId( ) ;
406
- }
407
- }
408
- }
409
-
410
428
#getCurrentTimeSeconds( ) : number {
411
429
return Math . round ( Date . now ( ) / 1000 ) ;
412
430
}
413
431
414
432
#validateSetNameRequest( request : SetNameRequest ) {
415
- const { name, value, type, sourceId } = request ;
433
+ const { name, value, type, sourceId, variation } = request ;
416
434
const errorMessages : string [ ] = [ ] ;
417
435
418
436
this . #validateValue( value , errorMessages ) ;
419
437
this . #validateType( type , errorMessages ) ;
420
438
this . #validateName( name , errorMessages ) ;
421
439
this . #validateSourceId( sourceId , type , name , errorMessages ) ;
440
+ this . #validateVariation( variation , type , errorMessages ) ;
422
441
423
442
if ( errorMessages . length ) {
424
443
throw new Error ( errorMessages . join ( ' ' ) ) ;
425
444
}
426
445
}
427
446
428
447
#validateUpdateProposedNamesRequest( request : UpdateProposedNamesRequest ) {
429
- const { value, type, sourceIds } = request ;
448
+ const { value, type, sourceIds, variation } = request ;
430
449
const errorMessages : string [ ] = [ ] ;
431
450
432
451
this . #validateValue( value , errorMessages ) ;
433
452
this . #validateType( type , errorMessages ) ;
434
453
this . #validateSourceIds( sourceIds , type , errorMessages ) ;
435
454
this . #validateDuplicateSourceIds( type , errorMessages ) ;
455
+ this . #validateVariation( variation , type , errorMessages ) ;
436
456
437
457
if ( errorMessages . length ) {
438
458
throw new Error ( errorMessages . join ( ' ' ) ) ;
@@ -536,6 +556,26 @@ export class NameController extends BaseControllerV2<
536
556
}
537
557
}
538
558
559
+ #validateVariation(
560
+ variation : string | undefined ,
561
+ type : string ,
562
+ errorMessages : string [ ] ,
563
+ ) {
564
+ if ( type !== NameType . ETHEREUM_ADDRESS ) {
565
+ return ;
566
+ }
567
+
568
+ if (
569
+ ! variation ?. length ||
570
+ typeof variation !== 'string' ||
571
+ ! variation . match ( / ^ 0 x [ 0 - 9 A - F a - f ] + $ / u)
572
+ ) {
573
+ errorMessages . push (
574
+ `Must specify a chain ID in hexidecimal format for variation when using '${ type } ' type.` ,
575
+ ) ;
576
+ }
577
+ }
578
+
539
579
#getAllSourceIds( type : NameType ) : string [ ] {
540
580
return (
541
581
this . #providers
0 commit comments