synapsecns/sanguine

View on GitHub
agents/domains/evm/summit.go

Summary

Maintainability
A
2 hrs
Test Coverage
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
}