@@ -13,8 +13,9 @@ export type AddressBookJson<
1313
1414export type AddressBookEntry = {
1515 address : string
16- proxy ?: boolean
17- implementation ?: AddressBookEntry
16+ proxy ?: 'graph' | 'transparent'
17+ proxyAdmin ?: string
18+ implementation ?: string
1819}
1920
2021/**
@@ -24,8 +25,9 @@ export type AddressBookEntry = {
2425 * "<CHAIN_ID>": {
2526 * "<CONTRACT_NAME>": {
2627 * "address": "<ADDRESS>",
27- * "proxy": true, // optional
28- * "implementation": { ... } // optional, nested contract structure
28+ * "proxy": "<graph|transparent>", // optional
29+ * "proxyAdmin": "<ADDRESS>", // optional
30+ * "implementation": "<ADDRESS>", // optional
2931 * ...
3032 * }
3133 * }
@@ -80,7 +82,7 @@ export abstract class AddressBook<
8082 // If it's empty, initialize it with an empty object
8183 const fileContents = JSON . parse ( fs . readFileSync ( this . file , 'utf8' ) || '{}' )
8284 if ( ! fileContents [ this . chainId ] ) {
83- fileContents [ this . chainId ] = { } as Record < ContractName , AddressBookEntry >
85+ fileContents [ this . chainId ] = { }
8486 }
8587 this . assertAddressBookJson ( fileContents )
8688 this . addressBook = fileContents
@@ -100,25 +102,29 @@ export abstract class AddressBook<
100102 * Get an entry from the address book
101103 *
102104 * @param name the name of the contract to get
105+ * @param strict if true it will throw an error if the contract is not found
103106 * @returns the address book entry for the contract
104107 * Returns an empty address book entry if the contract is not found
105108 */
106- getEntry ( name : ContractName ) : { address : string } {
107- const entry = this . addressBook [ this . chainId ] [ name ]
108- // Handle both object and string formats
109- if ( typeof entry === 'string' ) {
110- return { address : entry }
109+ getEntry ( name : string ) : AddressBookEntry {
110+ if ( ! this . isContractName ( name ) ) {
111+ throw new Error ( `Contract name ${ name } is not a valid contract name` )
111112 }
113+ const entry = this . addressBook [ this . chainId ] [ name ]
114+ this . _assertAddressBookEntry ( entry )
112115 return entry
113116 }
114117
115118 /**
116119 * Save an entry to the address book
117- *
120+ * Allows partial address book entries to be saved
118121 * @param name the name of the contract to save
119122 * @param entry the address book entry for the contract
120123 */
121- setEntry ( name : ContractName , entry : AddressBookEntry ) : void {
124+ setEntry ( name : ContractName , entry : Partial < AddressBookEntry > ) : void {
125+ if ( entry . address === undefined ) {
126+ entry . address = '0x0000000000000000000000000000000000000000'
127+ }
122128 this . _assertAddressBookEntry ( entry )
123129 this . addressBook [ this . chainId ] [ name ] = entry
124130 try {
@@ -162,7 +168,8 @@ export abstract class AddressBook<
162168 ) : ContractList < ContractName > {
163169 const contracts = { } as ContractList < ContractName >
164170 if ( this . listEntries ( ) . length == 0 ) {
165- throw Error ( 'No valid contracts found in address book' )
171+ logError ( 'No valid contracts found in address book' )
172+ return contracts
166173 }
167174 for ( const contractName of this . listEntries ( ) ) {
168175 const artifactPath = typeof artifactsPath === 'object' && ! Array . isArray ( artifactsPath )
@@ -214,18 +221,17 @@ export abstract class AddressBook<
214221 // Asserts the provided object is a valid address book entry
215222 _assertAddressBookEntry (
216223 entry : unknown ,
217- ) : asserts entry is { address : string } {
218- if ( typeof entry === 'string' ) {
219- // If it's a string, treat it as an address
220- return
221- }
222-
224+ ) : asserts entry is AddressBookEntry {
223225 assertObject ( entry )
224226 if ( ! ( 'address' in entry ) ) {
225227 throw new Error ( 'Address book entry must have an address field' )
226228 }
227- if ( typeof entry . address !== 'string' ) {
228- throw new Error ( 'Address book entry address must be a string' )
229+
230+ const allowedFields = [ 'address' , 'implementation' , 'proxyAdmin' , 'proxy' ]
231+ const entryFields = Object . keys ( entry )
232+ const invalidFields = entryFields . filter ( field => ! allowedFields . includes ( field ) )
233+ if ( invalidFields . length > 0 ) {
234+ throw new Error ( `Address book entry contains invalid fields: ${ invalidFields . join ( ', ' ) } ` )
229235 }
230236 }
231237}
0 commit comments