Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
56 changes: 56 additions & 0 deletions bindings/compile/aptos_cli.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
package compile

import (
"fmt"
"os"
"os/exec"
"path/filepath"
)

const aptosCLIEnvVar = "APTOS_CLI"

// resolveAptosCLI returns the Aptos Labs CLI binary used for Move compilation.
// APTOS_CLI overrides PATH lookup when set.
func resolveAptosCLI() (string, error) {

@RodrigoAD RodrigoAD Jul 3, 2026

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There was a collision with the aptos relayer binary in core e2e tests. Adding the resolver to make sure aptos binary is actually the CLI binary

if cli := os.Getenv(aptosCLIEnvVar); cli != "" {
if err := assertExecutable(cli); err != nil {
return "", fmt.Errorf("%s=%q: %w", aptosCLIEnvVar, cli, err)
}
return cli, nil
}

for _, dir := range filepath.SplitList(os.Getenv("PATH")) {
if dir == "" {
continue
}
candidate := filepath.Join(dir, "aptos")
if !isAptosCLI(candidate) {
continue
}
return candidate, nil
}

return "", fmt.Errorf(
"aptos CLI not found on PATH; set %s to the binary path)",
aptosCLIEnvVar,
)
}

func assertExecutable(path string) error {
info, err := os.Stat(path)
if err != nil {
return err
}
if info.IsDir() {
return fmt.Errorf("not an executable file")
}
return nil
}

func isAptosCLI(path string) bool {
if err := assertExecutable(path); err != nil {
return false
}
cmd := exec.Command(path, "move", "--help")
return cmd.Run() == nil
}
73 changes: 73 additions & 0 deletions bindings/compile/aptos_cli_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
package compile

import (
"os"
"path/filepath"
"testing"

"github.com/stretchr/testify/require"
)

func writeFakeCLI(t *testing.T, dir, name string, script string) string {
t.Helper()
path := filepath.Join(dir, name)
require.NoError(t, os.WriteFile(path, []byte(script), 0o755))
return path
}

func Test_resolveAptosCLI_APTOS_CLIOverride(t *testing.T) {
dir := t.TempDir()
cli := writeFakeCLI(t, dir, "aptos-labs", "#!/bin/sh\nexit 0\n")

t.Setenv(aptosCLIEnvVar, cli)
t.Setenv("PATH", "")

got, err := resolveAptosCLI()
require.NoError(t, err)
require.Equal(t, cli, got)
}

func Test_resolveAptosCLI_APTOS_CLIOverride_missing(t *testing.T) {
t.Setenv(aptosCLIEnvVar, filepath.Join(t.TempDir(), "missing"))
t.Setenv("PATH", "")

_, err := resolveAptosCLI()
require.Error(t, err)
require.Contains(t, err.Error(), aptosCLIEnvVar)
}

func Test_resolveAptosCLI_PATHPrefersLabsCLI(t *testing.T) {
loopOnlyDir := t.TempDir()
writeFakeCLI(t, loopOnlyDir, "aptos", "#!/bin/sh\nif [ \"$1\" = move ]; then exit 1; fi\nexit 0\n")
labsAsAptosDir := t.TempDir()
writeFakeCLI(t, labsAsAptosDir, "aptos", "#!/bin/sh\nif [ \"$1\" = move ] && [ \"$2\" = --help ]; then exit 0; fi\nexit 1\n")

t.Setenv(aptosCLIEnvVar, "")
t.Setenv("PATH", loopOnlyDir+string(filepath.ListSeparator)+labsAsAptosDir)

got, err := resolveAptosCLI()
require.NoError(t, err)
require.Equal(t, filepath.Join(labsAsAptosDir, "aptos"), got)
}

func Test_resolveAptosCLI_noValidCLI(t *testing.T) {
dir := t.TempDir()
writeFakeCLI(t, dir, "aptos", "#!/bin/sh\nexit 1\n")

t.Setenv(aptosCLIEnvVar, "")
t.Setenv("PATH", dir)

_, err := resolveAptosCLI()
require.Error(t, err)
require.Contains(t, err.Error(), aptosCLIEnvVar)
}

func Test_isAptosLabsCLI(t *testing.T) {
dir := t.TempDir()
labs := writeFakeCLI(t, dir, "labs", "#!/bin/sh\nif [ \"$1\" = move ] && [ \"$2\" = --help ]; then exit 0; fi\nexit 1\n")
loop := writeFakeCLI(t, dir, "loop", "#!/bin/sh\nif [ \"$1\" = move ]; then exit 1; fi\nexit 0\n")

require.True(t, isAptosCLI(labs))
require.False(t, isAptosCLI(loop))
require.False(t, isAptosCLI(filepath.Join(dir, "missing")))
}
7 changes: 6 additions & 1 deletion bindings/compile/compile.go
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,12 @@ func CompilePackage(packageName contracts.Package, namedAddresses map[string]apt
args = append(args, "--named-addresses", strings.Join(namedAddr, ","))
}

cmd := exec.Command("aptos", args...)
aptosBin, err := resolveAptosCLI()
if err != nil {
return CompiledPackage{}, err
}

cmd := exec.Command(aptosBin, args...)
cmd.Dir = packageRoot // Command is run in the temporary destination directory
// Buffer stdErr and stdOut
stdOut := &bytes.Buffer{}
Expand Down
1 change: 1 addition & 0 deletions deployment/ccip/adapters/connect_chains.go
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,7 @@ var ConfigureLaneLegAsDest = cldf_ops.NewSequence(
IsEnabled: isEnabled,
TestRouter: input.TestRouter,
IsRMNVerificationDisabled: !input.Source.RMNVerificationEnabled,
OnRamp: input.Source.OnRamp,
},
},
})
Expand Down
18 changes: 6 additions & 12 deletions deployment/ccip/operation/off_ramp.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,17 +7,12 @@ import (
mcmstypes "github.com/smartcontractkit/mcms/types"

"github.com/smartcontractkit/chainlink-aptos/bindings/ccip_offramp"
aptosutils "github.com/smartcontractkit/chainlink-aptos/relayer/utils"
"github.com/smartcontractkit/chainlink-deployments-framework/operations"
"github.com/smartcontractkit/chainlink-aptos/deployment/ccip/dependency"
"github.com/smartcontractkit/chainlink-aptos/deployment/ccip/utils"
"github.com/smartcontractkit/chainlink-aptos/deployment/ccip/internal"
"github.com/smartcontractkit/chainlink-aptos/deployment/ccip/utils"
"github.com/smartcontractkit/chainlink-aptos/deployment/ccip/v1_6"
)

const (
pluginTypeCCIPCommit uint8 = 0

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unused?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yup

pluginTypeCCIPExec uint8 = 1
aptosutils "github.com/smartcontractkit/chainlink-aptos/relayer/utils"
"github.com/smartcontractkit/chainlink-deployments-framework/operations"
)

var OffRampOperations = []*operations.Operation[any, any, any]{
Expand Down Expand Up @@ -56,11 +51,10 @@ func updateOffRampSources(b operations.Bundle, deps dependency.AptosDeps, in Upd
sourceChainEnabled = append(sourceChainEnabled, update.IsEnabled)
sourceChainRMNVerificationDisabled = append(sourceChainRMNVerificationDisabled, update.IsRMNVerificationDisabled)

onRampBytes, err := deps.CCIPOnChainState.GetOnRampAddressBytes(sourceChainSelector)
if err != nil {
return nil, fmt.Errorf("failed to get onRamp address for source chain %d: %w", sourceChainSelector, err)
if len(update.OnRamp) == 0 {
return nil, fmt.Errorf("no onramp provided for source chain %d", sourceChainSelector)
}
sourceChainOnRamp = append(sourceChainOnRamp, onRampBytes)
sourceChainOnRamp = append(sourceChainOnRamp, update.OnRamp)
}

if len(sourceChainSelectors) == 0 {
Expand Down
13 changes: 7 additions & 6 deletions deployment/ccip/v1_6/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,10 @@ type ConnectionConfig struct {
// ChainDefinition defines how a chain should be configured on both remote chains and itself.
type ChainDefinition struct {
ConnectionConfig `json:"connectionConfig"`
Selector uint64 `json:"selector"`
GasPrice *big.Int `json:"gasPrice"`
TokenPrices map[common.Address]*big.Int `json:"tokenPrices"`
FeeQuoterDestChainConfig fee_quoter.FeeQuoterDestChainConfig `json:"feeQuoterDestChainConfig"`
Selector uint64 `json:"selector"`
GasPrice *big.Int `json:"gasPrice"`
TokenPrices map[common.Address]*big.Int `json:"tokenPrices"`
FeeQuoterDestChainConfig fee_quoter.FeeQuoterDestChainConfig `json:"feeQuoterDestChainConfig"`
}

type OnRampDestinationUpdate struct {
Expand All @@ -39,11 +39,12 @@ type OffRampSourceUpdate struct {
IsEnabled bool
TestRouter bool
IsRMNVerificationDisabled bool
OnRamp []byte
}

type UpdateOffRampSourcesConfig struct {
UpdatesByChain map[uint64]map[uint64]OffRampSourceUpdate
MCMS *cldfproposalutils.TimelockConfig
UpdatesByChain map[uint64]map[uint64]OffRampSourceUpdate
MCMS *cldfproposalutils.TimelockConfig
SkipOwnershipCheck bool
}

Expand Down
4 changes: 0 additions & 4 deletions deployment/stateview/state.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import (

"github.com/aptos-labs/aptos-go-sdk"
chainselectors "github.com/smartcontractkit/chain-selectors"
"github.com/ethereum/go-ethereum/common"

cldf "github.com/smartcontractkit/chainlink-deployments-framework/deployment"

Expand Down Expand Up @@ -47,9 +46,6 @@ func (c CCIPOnChainState) GetOnRampAddressBytes(chainSelector uint64) ([]byte, e
return nil, fmt.Errorf("no ccip address found in the state for Aptos chain %d", chainSelector)
}
return ccipAddress[:], nil
case chainselectors.FamilyEVM:
// For integration tests, EVM onramp bytes may be supplied via mock addresses in config.
return common.HexToAddress("0x0BF3dE8c5D3e8A2B34D2BEeB17ABfCeBaf363A59").Bytes(), nil
default:
return nil, fmt.Errorf("unsupported chain family for onramp lookup: %s", family)
}
Expand Down
19 changes: 17 additions & 2 deletions integration-tests/deployment/ccip/cs_update_aptos_lanes_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,11 @@ import (
_ "github.com/smartcontractkit/chainlink-ccip/chains/evm/deployment/v1_6_0/sequences"
deployops "github.com/smartcontractkit/chainlink-ccip/deployment/deploy"
"github.com/smartcontractkit/chainlink-ccip/deployment/lanes"
"github.com/smartcontractkit/chainlink-ccip/deployment/utils/mcms"
cs_ccip "github.com/smartcontractkit/chainlink-ccip/deployment/utils/changesets"
"github.com/smartcontractkit/chainlink-ccip/deployment/utils/mcms"

"github.com/smartcontractkit/chainlink-aptos/deployment/ccip/shared"
_ "github.com/smartcontractkit/chainlink-aptos/deployment/ccip/adapters"
"github.com/smartcontractkit/chainlink-aptos/deployment/ccip/shared"
"github.com/smartcontractkit/chainlink-aptos/deployment/stateview"
"github.com/smartcontractkit/chainlink-aptos/integration-tests/deployment/testutil"
)
Expand Down Expand Up @@ -135,6 +135,21 @@ func TestUpdateAptosLanes(t *testing.T) {
require.NoError(t, err)
require.True(t, isSupported)

evmAdapter, ok := lanesRegistry.GetLaneAdapter(chain_selectors.FamilyEVM, toolingAPIVersion)
require.True(t, ok)
evmOnRampBytes, err := evmAdapter.GetOnRampAddress(env.DataStore, evmSelector1)
require.NoError(t, err)
evmOnRampBytes2, err := evmAdapter.GetOnRampAddress(env.DataStore, evmSelector2)
require.NoError(t, err)

srcCfg1, err := aptosOffRamp.Offramp().GetSourceChainConfig(&bind.CallOpts{}, evmSelector1)
require.NoError(t, err)
require.Equal(t, evmOnRampBytes, srcCfg1.OnRamp)

srcCfg2, err := aptosOffRamp.Offramp().GetSourceChainConfig(&bind.CallOpts{}, evmSelector2)
require.NoError(t, err)
require.Equal(t, evmOnRampBytes2, srcCfg2.OnRamp)

_, _, router, routerState, err := aptosOnRamp.Onramp().GetDestChainConfigV2(&bind.CallOpts{}, evmSelector1)
require.NoError(t, err)
require.NotEqual(t, aptos.AccountAddress{}, router)
Expand Down
Loading