@@ -1716,8 +1716,9 @@ func (l *signatureTreeSapientCompactLeaf) write(writer io.Writer) error {
17161716type WalletConfig struct {
17171717 Threshold_ uint16 `json:"threshold" toml:"threshold"`
17181718 // WARNING: contract code is uint64
1719- Checkpoint_ uint64 `json:"checkpoint" toml:"checkpoint"`
1720- Tree WalletConfigTree `json:"tree" toml:"tree"`
1719+ Checkpoint_ uint64 `json:"checkpoint" toml:"checkpoint"`
1720+ Tree WalletConfigTree `json:"tree" toml:"tree"`
1721+ Checkpointer common.Address `json:"checkpointer,omitempty" toml:"checkpointer,omitempty"`
17211722}
17221723
17231724func (c * WalletConfig ) Threshold () uint16 {
@@ -1747,18 +1748,22 @@ func (c *WalletConfig) IsUsable() error {
17471748}
17481749
17491750func (c * WalletConfig ) ImageHash () core.ImageHash {
1750- imageHash := c .Tree .ImageHash ()
1751- threshold := common .BigToHash (new (big.Int ).SetUint64 (uint64 (c .Threshold_ )))
1752- checkpoint := common .BigToHash (new (big.Int ).SetUint64 (uint64 (c .Checkpoint_ )))
1751+ treeHash := c .Tree .ImageHash ().Bytes ()
1752+
1753+ thresholdBytes := common .BigToHash (new (big.Int ).SetUint64 (uint64 (c .Threshold_ ))).Bytes ()
1754+ checkpointBytes := common .BigToHash (new (big.Int ).SetUint64 (c .Checkpoint_ )).Bytes ()
1755+
1756+ checkpointerBytes := make ([]byte , 32 )
1757+ copy (checkpointerBytes [12 :], c .Checkpointer .Bytes ())
1758+
1759+ root := crypto .Keccak256Hash (treeHash , thresholdBytes )
1760+
1761+ root = crypto .Keccak256Hash (root .Bytes (), checkpointBytes )
1762+
1763+ root = crypto .Keccak256Hash (root .Bytes (), checkpointerBytes )
17531764
17541765 return core.ImageHash {
1755- Hash : crypto .Keccak256Hash (
1756- crypto .Keccak256Hash (
1757- imageHash .Bytes (),
1758- threshold .Bytes (),
1759- ).Bytes (),
1760- checkpoint .Bytes (),
1761- ),
1766+ Hash : root ,
17621767 Preimage : c ,
17631768 }
17641769}
@@ -1881,6 +1886,10 @@ func DecodeWalletConfigTree(object any) (WalletConfigTree, error) {
18811886 return decodeWalletConfigTreeNestedLeaf (object_ )
18821887 } else if hasKeys (object_ , []string {"subdigest" }) {
18831888 return decodeWalletConfigTreeSubdigestLeaf (object_ )
1889+ } else if hasKeys (object_ , []string {"weight" , "address" , "imageHash" }) {
1890+ return decodeWalletConfigTreeSapientSignerLeaf (object_ )
1891+ } else if hasKeys (object_ , []string {"digest" }) {
1892+ return decodeWalletConfigTreeAnyAddressSubdigestLeaf (object_ )
18841893 }
18851894 return nil , fmt .Errorf ("unknown wallet config tree type" )
18861895}
@@ -2025,9 +2034,15 @@ func decodeWalletConfigTreeAddressLeaf(object any) (*WalletConfigTreeAddressLeaf
20252034}
20262035
20272036func (l * WalletConfigTreeAddressLeaf ) ImageHash () core.ImageHash {
2028- var hash common.Hash
2029- hash .SetBytes (l .Address .Bytes ())
2030- hash [common .HashLength - common .AddressLength - 1 ] = l .Weight
2037+ weight := new (big.Int ).SetUint64 (uint64 (l .Weight ))
2038+ weightBytes := make ([]byte , 32 )
2039+ weight .FillBytes (weightBytes )
2040+
2041+ hash := crypto .Keccak256Hash (
2042+ []byte ("Sequence signer:\n " ),
2043+ l .Address .Bytes (),
2044+ weightBytes ,
2045+ )
20312046 return core.ImageHash {Hash : hash , Preimage : l }
20322047}
20332048
@@ -2277,6 +2292,153 @@ func (l WalletConfigTreeSubdigestLeaf) buildSignatureTree(signerSignatures map[c
22772292 return signatureTreeSubdigestLeaf {l .Subdigest }
22782293}
22792294
2295+ type WalletConfigTreeSapientSignerLeaf struct {
2296+ Weight uint8 `json:"weight" toml:"weight"`
2297+ Address common.Address `json:"address" toml:"address"`
2298+ ImageHash_ core.ImageHash `json:"imageHash" toml:"imageHash"`
2299+ }
2300+
2301+ func decodeWalletConfigTreeSapientSignerLeaf (object any ) (* WalletConfigTreeSapientSignerLeaf , error ) {
2302+ object_ , ok := object .(map [string ]any )
2303+ if ! ok {
2304+ return nil , fmt .Errorf ("wallet config tree sapient signer leaf must be an object" )
2305+ }
2306+
2307+ weight , ok := object_ ["weight" ]
2308+ if ! ok {
2309+ return nil , fmt .Errorf (`missing required "weight" property` )
2310+ }
2311+ weight_ , err := toUint8 (weight )
2312+ if err != nil {
2313+ return nil , fmt .Errorf ("unable to convert weight: %w" , err )
2314+ }
2315+
2316+ address , ok := object_ ["address" ]
2317+ if ! ok {
2318+ return nil , fmt .Errorf (`missing required "address" property` )
2319+ }
2320+ address_ , ok := address .(string )
2321+ if ! ok {
2322+ return nil , fmt .Errorf ("address must be a string" )
2323+ }
2324+ if ! common .IsHexAddress (address_ ) {
2325+ return nil , fmt .Errorf (`"%v" is not a valid address` , address_ )
2326+ }
2327+
2328+ imageHash , ok := object_ ["imageHash" ]
2329+ if ! ok {
2330+ return nil , fmt .Errorf (`missing required "imageHash" property` )
2331+ }
2332+ imageHash_ , ok := imageHash .(string )
2333+ if ! ok {
2334+ return nil , fmt .Errorf ("imageHash must be a string" )
2335+ }
2336+ imageHashBytes , err := hexutil .Decode (imageHash_ )
2337+ if err != nil || len (imageHashBytes ) != 32 {
2338+ return nil , fmt .Errorf (`"%v" is not a valid 32-byte hash` , imageHash_ )
2339+ }
2340+
2341+ return & WalletConfigTreeSapientSignerLeaf {
2342+ Weight : weight_ ,
2343+ Address : common .HexToAddress (address_ ),
2344+ ImageHash_ : core.ImageHash {Hash : common .BytesToHash (imageHashBytes )},
2345+ }, nil
2346+ }
2347+
2348+ func (l * WalletConfigTreeSapientSignerLeaf ) ImageHash () core.ImageHash {
2349+ weight := new (big.Int ).SetUint64 (uint64 (l .Weight ))
2350+ weightBytes := make ([]byte , 32 )
2351+ weight .FillBytes (weightBytes )
2352+
2353+ hash := crypto .Keccak256Hash (
2354+ []byte ("Sequence sapient config:\n " ),
2355+ l .Address .Bytes (),
2356+ weightBytes ,
2357+ l .ImageHash_ .Bytes (),
2358+ )
2359+ return core.ImageHash {Hash : hash , Preimage : l }
2360+ }
2361+
2362+ func (l * WalletConfigTreeSapientSignerLeaf ) maxWeight () * big.Int {
2363+ return new (big.Int ).SetUint64 (uint64 (l .Weight ))
2364+ }
2365+
2366+ func (l * WalletConfigTreeSapientSignerLeaf ) readSignersIntoMap (signers map [common.Address ]uint16 ) {
2367+ signers [l .Address ] = uint16 (l .Weight )
2368+ }
2369+
2370+ func (l * WalletConfigTreeSapientSignerLeaf ) unverifiedWeight (signers map [common.Address ]uint16 ) * big.Int {
2371+ if _ , ok := signers [l .Address ]; ok {
2372+ return new (big.Int ).SetUint64 (uint64 (l .Weight ))
2373+ }
2374+ return new (big.Int )
2375+ }
2376+
2377+ func (l * WalletConfigTreeSapientSignerLeaf ) buildSignatureTree (signerSignatures map [common.Address ]signerSignature ) signatureTree {
2378+ if signature , ok := signerSignatures [l .Address ]; ok {
2379+ return & signatureTreeSapientLeaf {
2380+ Weight : l .Weight ,
2381+ Address : l .Address ,
2382+ Signature : signature .signature ,
2383+ }
2384+ }
2385+ return & signatureTreeAddressLeaf {Weight : l .Weight , Address : l .Address }
2386+ }
2387+
2388+ type WalletConfigTreeAnyAddressSubdigestLeaf struct {
2389+ Digest core.Subdigest `json:"digest" toml:"digest"`
2390+ }
2391+
2392+ func decodeWalletConfigTreeAnyAddressSubdigestLeaf (object any ) (WalletConfigTreeAnyAddressSubdigestLeaf , error ) {
2393+ object_ , ok := object .(map [string ]any )
2394+ if ! ok {
2395+ return WalletConfigTreeAnyAddressSubdigestLeaf {}, fmt .Errorf ("wallet config tree any address subdigest leaf must be an object" )
2396+ }
2397+
2398+ digest , ok := object_ ["digest" ]
2399+ if ! ok {
2400+ return WalletConfigTreeAnyAddressSubdigestLeaf {}, fmt .Errorf (`missing required "digest" property` )
2401+ }
2402+ digest_ , ok := digest .(string )
2403+ if ! ok {
2404+ return WalletConfigTreeAnyAddressSubdigestLeaf {}, fmt .Errorf ("digest must be a string" )
2405+ }
2406+ digestBytes , err := hexutil .Decode (digest_ )
2407+ if err != nil || len (digestBytes ) != 32 {
2408+ return WalletConfigTreeAnyAddressSubdigestLeaf {}, fmt .Errorf (`"%v" is not a valid 32-byte hash` , digest_ )
2409+ }
2410+
2411+ return WalletConfigTreeAnyAddressSubdigestLeaf {
2412+ Digest : core.Subdigest {Hash : common .BytesToHash (digestBytes )},
2413+ }, nil
2414+ }
2415+
2416+ func (l WalletConfigTreeAnyAddressSubdigestLeaf ) ImageHash () core.ImageHash {
2417+ hash := crypto .Keccak256Hash (
2418+ []byte ("Sequence any address subdigest:\n " ),
2419+ l .Digest .Bytes (),
2420+ )
2421+ return core.ImageHash {
2422+ Hash : hash ,
2423+ Preimage : & l ,
2424+ }
2425+ }
2426+
2427+ func (l WalletConfigTreeAnyAddressSubdigestLeaf ) maxWeight () * big.Int {
2428+ return new (big.Int ).Set (maxUint256 )
2429+ }
2430+
2431+ func (l WalletConfigTreeAnyAddressSubdigestLeaf ) readSignersIntoMap (signers map [common.Address ]uint16 ) {
2432+ }
2433+
2434+ func (l WalletConfigTreeAnyAddressSubdigestLeaf ) unverifiedWeight (signers map [common.Address ]uint16 ) * big.Int {
2435+ return new (big.Int ).Set (maxUint256 )
2436+ }
2437+
2438+ func (l WalletConfigTreeAnyAddressSubdigestLeaf ) buildSignatureTree (signerSignatures map [common.Address ]signerSignature ) signatureTree {
2439+ return & signatureTreeAnyAddressSubdigestLeaf {l .Digest }
2440+ }
2441+
22802442func ecrecover (subdigest core.Subdigest , signature []byte ) (common.Address , error ) {
22812443 if len (signature ) != crypto .SignatureLength {
22822444 return common.Address {}, fmt .Errorf ("invalid signature length %v, expected %v" , len (signature ), crypto .SignatureLength )
0 commit comments