agents/domains/evm/summit.go
package evm
import (
"context"
"fmt"
"github.com/ethereum/go-ethereum/accounts/abi/bind"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/event"
"github.com/synapsecns/sanguine/agents/contracts/summit"
"github.com/synapsecns/sanguine/agents/domains"
"github.com/synapsecns/sanguine/agents/types"
"github.com/synapsecns/sanguine/ethergo/chain"
"github.com/synapsecns/sanguine/ethergo/signer/nonce"
"github.com/synapsecns/sanguine/ethergo/signer/signer"
)
// NewSummitContract returns a bound summit contract.
//
//nolint:staticcheck
func NewSummitContract(ctx context.Context, client chain.Chain, summitAddress common.Address) (domains.SummitContract, error) {
boundCountract, err := summit.NewSummitRef(summitAddress, client)
if err != nil {
return nil, fmt.Errorf("could not create %T: %w", &summit.SummitRef{}, err)
}
nonceManager := nonce.NewNonceManager(ctx, client, client.GetBigChainID())
return summitContract{
contract: boundCountract,
client: client,
nonceManager: nonceManager,
}, nil
}
type summitContract struct {
// contract contains the conract handle
contract *summit.SummitRef
// client contains the evm client
//nolint: staticcheck
client chain.Chain
// nonceManager is the nonce manager used for transacting with the chain
nonceManager nonce.Manager
}
func (a summitContract) GetLatestState(ctx context.Context, origin uint32) (types.State, error) {
rawState, err := a.contract.GetLatestState(&bind.CallOpts{Context: ctx}, origin)
if err != nil {
return nil, fmt.Errorf("could not retrieve latest state: %w", err)
}
state, err := types.DecodeState(rawState)
if err != nil {
return nil, fmt.Errorf("could not decode state: %w", err)
}
return state, nil
}
func (a summitContract) GetLatestAgentState(ctx context.Context, origin uint32, bondedAgentSigner signer.Signer) (types.State, error) {
rawState, err := a.contract.GetLatestAgentState(&bind.CallOpts{Context: ctx}, origin, bondedAgentSigner.Address())
if err != nil {
return nil, fmt.Errorf("could not retrieve latest agent state: %w", err)
}
state, err := types.DecodeState(rawState)
if err != nil {
return nil, fmt.Errorf("could not decode state: %w", err)
}
return state, nil
}
func (a summitContract) GetLatestNotaryAttestation(ctx context.Context, notarySigner signer.Signer) (types.NotaryAttestation, error) {
lastNotaryAttestation, err := a.contract.GetLatestNotaryAttestation(&bind.CallOpts{Context: ctx}, notarySigner.Address())
if err != nil {
return nil, fmt.Errorf("could not retrieve latest notary attestation: %w", err)
}
if len(lastNotaryAttestation.AttPayload) == 0 {
return nil, nil
}
notaryAttestation, err := types.NewNotaryAttestation(lastNotaryAttestation.AttPayload, lastNotaryAttestation.AgentRoot, lastNotaryAttestation.SnapGas)
if err != nil {
return nil, fmt.Errorf("could not decode notary attestation: %w", err)
}
return notaryAttestation, nil
}
func (a summitContract) WatchAttestationSaved(ctx context.Context, sink chan<- *summit.SummitAttestationSaved) (event.Subscription, error) {
sub, err := a.contract.WatchAttestationSaved(&bind.WatchOpts{Context: ctx}, sink)
if err != nil {
return nil, fmt.Errorf("could set up channel to watch attestation saved: %w", err)
}
return sub, nil
}
//nolint:wrapcheck
func (a summitContract) IsValidAttestation(ctx context.Context, attestation []byte) (bool, error) {
return a.contract.IsValidAttestation(&bind.CallOpts{Context: ctx}, attestation)
}
func (a summitContract) GetNotarySnapshot(ctx context.Context, attPayload []byte) (types.Snapshot, error) {
rawSnapshot, err := a.contract.GetNotarySnapshot(&bind.CallOpts{Context: ctx}, attPayload)
if err != nil {
return nil, fmt.Errorf("could not retrieve notary snapshot: %w", err)
}
snapshot, err := types.DecodeSnapshot(rawSnapshot.SnapPayload)
if err != nil {
return nil, fmt.Errorf("could not decode snapshot: %w", err)
}
return snapshot, nil
}
func (a summitContract) GetAttestation(ctx context.Context, attNonce uint32) (types.NotaryAttestation, error) {
rawAttestation, err := a.contract.GetAttestation(&bind.CallOpts{Context: ctx}, attNonce)
if err != nil {
return nil, fmt.Errorf("could not retrieve attestation: %w", err)
}
if len(rawAttestation.AttPayload) == 0 {
//nolint:nil,nil
return nil, nil
}
attestation, err := types.NewNotaryAttestation(rawAttestation.AttPayload, rawAttestation.AgentRoot, rawAttestation.SnapGas)
if err != nil {
return nil, fmt.Errorf("could not decode attestation: %w", err)
}
return attestation, nil
}