From be8d764498cdf074b1db6a6660fd0aa6f31b3d1a Mon Sep 17 00:00:00 2001 From: Chase Fleming <1666730+chasefleming@users.noreply.github.com> Date: Mon, 24 Nov 2025 16:11:01 -0800 Subject: [PATCH 1/4] Add alias flag --- .../dependencymanager/dependencyinstaller.go | 37 +++++- .../dependencyinstaller_test.go | 112 ++++++++++++++++++ internal/dependencymanager/install.go | 8 +- 3 files changed, 151 insertions(+), 6 deletions(-) diff --git a/internal/dependencymanager/dependencyinstaller.go b/internal/dependencymanager/dependencyinstaller.go index 8df6e16d1..77f6c2d42 100644 --- a/internal/dependencymanager/dependencyinstaller.go +++ b/internal/dependencymanager/dependencyinstaller.go @@ -103,6 +103,7 @@ type DependencyFlags struct { skipAlias bool `default:"false" flag:"skip-alias" info:"Skip prompting for an alias"` skipUpdatePrompts bool `default:"false" flag:"skip-update-prompts" info:"Skip prompting to update existing dependencies"` deploymentAccount string `default:"" flag:"deployment-account,d" info:"Account name to use for deployments (skips deployment account prompt)"` + alias string `default:"" flag:"alias" info:"Custom alias name for the dependency"` } func (f *DependencyFlags) AddToCommand(cmd *cobra.Command) { @@ -125,6 +126,7 @@ type DependencyInstaller struct { SkipDeployments bool SkipAlias bool DeploymentAccount string + Alias string logs categorizedLogs dependencies map[string]config.Dependency accountAliases map[string]map[string]flowsdk.Address // network -> account -> alias @@ -164,6 +166,7 @@ func NewDependencyInstaller(logger output.Logger, state *flowkit.State, saveStat SkipDeployments: flags.skipDeployments, SkipAlias: flags.skipAlias, DeploymentAccount: flags.deploymentAccount, + Alias: flags.alias, dependencies: make(map[string]config.Dependency), logs: categorizedLogs{}, accountAliases: make(map[string]map[string]flowsdk.Address), @@ -222,6 +225,12 @@ func (di *DependencyInstaller) AddBySourceString(depSource string) error { }, } + // If an alias is provided, use it as the dependency name and set canonical + if di.Alias != "" { + dep.Name = di.Alias + dep.Canonical = depContractName + } + return di.Add(dep) } @@ -257,6 +266,12 @@ func (di *DependencyInstaller) AddByCoreContractName(coreContractName string) er }, } + // If an alias is provided, use it as the dependency name and set canonical + if di.Alias != "" { + dep.Name = di.Alias + dep.Canonical = depContractName + } + return di.Add(dep) } @@ -275,6 +290,12 @@ func (di *DependencyInstaller) AddByDefiContractName(defiContractName string) er return fmt.Errorf("contract %s not found in DeFi actions contracts", defiContractName) } + // If an alias is provided, use it as the dependency name and set canonical + if di.Alias != "" { + targetDep.Name = di.Alias + targetDep.Canonical = defiContractName + } + return di.Add(*targetDep) } @@ -333,6 +354,11 @@ func (di *DependencyInstaller) AddMany(dependencies []config.Dependency) error { } func (di *DependencyInstaller) AddAllByNetworkAddress(sourceStr string) error { + // Check if alias flag is set - not supported when installing all contracts at an address + if di.Alias != "" { + return fmt.Errorf("--alias flag is not supported when installing all contracts at an address (network://address). Please specify a specific contract using network://address.ContractName format") + } + network, address := ParseNetworkAddressString(sourceStr) accountContracts, err := di.getContracts(network, flowsdk.HexToAddress(address)) @@ -783,12 +809,13 @@ func (di *DependencyInstaller) updateDependencyAlias(contractName, aliasNetwork } func (di *DependencyInstaller) updateDependencyState(originalDependency config.Dependency, contractHash string) error { - // Create the dependency to save, preserving aliases from the original + // Create the dependency to save, preserving aliases and canonical from the original dep := config.Dependency{ - Name: originalDependency.Name, - Source: originalDependency.Source, - Hash: contractHash, - Aliases: originalDependency.Aliases, // Preserve aliases from the original dependency + Name: originalDependency.Name, + Source: originalDependency.Source, + Hash: contractHash, + Aliases: originalDependency.Aliases, // Preserve aliases from the original dependency + Canonical: originalDependency.Canonical, // Preserve canonical name if this is an alias } isNewDep := di.State.Dependencies().ByName(dep.Name) == nil diff --git a/internal/dependencymanager/dependencyinstaller_test.go b/internal/dependencymanager/dependencyinstaller_test.go index f2f1ba1a5..058f92e28 100644 --- a/internal/dependencymanager/dependencyinstaller_test.go +++ b/internal/dependencymanager/dependencyinstaller_test.go @@ -743,3 +743,115 @@ func TestAliasedImportHandling(t *testing.T) { assert.NotNil(t, fileContent) }) } + +func TestDependencyInstallerWithAlias(t *testing.T) { + logger := output.NewStdoutLogger(output.NoneLog) + _, state, _ := util.TestMocks(t) + + serviceAcc, _ := state.EmulatorServiceAccount() + serviceAddress := serviceAcc.Address + + t.Run("AddBySourceStringWithAlias", func(t *testing.T) { + gw := mocks.DefaultMockGateway() + + gw.GetAccount.Run(func(args mock.Arguments) { + addr := args.Get(1).(flow.Address) + assert.Equal(t, addr.String(), serviceAddress.String()) + acc := tests.NewAccountWithAddress(addr.String()) + acc.Contracts = map[string][]byte{ + "NumberFormatter": []byte("access(all) contract NumberFormatter {}"), + } + gw.GetAccount.Return(acc, nil) + }) + + di := &DependencyInstaller{ + Gateways: map[string]gateway.Gateway{ + config.EmulatorNetwork.Name: gw.Mock, + config.TestnetNetwork.Name: gw.Mock, + config.MainnetNetwork.Name: gw.Mock, + }, + Logger: logger, + State: state, + SaveState: true, + TargetDir: "", + SkipDeployments: true, + SkipAlias: true, + Alias: "NumberFormatterAlias", + dependencies: make(map[string]config.Dependency), + } + + err := di.AddBySourceString(fmt.Sprintf("%s://%s.%s", config.EmulatorNetwork.Name, serviceAddress.String(), "NumberFormatter")) + assert.NoError(t, err, "Failed to add dependency with alias") + + // Check that the dependency was added with the alias name + dep := state.Dependencies().ByName("NumberFormatterAlias") + assert.NotNil(t, dep, "Dependency should exist with alias name") + assert.Equal(t, "NumberFormatter", dep.Source.ContractName, "Source ContractName should be the actual contract name") + assert.Equal(t, "NumberFormatter", dep.Canonical, "Canonical should be set to the actual contract name") + + // Check that the contract was added with canonical field + contract, err := state.Contracts().ByName("NumberFormatterAlias") + assert.NoError(t, err, "Contract should exist") + assert.Equal(t, "NumberFormatter", contract.Canonical, "Contract Canonical should be set") + + // Check that the file was created with the actual contract name + filePath := fmt.Sprintf("imports/%s/NumberFormatter.cdc", serviceAddress.String()) + fileContent, err := state.ReaderWriter().ReadFile(filePath) + assert.NoError(t, err, "Contract file should exist at imports/address/NumberFormatter.cdc") + assert.NotNil(t, fileContent) + }) + + t.Run("AddByCoreContractNameWithAlias", func(t *testing.T) { + di := &DependencyInstaller{ + Gateways: map[string]gateway.Gateway{ + config.EmulatorNetwork.Name: mocks.DefaultMockGateway().Mock, + config.TestnetNetwork.Name: mocks.DefaultMockGateway().Mock, + config.MainnetNetwork.Name: mocks.DefaultMockGateway().Mock, + }, + Logger: logger, + State: state, + SaveState: true, + TargetDir: "", + SkipDeployments: true, + SkipAlias: true, + Alias: "FlowTokenAlias", + dependencies: make(map[string]config.Dependency), + } + + // Mock the gateway to return FlowToken contract + gw := mocks.DefaultMockGateway() + gw.GetAccount.Run(func(args mock.Arguments) { + addr := args.Get(1).(flow.Address) + acc := tests.NewAccountWithAddress(addr.String()) + acc.Contracts = map[string][]byte{ + "FlowToken": []byte("access(all) contract FlowToken {}"), + } + gw.GetAccount.Return(acc, nil) + }) + + di.Gateways[config.MainnetNetwork.Name] = gw.Mock + + err := di.AddByCoreContractName("FlowToken") + assert.NoError(t, err, "Failed to add core contract with alias") + + // Check that the dependency was added with the alias name + dep := state.Dependencies().ByName("FlowTokenAlias") + assert.NotNil(t, dep, "Dependency should exist with alias name") + assert.Equal(t, "FlowToken", dep.Source.ContractName, "Source ContractName should be FlowToken") + assert.Equal(t, "FlowToken", dep.Canonical, "Canonical should be set to FlowToken") + }) + + t.Run("AddAllByNetworkAddressWithAliasError", func(t *testing.T) { + di := &DependencyInstaller{ + Logger: logger, + State: state, + SaveState: true, + TargetDir: "", + Alias: "SomeAlias", + } + + err := di.AddAllByNetworkAddress(fmt.Sprintf("%s://%s", config.EmulatorNetwork.Name, serviceAddress.String())) + assert.Error(t, err, "Should error when using --alias with network://address format") + assert.Contains(t, err.Error(), "--alias flag is not supported when installing all contracts", "Error message should mention alias flag limitation") + }) +} diff --git a/internal/dependencymanager/install.go b/internal/dependencymanager/install.go index a8e2ae63d..1775f5665 100644 --- a/internal/dependencymanager/install.go +++ b/internal/dependencymanager/install.go @@ -74,10 +74,15 @@ Examples: flow dependencies install --deployment-account my-account FlowToken flow dependencies install -d my-account FlowToken + 8. Install a dependency with a custom alias: + flow dependencies install --alias USDF testnet://0x1234abcd.FiatToken + flow dependencies install --alias MyToken mainnet://0xabcd1234.TokenContract + Flags: • --deployment-account, -d: Specify the account name to use for deployments (skips deployment account prompt) • --skip-deployments: Skip adding the dependency to deployments • --skip-alias: Skip prompting for an alias +• --alias: Custom alias name for the dependency (e.g., --alias USDF) Note: • Using 'network://address' will attempt to install all contracts deployed at that address. @@ -94,7 +99,8 @@ flow dependencies install FlowToken flow dependencies install DeFiActions flow dependencies install FlowToken NonFungibleToken DeFiActions flow dependencies install --deployment-account my-account FlowToken -flow dependencies install -d my-account FlowToken`, +flow dependencies install -d my-account FlowToken +flow dependencies install --alias USDF testnet://0x1234abcd.FiatToken`, Args: cobra.ArbitraryArgs, }, Flags: &installFlags, From 6446801c4262e964e9192593f725ff709ab59190 Mon Sep 17 00:00:00 2001 From: Chase Fleming <1666730+chasefleming@users.noreply.github.com> Date: Mon, 24 Nov 2025 16:49:59 -0800 Subject: [PATCH 2/4] Rename alias flag to name flag for dependency manager - Changed --alias flag to --name flag for better clarity - Updated all references from Alias to Name in DependencyInstaller - Updated documentation and examples to use --name instead of --alias - Updated tests to reflect the new flag name --- .../dependencymanager/dependencyinstaller.go | 34 +++++++++---------- .../dependencyinstaller_test.go | 34 +++++++++---------- internal/dependencymanager/install.go | 10 +++--- 3 files changed, 39 insertions(+), 39 deletions(-) diff --git a/internal/dependencymanager/dependencyinstaller.go b/internal/dependencymanager/dependencyinstaller.go index 77f6c2d42..2a63a7b88 100644 --- a/internal/dependencymanager/dependencyinstaller.go +++ b/internal/dependencymanager/dependencyinstaller.go @@ -103,7 +103,7 @@ type DependencyFlags struct { skipAlias bool `default:"false" flag:"skip-alias" info:"Skip prompting for an alias"` skipUpdatePrompts bool `default:"false" flag:"skip-update-prompts" info:"Skip prompting to update existing dependencies"` deploymentAccount string `default:"" flag:"deployment-account,d" info:"Account name to use for deployments (skips deployment account prompt)"` - alias string `default:"" flag:"alias" info:"Custom alias name for the dependency"` + name string `default:"" flag:"name" info:"Custom name for the dependency"` } func (f *DependencyFlags) AddToCommand(cmd *cobra.Command) { @@ -126,7 +126,7 @@ type DependencyInstaller struct { SkipDeployments bool SkipAlias bool DeploymentAccount string - Alias string + Name string logs categorizedLogs dependencies map[string]config.Dependency accountAliases map[string]map[string]flowsdk.Address // network -> account -> alias @@ -166,7 +166,7 @@ func NewDependencyInstaller(logger output.Logger, state *flowkit.State, saveStat SkipDeployments: flags.skipDeployments, SkipAlias: flags.skipAlias, DeploymentAccount: flags.deploymentAccount, - Alias: flags.alias, + Name: flags.name, dependencies: make(map[string]config.Dependency), logs: categorizedLogs{}, accountAliases: make(map[string]map[string]flowsdk.Address), @@ -225,9 +225,9 @@ func (di *DependencyInstaller) AddBySourceString(depSource string) error { }, } - // If an alias is provided, use it as the dependency name and set canonical - if di.Alias != "" { - dep.Name = di.Alias + // If a custom name is provided, use it as the dependency name and set canonical + if di.Name != "" { + dep.Name = di.Name dep.Canonical = depContractName } @@ -266,9 +266,9 @@ func (di *DependencyInstaller) AddByCoreContractName(coreContractName string) er }, } - // If an alias is provided, use it as the dependency name and set canonical - if di.Alias != "" { - dep.Name = di.Alias + // If a custom name is provided, use it as the dependency name and set canonical + if di.Name != "" { + dep.Name = di.Name dep.Canonical = depContractName } @@ -290,9 +290,9 @@ func (di *DependencyInstaller) AddByDefiContractName(defiContractName string) er return fmt.Errorf("contract %s not found in DeFi actions contracts", defiContractName) } - // If an alias is provided, use it as the dependency name and set canonical - if di.Alias != "" { - targetDep.Name = di.Alias + // If a custom name is provided, use it as the dependency name and set canonical + if di.Name != "" { + targetDep.Name = di.Name targetDep.Canonical = defiContractName } @@ -354,9 +354,9 @@ func (di *DependencyInstaller) AddMany(dependencies []config.Dependency) error { } func (di *DependencyInstaller) AddAllByNetworkAddress(sourceStr string) error { - // Check if alias flag is set - not supported when installing all contracts at an address - if di.Alias != "" { - return fmt.Errorf("--alias flag is not supported when installing all contracts at an address (network://address). Please specify a specific contract using network://address.ContractName format") + // Check if name flag is set - not supported when installing all contracts at an address + if di.Name != "" { + return fmt.Errorf("--name flag is not supported when installing all contracts at an address (network://address). Please specify a specific contract using network://address.ContractName format") } network, address := ParseNetworkAddressString(sourceStr) @@ -814,8 +814,8 @@ func (di *DependencyInstaller) updateDependencyState(originalDependency config.D Name: originalDependency.Name, Source: originalDependency.Source, Hash: contractHash, - Aliases: originalDependency.Aliases, // Preserve aliases from the original dependency - Canonical: originalDependency.Canonical, // Preserve canonical name if this is an alias + Aliases: originalDependency.Aliases, + Canonical: originalDependency.Canonical, } isNewDep := di.State.Dependencies().ByName(dep.Name) == nil diff --git a/internal/dependencymanager/dependencyinstaller_test.go b/internal/dependencymanager/dependencyinstaller_test.go index 058f92e28..d64ed2a0c 100644 --- a/internal/dependencymanager/dependencyinstaller_test.go +++ b/internal/dependencymanager/dependencyinstaller_test.go @@ -751,7 +751,7 @@ func TestDependencyInstallerWithAlias(t *testing.T) { serviceAcc, _ := state.EmulatorServiceAccount() serviceAddress := serviceAcc.Address - t.Run("AddBySourceStringWithAlias", func(t *testing.T) { + t.Run("AddBySourceStringWithName", func(t *testing.T) { gw := mocks.DefaultMockGateway() gw.GetAccount.Run(func(args mock.Arguments) { @@ -776,21 +776,21 @@ func TestDependencyInstallerWithAlias(t *testing.T) { TargetDir: "", SkipDeployments: true, SkipAlias: true, - Alias: "NumberFormatterAlias", + Name: "NumberFormatterCustom", dependencies: make(map[string]config.Dependency), } err := di.AddBySourceString(fmt.Sprintf("%s://%s.%s", config.EmulatorNetwork.Name, serviceAddress.String(), "NumberFormatter")) - assert.NoError(t, err, "Failed to add dependency with alias") + assert.NoError(t, err, "Failed to add dependency with custom name") - // Check that the dependency was added with the alias name - dep := state.Dependencies().ByName("NumberFormatterAlias") - assert.NotNil(t, dep, "Dependency should exist with alias name") + // Check that the dependency was added with the custom name + dep := state.Dependencies().ByName("NumberFormatterCustom") + assert.NotNil(t, dep, "Dependency should exist with custom name") assert.Equal(t, "NumberFormatter", dep.Source.ContractName, "Source ContractName should be the actual contract name") assert.Equal(t, "NumberFormatter", dep.Canonical, "Canonical should be set to the actual contract name") // Check that the contract was added with canonical field - contract, err := state.Contracts().ByName("NumberFormatterAlias") + contract, err := state.Contracts().ByName("NumberFormatterCustom") assert.NoError(t, err, "Contract should exist") assert.Equal(t, "NumberFormatter", contract.Canonical, "Contract Canonical should be set") @@ -801,7 +801,7 @@ func TestDependencyInstallerWithAlias(t *testing.T) { assert.NotNil(t, fileContent) }) - t.Run("AddByCoreContractNameWithAlias", func(t *testing.T) { + t.Run("AddByCoreContractNameWithName", func(t *testing.T) { di := &DependencyInstaller{ Gateways: map[string]gateway.Gateway{ config.EmulatorNetwork.Name: mocks.DefaultMockGateway().Mock, @@ -814,7 +814,7 @@ func TestDependencyInstallerWithAlias(t *testing.T) { TargetDir: "", SkipDeployments: true, SkipAlias: true, - Alias: "FlowTokenAlias", + Name: "FlowTokenCustom", dependencies: make(map[string]config.Dependency), } @@ -832,26 +832,26 @@ func TestDependencyInstallerWithAlias(t *testing.T) { di.Gateways[config.MainnetNetwork.Name] = gw.Mock err := di.AddByCoreContractName("FlowToken") - assert.NoError(t, err, "Failed to add core contract with alias") + assert.NoError(t, err, "Failed to add core contract with custom name") - // Check that the dependency was added with the alias name - dep := state.Dependencies().ByName("FlowTokenAlias") - assert.NotNil(t, dep, "Dependency should exist with alias name") + // Check that the dependency was added with the custom name + dep := state.Dependencies().ByName("FlowTokenCustom") + assert.NotNil(t, dep, "Dependency should exist with custom name") assert.Equal(t, "FlowToken", dep.Source.ContractName, "Source ContractName should be FlowToken") assert.Equal(t, "FlowToken", dep.Canonical, "Canonical should be set to FlowToken") }) - t.Run("AddAllByNetworkAddressWithAliasError", func(t *testing.T) { + t.Run("AddAllByNetworkAddressWithNameError", func(t *testing.T) { di := &DependencyInstaller{ Logger: logger, State: state, SaveState: true, TargetDir: "", - Alias: "SomeAlias", + Name: "SomeName", } err := di.AddAllByNetworkAddress(fmt.Sprintf("%s://%s", config.EmulatorNetwork.Name, serviceAddress.String())) - assert.Error(t, err, "Should error when using --alias with network://address format") - assert.Contains(t, err.Error(), "--alias flag is not supported when installing all contracts", "Error message should mention alias flag limitation") + assert.Error(t, err, "Should error when using --name with network://address format") + assert.Contains(t, err.Error(), "--name flag is not supported when installing all contracts", "Error message should mention name flag limitation") }) } diff --git a/internal/dependencymanager/install.go b/internal/dependencymanager/install.go index 1775f5665..7d59870a0 100644 --- a/internal/dependencymanager/install.go +++ b/internal/dependencymanager/install.go @@ -74,15 +74,15 @@ Examples: flow dependencies install --deployment-account my-account FlowToken flow dependencies install -d my-account FlowToken - 8. Install a dependency with a custom alias: - flow dependencies install --alias USDF testnet://0x1234abcd.FiatToken - flow dependencies install --alias MyToken mainnet://0xabcd1234.TokenContract + 8. Install a dependency with a custom name: + flow dependencies install --name USDF testnet://0x1234abcd.FiatToken + flow dependencies install --name MyToken mainnet://0xabcd1234.TokenContract Flags: • --deployment-account, -d: Specify the account name to use for deployments (skips deployment account prompt) • --skip-deployments: Skip adding the dependency to deployments • --skip-alias: Skip prompting for an alias -• --alias: Custom alias name for the dependency (e.g., --alias USDF) +• --name: Custom name for the dependency (e.g., --name USDF) Note: • Using 'network://address' will attempt to install all contracts deployed at that address. @@ -100,7 +100,7 @@ flow dependencies install DeFiActions flow dependencies install FlowToken NonFungibleToken DeFiActions flow dependencies install --deployment-account my-account FlowToken flow dependencies install -d my-account FlowToken -flow dependencies install --alias USDF testnet://0x1234abcd.FiatToken`, +flow dependencies install --name USDF testnet://0x1234abcd.FiatToken`, Args: cobra.ArbitraryArgs, }, Flags: &installFlags, From 024c5bb82e37e307d905a1a9faa0aa90a4e8820c Mon Sep 17 00:00:00 2001 From: Chase Fleming <1666730+chasefleming@users.noreply.github.com> Date: Mon, 24 Nov 2025 17:10:12 -0800 Subject: [PATCH 3/4] Update description --- .../dependencymanager/dependencyinstaller.go | 8 +++++--- .../dependencyinstaller_test.go | 20 +++++++++---------- internal/dependencymanager/install.go | 5 +++-- 3 files changed, 18 insertions(+), 15 deletions(-) diff --git a/internal/dependencymanager/dependencyinstaller.go b/internal/dependencymanager/dependencyinstaller.go index 2a63a7b88..80ff47753 100644 --- a/internal/dependencymanager/dependencyinstaller.go +++ b/internal/dependencymanager/dependencyinstaller.go @@ -103,7 +103,7 @@ type DependencyFlags struct { skipAlias bool `default:"false" flag:"skip-alias" info:"Skip prompting for an alias"` skipUpdatePrompts bool `default:"false" flag:"skip-update-prompts" info:"Skip prompting to update existing dependencies"` deploymentAccount string `default:"" flag:"deployment-account,d" info:"Account name to use for deployments (skips deployment account prompt)"` - name string `default:"" flag:"name" info:"Custom name for the dependency"` + name string `default:"" flag:"name" info:"Import alias name for the dependency (sets canonical field for Cadence import aliasing)"` } func (f *DependencyFlags) AddToCommand(cmd *cobra.Command) { @@ -225,7 +225,8 @@ func (di *DependencyInstaller) AddBySourceString(depSource string) error { }, } - // If a custom name is provided, use it as the dependency name and set canonical + // If a name is provided, use it as the import alias and set canonical for Cadence import aliasing + // This enables "import OriginalContract as AliasName from address" syntax if di.Name != "" { dep.Name = di.Name dep.Canonical = depContractName @@ -266,7 +267,8 @@ func (di *DependencyInstaller) AddByCoreContractName(coreContractName string) er }, } - // If a custom name is provided, use it as the dependency name and set canonical + // If a name is provided, use it as the import alias and set canonical for Cadence import aliasing + // This enables "import OriginalContract as AliasName from address" syntax if di.Name != "" { dep.Name = di.Name dep.Canonical = depContractName diff --git a/internal/dependencymanager/dependencyinstaller_test.go b/internal/dependencymanager/dependencyinstaller_test.go index d64ed2a0c..6f3dad21b 100644 --- a/internal/dependencymanager/dependencyinstaller_test.go +++ b/internal/dependencymanager/dependencyinstaller_test.go @@ -781,18 +781,18 @@ func TestDependencyInstallerWithAlias(t *testing.T) { } err := di.AddBySourceString(fmt.Sprintf("%s://%s.%s", config.EmulatorNetwork.Name, serviceAddress.String(), "NumberFormatter")) - assert.NoError(t, err, "Failed to add dependency with custom name") + assert.NoError(t, err, "Failed to add dependency with import alias") - // Check that the dependency was added with the custom name + // Check that the dependency was added with the import alias name dep := state.Dependencies().ByName("NumberFormatterCustom") - assert.NotNil(t, dep, "Dependency should exist with custom name") + assert.NotNil(t, dep, "Dependency should exist with import alias name") assert.Equal(t, "NumberFormatter", dep.Source.ContractName, "Source ContractName should be the actual contract name") - assert.Equal(t, "NumberFormatter", dep.Canonical, "Canonical should be set to the actual contract name") + assert.Equal(t, "NumberFormatter", dep.Canonical, "Canonical should be set to the actual contract name for import aliasing") - // Check that the contract was added with canonical field + // Check that the contract was added with canonical field for Cadence import aliasing contract, err := state.Contracts().ByName("NumberFormatterCustom") assert.NoError(t, err, "Contract should exist") - assert.Equal(t, "NumberFormatter", contract.Canonical, "Contract Canonical should be set") + assert.Equal(t, "NumberFormatter", contract.Canonical, "Contract Canonical should be set for import aliasing") // Check that the file was created with the actual contract name filePath := fmt.Sprintf("imports/%s/NumberFormatter.cdc", serviceAddress.String()) @@ -832,13 +832,13 @@ func TestDependencyInstallerWithAlias(t *testing.T) { di.Gateways[config.MainnetNetwork.Name] = gw.Mock err := di.AddByCoreContractName("FlowToken") - assert.NoError(t, err, "Failed to add core contract with custom name") + assert.NoError(t, err, "Failed to add core contract with import alias") - // Check that the dependency was added with the custom name + // Check that the dependency was added with the import alias name dep := state.Dependencies().ByName("FlowTokenCustom") - assert.NotNil(t, dep, "Dependency should exist with custom name") + assert.NotNil(t, dep, "Dependency should exist with import alias name") assert.Equal(t, "FlowToken", dep.Source.ContractName, "Source ContractName should be FlowToken") - assert.Equal(t, "FlowToken", dep.Canonical, "Canonical should be set to FlowToken") + assert.Equal(t, "FlowToken", dep.Canonical, "Canonical should be set to FlowToken for import aliasing") }) t.Run("AddAllByNetworkAddressWithNameError", func(t *testing.T) { diff --git a/internal/dependencymanager/install.go b/internal/dependencymanager/install.go index 7d59870a0..c180634ad 100644 --- a/internal/dependencymanager/install.go +++ b/internal/dependencymanager/install.go @@ -74,15 +74,16 @@ Examples: flow dependencies install --deployment-account my-account FlowToken flow dependencies install -d my-account FlowToken - 8. Install a dependency with a custom name: + 8. Install a dependency with an import alias (for Cadence import aliasing): flow dependencies install --name USDF testnet://0x1234abcd.FiatToken flow dependencies install --name MyToken mainnet://0xabcd1234.TokenContract + This creates an import alias that enables "import FiatToken as USDF from 0x1234abcd" syntax in Cadence. Flags: • --deployment-account, -d: Specify the account name to use for deployments (skips deployment account prompt) • --skip-deployments: Skip adding the dependency to deployments • --skip-alias: Skip prompting for an alias -• --name: Custom name for the dependency (e.g., --name USDF) +• --name: Import alias name for the dependency (sets canonical field for Cadence import aliasing, e.g., --name USDF) Note: • Using 'network://address' will attempt to install all contracts deployed at that address. From b898bc10720c59d34622553f45d8ac84c3c28b74 Mon Sep 17 00:00:00 2001 From: Chase Fleming <1666730+chasefleming@users.noreply.github.com> Date: Mon, 24 Nov 2025 17:12:51 -0800 Subject: [PATCH 4/4] Simplify test --- .../dependencyinstaller_test.go | 31 ++++++++----------- 1 file changed, 13 insertions(+), 18 deletions(-) diff --git a/internal/dependencymanager/dependencyinstaller_test.go b/internal/dependencymanager/dependencyinstaller_test.go index 6f3dad21b..8e099c8e8 100644 --- a/internal/dependencymanager/dependencyinstaller_test.go +++ b/internal/dependencymanager/dependencyinstaller_test.go @@ -767,8 +767,6 @@ func TestDependencyInstallerWithAlias(t *testing.T) { di := &DependencyInstaller{ Gateways: map[string]gateway.Gateway{ config.EmulatorNetwork.Name: gw.Mock, - config.TestnetNetwork.Name: gw.Mock, - config.MainnetNetwork.Name: gw.Mock, }, Logger: logger, State: state, @@ -802,11 +800,20 @@ func TestDependencyInstallerWithAlias(t *testing.T) { }) t.Run("AddByCoreContractNameWithName", func(t *testing.T) { + // Mock the gateway to return FlowToken contract + gw := mocks.DefaultMockGateway() + gw.GetAccount.Run(func(args mock.Arguments) { + addr := args.Get(1).(flow.Address) + acc := tests.NewAccountWithAddress(addr.String()) + acc.Contracts = map[string][]byte{ + "FlowToken": []byte("access(all) contract FlowToken {}"), + } + gw.GetAccount.Return(acc, nil) + }) + di := &DependencyInstaller{ Gateways: map[string]gateway.Gateway{ - config.EmulatorNetwork.Name: mocks.DefaultMockGateway().Mock, - config.TestnetNetwork.Name: mocks.DefaultMockGateway().Mock, - config.MainnetNetwork.Name: mocks.DefaultMockGateway().Mock, + config.MainnetNetwork.Name: gw.Mock, }, Logger: logger, State: state, @@ -818,19 +825,6 @@ func TestDependencyInstallerWithAlias(t *testing.T) { dependencies: make(map[string]config.Dependency), } - // Mock the gateway to return FlowToken contract - gw := mocks.DefaultMockGateway() - gw.GetAccount.Run(func(args mock.Arguments) { - addr := args.Get(1).(flow.Address) - acc := tests.NewAccountWithAddress(addr.String()) - acc.Contracts = map[string][]byte{ - "FlowToken": []byte("access(all) contract FlowToken {}"), - } - gw.GetAccount.Return(acc, nil) - }) - - di.Gateways[config.MainnetNetwork.Name] = gw.Mock - err := di.AddByCoreContractName("FlowToken") assert.NoError(t, err, "Failed to add core contract with import alias") @@ -842,6 +836,7 @@ func TestDependencyInstallerWithAlias(t *testing.T) { }) t.Run("AddAllByNetworkAddressWithNameError", func(t *testing.T) { + // This test doesn't need gateways since it returns an error before making any gateway calls di := &DependencyInstaller{ Logger: logger, State: state,