From bdaa802a66d4b4b73e0419b2308b322a96db02f1 Mon Sep 17 00:00:00 2001 From: Josh Hannan Date: Thu, 30 Jan 2025 16:05:16 -0600 Subject: [PATCH] first draft of go package to get contracts and transactions --- go.mod | 25 +- go.sum | 18 + gotests/contracts_test.go | 28 + main.go | 1093 ++++++++++++++++++++++--------------- 4 files changed, 725 insertions(+), 439 deletions(-) create mode 100644 gotests/contracts_test.go diff --git a/go.mod b/go.mod index 92db811c..ce7046cd 100644 --- a/go.mod +++ b/go.mod @@ -1,10 +1,12 @@ module github.com/onflow/flow-evm-bridge -go 1.21.5 +go 1.22 + +toolchain go1.23.1 require ( github.com/bjartek/overflow/v2 v2.0.0-stable-cadence-beta.13 - github.com/onflow/cadence v1.0.0-preview.25 + github.com/onflow/cadence v1.0.0-preview.51 ) require ( @@ -132,22 +134,23 @@ require ( github.com/multiformats/go-varint v0.0.7 // indirect github.com/nightlyone/lockfile v1.0.0 // indirect github.com/olekukonko/tablewriter v0.0.5 // indirect - github.com/onflow/atree v0.7.0-rc.1 // indirect + github.com/onflow/atree v0.8.0-rc.6 // indirect github.com/onflow/crypto v0.25.1 // indirect github.com/onflow/flixkit-go v1.2.1-cadence-v1-preview.10 // indirect github.com/onflow/flow-core-contracts/lib/go/contracts v0.15.2-0.20240429192223-e696a8e439b5 // indirect - github.com/onflow/flow-core-contracts/lib/go/templates v0.15.2-0.20240429192223-e696a8e439b5 // indirect + github.com/onflow/flow-core-contracts/lib/go/templates v1.4.0 // indirect github.com/onflow/flow-emulator v1.0.0-preview.22 // indirect + github.com/onflow/flow-evm-bridge/bridge v0.0.0-00010101000000-000000000000 // indirect github.com/onflow/flow-ft/lib/go/contracts v0.7.1-0.20240424211859-3ff4c0fe2a1e // indirect - github.com/onflow/flow-ft/lib/go/templates v0.7.1-0.20240424211859-3ff4c0fe2a1e // indirect + github.com/onflow/flow-ft/lib/go/templates v1.0.1 // indirect github.com/onflow/flow-go v0.34.0-crescendo-preview.18 // indirect - github.com/onflow/flow-go-sdk v1.0.0-preview.25 // indirect + github.com/onflow/flow-go-sdk v1.0.0-preview.54 // indirect github.com/onflow/flow-nft/lib/go/contracts v1.1.1-0.20240429184308-40c3de711140 // indirect - github.com/onflow/flow-nft/lib/go/templates v0.0.0-20240429184308-40c3de711140 // indirect - github.com/onflow/flow/protobuf/go/flow v0.4.1-0.20240412170550-911321113030 // indirect + github.com/onflow/flow-nft/lib/go/templates v1.2.1 // indirect + github.com/onflow/flow/protobuf/go/flow v0.4.3 // indirect github.com/onflow/flowkit/v2 v2.0.0-stable-cadence-alpha.18 // indirect github.com/onflow/go-ethereum v1.13.4 // indirect - github.com/onflow/sdks v0.5.1-0.20230912225508-b35402f12bba // indirect + github.com/onflow/sdks v0.6.0-preview.1 // indirect github.com/pbnjay/memory v0.0.0-20210728143218-7b4eea64cf58 // indirect github.com/pelletier/go-toml/v2 v2.0.6 // indirect github.com/pierrec/lz4 v2.6.1+incompatible // indirect @@ -225,7 +228,7 @@ require ( google.golang.org/protobuf v1.33.0 // indirect gopkg.in/ini.v1 v1.67.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect - lukechampine.com/blake3 v1.2.1 // indirect + lukechampine.com/blake3 v1.3.0 // indirect modernc.org/libc v1.37.6 // indirect modernc.org/mathutil v1.6.0 // indirect modernc.org/memory v1.7.2 // indirect @@ -233,3 +236,5 @@ require ( mvdan.cc/gofumpt v0.5.0 // indirect rsc.io/tmplfunc v0.0.3 // indirect ) + +replace github.com/onflow/flow-evm-bridge/bridge => ./ diff --git a/go.sum b/go.sum index 512af8ee..c62781f4 100644 --- a/go.sum +++ b/go.sum @@ -1965,9 +1965,13 @@ github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6 github.com/onflow/atree v0.6.1-0.20230711151834-86040b30171f/go.mod h1:xvP61FoOs95K7IYdIYRnNcYQGf4nbF/uuJ0tHf4DRuM= github.com/onflow/atree v0.7.0-rc.1 h1:g2DFhC3JeaA+L7/HZOp4NwE+OfxvfJ8nibymHHw7i3g= github.com/onflow/atree v0.7.0-rc.1/go.mod h1:xvP61FoOs95K7IYdIYRnNcYQGf4nbF/uuJ0tHf4DRuM= +github.com/onflow/atree v0.8.0-rc.6 h1:GWgaylK24b5ta2Hq+TvyOF7X5tZLiLzMMn7lEt59fsA= +github.com/onflow/atree v0.8.0-rc.6/go.mod h1:yccR+LR7xc1Jdic0mrjocbHvUD7lnVvg8/Ct1AA5zBo= github.com/onflow/cadence v1.0.0-M3/go.mod h1:odXGZZ/wGNA5mwT8bC9v8u8EXACHllB2ABSZK65TGL8= github.com/onflow/cadence v1.0.0-preview.25 h1:kSmWjxmg9PS+bsk8C3j1NUTkFAl/jNrintVhlh6miM0= github.com/onflow/cadence v1.0.0-preview.25/go.mod h1:fGhLBbuEmv5rh48qv0ZS0tUz53gxWsHpB4dPsF09h6E= +github.com/onflow/cadence v1.0.0-preview.51 h1:L+toCS2Sw9bsExc2PxeNMmAK96fn2LdTOD9bl5K/etA= +github.com/onflow/cadence v1.0.0-preview.51/go.mod h1:7wvvecnAZtYOspLOS3Lh+FuAmMeSrXhAWiycC3kQ1UU= github.com/onflow/crypto v0.25.0/go.mod h1:C8FbaX0x8y+FxWjbkHy0Q4EASCDR9bSPWZqlpCLYyVI= github.com/onflow/crypto v0.25.1 h1:0txy2PKPMM873JbpxQNbJmuOJtD56bfs48RQfm0ts5A= github.com/onflow/crypto v0.25.1/go.mod h1:C8FbaX0x8y+FxWjbkHy0Q4EASCDR9bSPWZqlpCLYyVI= @@ -1977,30 +1981,42 @@ github.com/onflow/flow-core-contracts/lib/go/contracts v0.15.2-0.20240429192223- github.com/onflow/flow-core-contracts/lib/go/contracts v0.15.2-0.20240429192223-e696a8e439b5/go.mod h1:+4JWLclBOT+emyBh6NAZSEbqEwzHcWHpIbfsXmRASgY= github.com/onflow/flow-core-contracts/lib/go/templates v0.15.2-0.20240429192223-e696a8e439b5 h1:6Cg0h+8Iyy/Nnefk5j0gdeVoMTNpUooAMjyV8sk6zoA= github.com/onflow/flow-core-contracts/lib/go/templates v0.15.2-0.20240429192223-e696a8e439b5/go.mod h1:0oTx6Nkc+LdOXaZe3PRtV1cY+J5z5ig08alR8d+OPHs= +github.com/onflow/flow-core-contracts/lib/go/templates v1.4.0 h1:u2DAG8pk0xFH7TwS70t1gSZ/FtIIZWMSNyiu4SeXBYg= +github.com/onflow/flow-core-contracts/lib/go/templates v1.4.0/go.mod h1:pN768Al/wLRlf3bwugv9TyxniqJxMu4sxnX9eQJam64= github.com/onflow/flow-emulator v1.0.0-preview.22 h1:l0BPXlDvK0gZDqQhY3Kc7pBm38pE/FbfefiZe7j6Ngg= github.com/onflow/flow-emulator v1.0.0-preview.22/go.mod h1:60M4QPVpdpEhEdz6NGOtLule+jcRLLKID1gYv2ehLvw= github.com/onflow/flow-ft/lib/go/contracts v0.7.1-0.20240424211859-3ff4c0fe2a1e h1:2LO6Rtmz2PVfH+ZXnMwvTwVeIz3PCy0fs3lQraqog14= github.com/onflow/flow-ft/lib/go/contracts v0.7.1-0.20240424211859-3ff4c0fe2a1e/go.mod h1:PwsL8fC81cjnUnTfmyL/HOIyHnyaw/JA474Wfj2tl6A= github.com/onflow/flow-ft/lib/go/templates v0.7.1-0.20240424211859-3ff4c0fe2a1e h1:jl7SYAui/gYRmBofrY//Ln8ixRJwvLzvwLstNfRKmWY= github.com/onflow/flow-ft/lib/go/templates v0.7.1-0.20240424211859-3ff4c0fe2a1e/go.mod h1:uQ8XFqmMK2jxyBSVrmyuwdWjTEb+6zGjRYotfDJ5pAE= +github.com/onflow/flow-ft/lib/go/templates v1.0.1 h1:FDYKAiGowABtoMNusLuRCILIZDtVqJ/5tYI4VkF5zfM= +github.com/onflow/flow-ft/lib/go/templates v1.0.1/go.mod h1:uQ8XFqmMK2jxyBSVrmyuwdWjTEb+6zGjRYotfDJ5pAE= github.com/onflow/flow-go v0.34.0-crescendo-preview.18 h1:Bre7uU/n1PjOEcIkTtaJDo4T5tngjKcr/cAOvxr3se4= github.com/onflow/flow-go v0.34.0-crescendo-preview.18/go.mod h1:bwjzi2kSev1emRVN685FqYfCLYcZ6t2A5z5ztYXfvH8= github.com/onflow/flow-go-sdk v1.0.0-M1/go.mod h1:TDW0MNuCs4SvqYRUzkbRnRmHQL1h4X8wURsCw9P9beo= github.com/onflow/flow-go-sdk v1.0.0-preview.25 h1:wL/+cK7oxSww31qSqTpt1Yfr26c8hJ8YHh9nIdq6PlI= github.com/onflow/flow-go-sdk v1.0.0-preview.25/go.mod h1:Px1fQdB7WFC0yhYsEM3rhKzuE+Zi8GpBjR4qVuDAwMA= +github.com/onflow/flow-go-sdk v1.0.0-preview.54 h1:5GjCkyIyvE9KolOUUPTkGdEiV/8qOe1MGnLHOLBmthA= +github.com/onflow/flow-go-sdk v1.0.0-preview.54/go.mod h1:u9oFiS25TpnU1EW62PQlq22jzkwBAj4VEiiCBM6nhHo= github.com/onflow/flow-nft/lib/go/contracts v1.1.1-0.20240429184308-40c3de711140 h1:oTj4RGgfuJSSBE1aDVrlh6avxKBMraucpNtRg0K+yhg= github.com/onflow/flow-nft/lib/go/contracts v1.1.1-0.20240429184308-40c3de711140/go.mod h1:2gpbza+uzs1k7x31hkpBPlggIRkI53Suo0n2AyA2HcE= github.com/onflow/flow-nft/lib/go/templates v0.0.0-20240429184308-40c3de711140 h1:7NwSIG4SEdm+96gr+Aaqx291jZ/Bqkxk/ghVnens9CU= github.com/onflow/flow-nft/lib/go/templates v0.0.0-20240429184308-40c3de711140/go.mod h1:p+2hRvtjLUR3MW1NsoJe5Gqgr2eeH49QB6+s6ze00w0= +github.com/onflow/flow-nft/lib/go/templates v1.2.1 h1:SAALMZPDw9Eb9p5kSLnmnFxjyig1MLiT4JUlLp0/bSE= +github.com/onflow/flow-nft/lib/go/templates v1.2.1/go.mod h1:W6hOWU0xltPqNpv9gQX8Pj8Jtf0OmRxc1XX2V0kzJaI= github.com/onflow/flow/protobuf/go/flow v0.3.2-0.20231121210617-52ee94b830c2/go.mod h1:NA2pX2nw8zuaxfKphhKsk00kWLwfd+tv8mS23YXO4Sk= github.com/onflow/flow/protobuf/go/flow v0.4.1-0.20240412170550-911321113030 h1:I+aosSiJny88O4p3nPbCiUcp/UqN6AepvO6uj82bjH0= github.com/onflow/flow/protobuf/go/flow v0.4.1-0.20240412170550-911321113030/go.mod h1:NA2pX2nw8zuaxfKphhKsk00kWLwfd+tv8mS23YXO4Sk= +github.com/onflow/flow/protobuf/go/flow v0.4.3 h1:gdY7Ftto8dtU+0wI+6ZgW4oE+z0DSDUMIDwVx8mqae8= +github.com/onflow/flow/protobuf/go/flow v0.4.3/go.mod h1:NA2pX2nw8zuaxfKphhKsk00kWLwfd+tv8mS23YXO4Sk= github.com/onflow/flowkit/v2 v2.0.0-stable-cadence-alpha.18 h1:vgQ1SpQ9mpTX+c6x1hm71DmaLnHoMr3kIG479Ye0ll4= github.com/onflow/flowkit/v2 v2.0.0-stable-cadence-alpha.18/go.mod h1:uQiVIHhm6dXrXDM9SQG00FIaEQgh+TdVvM+ortvpF+M= github.com/onflow/go-ethereum v1.13.4 h1:iNO86fm8RbBbhZ87ZulblInqCdHnAQVY8okBrNsTevc= github.com/onflow/go-ethereum v1.13.4/go.mod h1:cE/gEUkAffhwbVmMJYz+t1dAfVNHNwZCgc3BWtZxBGY= github.com/onflow/sdks v0.5.1-0.20230912225508-b35402f12bba h1:rIehuhO6bj4FkwE4VzwEjX7MoAlOhUJENBJLqDqVxAo= github.com/onflow/sdks v0.5.1-0.20230912225508-b35402f12bba/go.mod h1:F0dj0EyHC55kknLkeD10js4mo14yTdMotnWMslPirrU= +github.com/onflow/sdks v0.6.0-preview.1 h1:mb/cUezuqWEP1gFZNAgUI4boBltudv4nlfxke1KBp9k= +github.com/onflow/sdks v0.6.0-preview.1/go.mod h1:F0dj0EyHC55kknLkeD10js4mo14yTdMotnWMslPirrU= github.com/onflow/wal v0.0.0-20240208022732-d756cd497d3b h1:6O/BEmA99PDT5QVjoJgrYlGsWnpxGJTAMmsC+V9gyds= github.com/onflow/wal v0.0.0-20240208022732-d756cd497d3b/go.mod h1:iMC8gkLqu4nkbkAla5HkSBb+FGyQOZiWz3DYm2wSXCk= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= @@ -3296,6 +3312,8 @@ launchpad.net/gocheck v0.0.0-20140225173054-000000000087/go.mod h1:hj7XX3B/0A+80 lukechampine.com/blake3 v1.1.7/go.mod h1:tkKEOtDkNtklkXtLNEOGNq5tcV90tJiA1vAA12R78LA= lukechampine.com/blake3 v1.2.1 h1:YuqqRuaqsGV71BV/nm9xlI0MKUv4QC54jQnBChWbGnI= lukechampine.com/blake3 v1.2.1/go.mod h1:0OFRp7fBtAylGVCO40o87sbupkyIGgbpv1+M1k1LM6k= +lukechampine.com/blake3 v1.3.0 h1:sJ3XhFINmHSrYCgl958hscfIa3bw8x4DqMP3u1YvoYE= +lukechampine.com/blake3 v1.3.0/go.mod h1:0OFRp7fBtAylGVCO40o87sbupkyIGgbpv1+M1k1LM6k= lukechampine.com/uint128 v1.1.1/go.mod h1:c4eWIwlEGaxC/+H1VguhU4PHXNWDCDMUlWdIWl2j1gk= lukechampine.com/uint128 v1.2.0/go.mod h1:c4eWIwlEGaxC/+H1VguhU4PHXNWDCDMUlWdIWl2j1gk= modernc.org/cc/v3 v3.36.0/go.mod h1:NFUHyPn4ekoC/JHeZFfZurN6ixxawE1BnVonP/oahEI= diff --git a/gotests/contracts_test.go b/gotests/contracts_test.go new file mode 100644 index 00000000..29839453 --- /dev/null +++ b/gotests/contracts_test.go @@ -0,0 +1,28 @@ +package contracts_test + +import ( + "testing" + + "github.com/stretchr/testify/assert" + + coreContracts "github.com/onflow/flow-core-contracts/lib/go/templates" + "github.com/onflow/flow-evm-bridge/bridge" +) + +const ( + fakeAddr = "0x0A" +) + +func TestContract(t *testing.T) { + coreEnv := coreContracts.Environment{ + FungibleTokenAddress: fakeAddr, + ViewResolverAddress: fakeAddr, + BurnerAddress: fakeAddr, + } + + bridgeEnv := bridge.Environment{ + CrossVMNFTAddress: fakeAddr, + } + contract := bridge.GetCadenceCode("cadence/contracts/bridge/interfaces/CrossVMNFT.cdc", bridgeEnv, coreEnv) + assert.NotNil(t, contract) +} diff --git a/main.go b/main.go index 87ee6d65..55832612 100644 --- a/main.go +++ b/main.go @@ -1,486 +1,721 @@ -package main +package bridge import ( - "context" - "encoding/json" - "io/ioutil" + "embed" + "fmt" "log" - "os" - "path/filepath" - "slices" "strings" - . "github.com/bjartek/overflow/v2" - "github.com/onflow/cadence" + coreContracts "github.com/onflow/flow-core-contracts/lib/go/templates" ) -/** - * This script is used to configure the bridge contracts on various networks. - * The following assumptions about the bridge account are made: - * - The bridge account is named "NETWORK-flow-evm-bridge" in the flow.json - * - The bridge account has a balance to cover funding a COA with 1.0 FLOW tokens (if necessary) - * - The bridge account has enough FLOW to cover the storage required for the deployed contracts - */ +//go:embed cadence/contracts/bridge/interfaces/CrossVMNFT.cdc +var content embed.FS + +var ( + placeholderFungibleTokenAddress = "\"FungibleToken\"" + placeholderFungibleTokenMVAddress = "\"FungibleTokenMetadataViews\"" + placeholderMetadataViewsAddress = "\"MetadataViews\"" + placeholderFlowTokenAddress = "\"FlowToken\"" + placeholderBurnerAddress = "\"Burner\"" + placeholderViewResolverAddress = "\"ViewResolver\"" + placeholderNFTAddress = "\"NonFungibleToken\"" + + placeholderCrossVMNFTAddress = "\"CrossVMNFT\"" + placeholderCrossVMTokenAddress = "\"CrossVMToken\"" + placeholderFlowEVMBridgeHandlerInterfacesAddress = "\"FlowEVMBridgeHandlerInterfaces\"" + placeholderIBridgePermissionsAddress = "\"IBridgePermissions\"" + placeholderICrossVMAddress = "\"ICrossVM\"" + placeholderICrossVMAssetAddress = "\"ICrossVMAsset\"" + placeholderIEVMBridgeNFTMinterAddress = "\"IEVMBridgeNFTMinter\"" + placeholderIEVMBridgeTokenMinterAddress = "\"IEVMBridgeTokenMinter\"" + placeholderIFlowEVMNFTBridgeAddress = "\"IFlowEVMNFTBridge\"" + placeholderIFlowEVMTokenBridgeAddress = "\"IFlowEVMTokenBridge\"" + placeholderFlowEVMBridgeAddress = "\"FlowEVMBridge\"" + placeholderFlowEVMBridgeAccessorAddress = "\"FlowEVMBridgeAccessor\"" + placeholderFlowEVMBridgeConfigAddress = "\"FlowEVMBridgeConfig\"" + placeholderFlowEVMBridgeHandlersAddress = "\"FlowEVMBridgeHandlers\"" + placeholderFlowEVMBridgeNFTEscrowAddress = "\"FlowEVMBridgeNFTEscrow\"" + placeholderFlowEVMBridgeResolverAddress = "\"FlowEVMBridgeResolver\"" + placeholderFlowEVMBridgeTemplatesAddress = "\"FlowEVMBridgeTemplates\"" + placeholderFlowEVMBridgeTokenEscrowAddress = "\"FlowEVMBridgeTokenEscrow\"" + placeholderFlowEVMBridgeUtilsAddress = "\"FlowEVMBridgeUtils\"" + + placeholderArrayUtilsAddress = "\"ArrayUtils\"" + placeholderScopedFTProvidersAddress = "\"ScopedFTProviders\"" + placeholderSerializeAddress = "\"Serialize\"" + placeholderSerializeMetadataAddress = "\"SerializeMetadata\"" + placeholderStringUtilsAddress = "\"StringUtils\"" +) -// Overflow prefixes signer names with the current network - e.g. "crescendo-flow-evm-bridge" -// Ensure accounts in flow.json are named accordingly -var networks = []string{"crescendo", "emulator", "mainnet", "previewnet", "testnet"} - -// Pulled from flow.json deployments. Specified here as some contracts have init arg values that -// are emitted in transaction events and cannot be hardcoded in the deployment config section -var contracts = []string{ - "FlowEVMBridgeHandlerInterfaces", - "ArrayUtils", - "StringUtils", - "ScopedFTProviders", - "Serialize", - "SerializeMetadata", - "IBridgePermissions", - "ICrossVM", - "ICrossVMAsset", - "CrossVMNFT", - "CrossVMToken", - "FlowEVMBridgeConfig", - "FlowEVMBridgeUtils", - "FlowEVMBridgeResolver", - "FlowEVMBridgeHandlers", - "FlowEVMBridgeNFTEscrow", - "FlowEVMBridgeTokenEscrow", - "FlowEVMBridgeTemplates", - "IEVMBridgeNFTMinter", - "IEVMBridgeTokenMinter", - "IFlowEVMNFTBridge", - "IFlowEVMTokenBridge", - "FlowEVMBridge", +type Environment struct { + CrossVMNFTAddress string + CrossVMTokenAddress string + FlowEVMBridgeHandlerInterfacesAddress string + IBridgePermissionsAddress string + ICrossVMAddress string + ICrossVMAssetAddress string + IEVMBridgeNFTMinterAddress string + IEVMBridgeTokenMinterAddress string + IFlowEVMNFTBridgeAddress string + IFlowEVMTokenBridgeAddress string + FlowEVMBridgeAddress string + FlowEVMBridgeAccessorAddress string + FlowEVMBridgeConfigAddress string + FlowEVMBridgeHandlersAddress string + FlowEVMBridgeNFTEscrowAddress string + FlowEVMBridgeResolverAddress string + FlowEVMBridgeTemplatesAddress string + FlowEVMBridgeTokenEscrowAddress string + FlowEVMBridgeUtilsAddress string + ArrayUtilsAddress string + ScopedFTProvidersAddress string + SerializeAddress string + SerializeMetadataAddress string + StringUtilsAddress string } -// To run, execute the following command: -// go run main.go $NETWORK -func main() { - network := getSpecifiedNetwork() - - dir, err := os.Getwd() - checkNoErr(err) - - ctx := context.Background() - o := Overflow( - WithNetwork(network), - WithTransactionFolderName("cadence/transactions"), - WithScriptFolderName("cadence/scripts"), - WithGlobalPrintOptions(WithTransactionUrl()), - ) - - // Check if the script is a dry run - if checkDryRun() { - log.Printf("Dry run detected...running setup script in dry run mode") - // Run the dry run transaction - serviceDryRunResult := o.Tx("bridge/admin/dry_run", WithSigner("service-account")) - checkNoErr(serviceDryRunResult.Err) - log.Printf("Service Account dry run run successful...") - bridgeDryRunResult := o.Tx("bridge/admin/dry_run", WithSigner("flow-evm-bridge")) - checkNoErr(bridgeDryRunResult.Err) - log.Printf("Bridge Account dry run run successful...") - log.Printf("Dry run complete...exiting script") - return +func withHexPrefix(address string) string { + if address == "" { + return "" } - // Create a COA in the bridge account if one does not already exist - bridgeCOAHex, err := o.Script("evm/get_evm_address_string", WithArg("flowAddress", o.Address("flow-evm-bridge"))).GetAsInterface() - checkNoErr(err) - if bridgeCOAHex == nil { - // no COA found, create a COA in the bridge account - coaCreationTxn := o.Tx("evm/create_account", WithSigner("flow-evm-bridge"), WithArg("amount", 1.0)) - checkNoErr(coaCreationTxn.Err) - bridgeCOAHex, err = o.Script("evm/get_evm_address_string", WithArg("flowAddress", o.Address("flow-evm-bridge"))).GetAsInterface() - checkNoErr(err) - } - log.Printf("Bridge COA has EVM address: %s", bridgeCOAHex) - - /* --- EVM Configuration --- */ - - gasLimit := 15000000 - deploymentValue := 0.0 - - /// Deploy factory /// - // - // Get the Cadence args json for the factory deployment args - factoryArgsPath := filepath.Join(dir, "cadence/args/deploy-factory-args.json") - // Retrieve the bytecode from the JSON args - // Future implementations should use flowkit to handle this after fixing dependency issues - factoryBytecode := getBytecodeFromArgsJSON(factoryArgsPath) - factoryDeployment := o.Tx("evm/deploy", - WithSigner("flow-evm-bridge"), - WithArg("bytecode", factoryBytecode), - WithArg("gasLimit", gasLimit), - WithArg("value", deploymentValue), - ) - checkNoErr(factoryDeployment.Err) - factoryAddr := getContractAddressFromEVMEvent(factoryDeployment) - - log.Printf("Factory deployed to address: %s", factoryAddr) - - /// Deploy registry /// - // - // Get the Cadence args json for the factory deployment args - registryArgsPath := filepath.Join(dir, "cadence/args/deploy-deployment-registry-args.json") - // Retrieve the bytecode from the JSON args - // Future implementations should use flowkit to handle this after fixing dependency issues - registryBytecode := getBytecodeFromArgsJSON(registryArgsPath) - registryDeployment := o.Tx("evm/deploy", - WithSigner("flow-evm-bridge"), - WithArg("bytecode", registryBytecode), - WithArg("gasLimit", gasLimit), - WithArg("value", deploymentValue), - ) - checkNoErr(registryDeployment.Err) - registryAddr := getContractAddressFromEVMEvent(registryDeployment) - - log.Printf("Registry deployed to address: %s", registryAddr) - - /// Deploy ERC20 deployer /// - // - erc20DeployerArgsPath := filepath.Join(dir, "cadence/args/deploy-erc20-deployer-args.json") - erc20DeployerBytecode := getBytecodeFromArgsJSON(erc20DeployerArgsPath) - erc20DeployerDeployment := o.Tx("evm/deploy", - WithSigner("flow-evm-bridge"), - WithArg("bytecode", erc20DeployerBytecode), - WithArg("gasLimit", gasLimit), - WithArg("value", deploymentValue), - ) - checkNoErr(erc20DeployerDeployment.Err) - erc20DeployerAddr := getContractAddressFromEVMEvent(erc20DeployerDeployment) - - log.Printf("ERC20 Deployer deployed to address: %s", erc20DeployerAddr) - - /// Deploy ERC721 deployer /// - // - erc721DeployerArgsPath := filepath.Join(dir, "cadence/args/deploy-erc721-deployer-args.json") - erc721DeployerBytecode := getBytecodeFromArgsJSON(erc721DeployerArgsPath) - erc721DeployerDeployment := o.Tx("evm/deploy", - WithSigner("flow-evm-bridge"), - WithArg("bytecode", erc721DeployerBytecode), - WithArg("gasLimit", gasLimit), - WithArg("value", deploymentValue), - ) - checkNoErr(erc721DeployerDeployment.Err) - erc721DeployerAddr := getContractAddressFromEVMEvent(erc721DeployerDeployment) - - log.Printf("ERC721 Deployer deployed to address: %s", erc721DeployerAddr) - - /* --- Cadence Configuration --- */ - - log.Printf("Deploying Cadence contracts...") - // Iterate over contracts in the contracts map - for _, name := range contracts { - - log.Printf("Deploying contract: %s...", name) - - contract, err := o.State.Config().Contracts.ByName(name) - checkNoErr(err) - contractPath := filepath.Join(dir, contract.Location) - contractCode, err := os.ReadFile(contractPath) - checkNoErr(err) - - // If the contract is already deployed as-is, skip deployment - a, err := o.GetAccount(ctx, "flow-evm-bridge") - checkNoErr(err) - log.Printf("Checking if contract %s is already deployed...", name) - if a.Contracts[name] != nil { - log.Printf("Contract %s already deployed, skipping...", name) - continue - } - log.Printf("Contract %s not found on %s, deploying...", name, network) - - var args []cadence.Value - if name == "FlowEVMBridgeUtils" { - args = []cadence.Value{cadence.String(factoryAddr)} - } else { - args = []cadence.Value{} - } - - err = o.AddContract(ctx, "flow-evm-bridge", contractCode, args, contractPath, true) - checkNoErr(err) + if address[0:2] == "0x" { + return address } - log.Printf("Cadence contracts deployed...Pausing bridge for setup...") - - // If emulator, deploy USDCFlow contract - if network == "emulator" { - log.Printf("Emulator detected...deploying USDCFlow contract...") - - usdcContract, err := o.State.Config().Contracts.ByName("USDCFlow") - checkNoErr(err) - usdcPath := filepath.Join(dir, usdcContract.Location) - usdcCode, err := os.ReadFile(usdcPath) - checkNoErr(err) + return fmt.Sprintf("0x%s", address) +} - err = o.AddContract(ctx, "flow-evm-bridge", usdcCode, []cadence.Value{}, usdcPath, true) - checkNoErr(err) +func ReplaceAddresses(code string, bridgeEnv Environment, coreEnv coreContracts.Environment) string { - log.Printf("USDCFlow contract deployed...") - } + code = coreContracts.ReplaceAddresses(code, coreEnv) - // Pause the bridge for setup - var pauseResult = o.Tx("bridge/admin/pause/update_bridge_pause_status", - WithSigner("flow-evm-bridge"), - WithArg("pause", true), + code = strings.ReplaceAll( + code, + placeholderCrossVMNFTAddress, + withHexPrefix(bridgeEnv.CrossVMNFTAddress), ) - checkNoErr(pauseResult.Err) - - log.Printf("Bridge deployed and paused...") - - /* --- USDCFlow TokenHandler Configuration --- */ - - // Add USDCFlow TokenHandler - // usdcFlowAddr := o.Address("USDCFlow") - // usdcFlowVaultIdentifier := buildUSDCFlowVaultIdentifier(usdcFlowAddr) - // usdcFlowMinterIdentifier := buildUSDCFlowMinterIdentifier(usdcFlowAddr) - - // log.Printf("Bridge pause confirmed...configuring USDCFlow TokenHandler with vault=" + usdcFlowVaultIdentifier + " and minter=" + usdcFlowMinterIdentifier) - // // execute create_cadence_native_token_handler transaction - // createTokenHandlerResult := o.Tx("bridge/admin/token-handler/create_cadence_native_token_handler", - // WithSigner("flow-evm-bridge"), - // WithArg("vaultIdentifier", usdcFlowVaultIdentifier), - // WithArg("minterIdentifier", usdcFlowMinterIdentifier), - // ) - // checkNoErr(createTokenHandlerResult.Err) - - // log.Printf("USDCFlow TokenHandler configured...") - - /* --- Finish EVM Contract Setup --- */ - - log.Printf("Integrating EVM-side bridge contracts...") - - // Set the factory as registrar in the registry - setRegistrarResult := o.Tx("bridge/admin/evm/set_registrar", - WithSigner("flow-evm-bridge"), - WithArg("registryEVMAddressHex", registryAddr), - ) - checkNoErr(setRegistrarResult.Err) - // Add the registry to the factory - setRegistryResult := o.Tx("bridge/admin/evm/set_deployment_registry", - WithSigner("flow-evm-bridge"), - WithArg("registryEVMAddressHex", registryAddr), + code = strings.ReplaceAll( + code, + placeholderCrossVMTokenAddress, + withHexPrefix(bridgeEnv.CrossVMTokenAddress), ) - checkNoErr(setRegistryResult.Err) - // Set the factory as delegated deployer in the ERC20 deployer - setDelegatedDeployerResult := o.Tx("bridge/admin/evm/set_delegated_deployer", - WithSigner("flow-evm-bridge"), - WithArg("deployerEVMAddressHex", erc20DeployerAddr), + code = strings.ReplaceAll( + code, + placeholderFlowEVMBridgeHandlerInterfacesAddress, + withHexPrefix(bridgeEnv.FlowEVMBridgeHandlerInterfacesAddress), ) - checkNoErr(setDelegatedDeployerResult.Err) - // Set the factory as delegated deployer in the ERC721 deployer - setDelegatedDeployerResult = o.Tx("bridge/admin/evm/set_delegated_deployer", - WithSigner("flow-evm-bridge"), - WithArg("deployerEVMAddressHex", erc721DeployerAddr), + code = strings.ReplaceAll( + code, + placeholderIBridgePermissionsAddress, + withHexPrefix(bridgeEnv.IBridgePermissionsAddress), ) - checkNoErr(setDelegatedDeployerResult.Err) - // Add the ERC20 Deployer as a deployer in the factory - addDeployerResult := o.Tx("bridge/admin/evm/add_deployer", - WithSigner("flow-evm-bridge"), - WithArg("deployerTag", "ERC20"), - WithArg("deployerEVMAddressHex", erc20DeployerAddr), + code = strings.ReplaceAll( + code, + placeholderICrossVMAddress, + withHexPrefix(bridgeEnv.ICrossVMAddress), ) - checkNoErr(addDeployerResult.Err) - - // Add the ERC721 Deployer as a deployer in the factory - addDeployerResult = o.Tx("bridge/admin/evm/add_deployer", - WithSigner("flow-evm-bridge"), - WithArg("deployerTag", "ERC721"), - WithArg("deployerEVMAddressHex", erc721DeployerAddr), + code = strings.ReplaceAll( + code, + placeholderICrossVMAssetAddress, + withHexPrefix(bridgeEnv.ICrossVMAssetAddress), ) - checkNoErr(addDeployerResult.Err) - - log.Printf("Cross-VM bridge contract integration complete...integrating with EVM contract...") - - /* --- EVM Contract Integration --- */ - - // Deploy FlowEVMBridgeAccessor, providing EVM contract host (network service account) as argument - accessorContract, err := o.State.Config().Contracts.ByName("FlowEVMBridgeAccessor") - checkNoErr(err) - // accessorPath := filepath.Join(projectRoot, accessorContract.Location) - accessorPath := filepath.Join(dir, accessorContract.Location) - accessorCode, err := os.ReadFile(accessorPath) - checkNoErr(err) - evmConfigAddr, err := o.State.Config().Contracts.ByName("EVM") - checkNoErr(err) - evmAddr := evmConfigAddr.Aliases.ByNetwork(o.GetNetwork()).Address - log.Printf("EVM contract address: %s", evmAddr) - err = o.AddContract(ctx, "flow-evm-bridge", accessorCode, []cadence.Value{cadence.NewAddress(evmAddr)}, accessorPath, false) - checkNoErr(err) - - // Integrate the EVM contract with the BridgeAccessor - integrateResult := o.Tx("bridge/admin/evm-integration/claim_accessor_capability_and_save_router", - WithSigner("service-account"), - WithArg("name", "FlowEVMBridgeAccessor"), - WithArg("provider", o.Address("FlowEVMBridge")), + code = strings.ReplaceAll( + code, + placeholderIEVMBridgeNFTMinterAddress, + withHexPrefix(bridgeEnv.IEVMBridgeNFTMinterAddress), ) - checkNoErr(integrateResult.Err) - - log.Printf("EVM integration complete...setting fees...") - - /* --- Set Bridge Fees --- */ - - onboardFeeResult := o.Tx("bridge/admin/fee/update_onboard_fee", - WithSigner("flow-evm-bridge"), - WithArg("newFee", 1.0), + code = strings.ReplaceAll( + code, + placeholderIEVMBridgeTokenMinterAddress, + withHexPrefix(bridgeEnv.IEVMBridgeTokenMinterAddress), ) - checkNoErr(onboardFeeResult.Err) - baseFeeResult := o.Tx("bridge/admin/fee/update_base_fee", - WithSigner("flow-evm-bridge"), - WithArg("newFee", 0.001), + code = strings.ReplaceAll( + code, + placeholderIFlowEVMNFTBridgeAddress, + withHexPrefix(bridgeEnv.IFlowEVMNFTBridgeAddress), ) - checkNoErr(baseFeeResult.Err) - - /* --- COMPLETE --- */ - - log.Printf("Bridge setup complete...Adding bridged Token & NFT templates") - - // TODO: Try to pull args JSON from local file once flowkit ParseJSON is fixed - tokenChunkPath := filepath.Join( - dir, - "cadence/args/bridged-token-code-chunks-args-"+network+".json", + code = strings.ReplaceAll( + code, + placeholderIFlowEVMTokenBridgeAddress, + withHexPrefix(bridgeEnv.IFlowEVMTokenBridgeAddress), + ) + code = strings.ReplaceAll( + code, + placeholderFlowEVMBridgeAddress, + withHexPrefix(bridgeEnv.FlowEVMBridgeAddress), ) - nftChunkPath := filepath.Join(dir, "cadence/args/bridged-nft-code-chunks-args-"+network+".json") - tokenChunks := getCodeChunksFromArgsJSON(tokenChunkPath) - nftChunks := getCodeChunksFromArgsJSON(nftChunkPath) - tokenChunkUpsert := o.Tx("bridge/admin/templates/upsert_contract_code_chunks", - WithSigner("flow-evm-bridge"), - WithArg("forTemplate", "bridgedToken"), - WithArg("newChunks", tokenChunks), + code = strings.ReplaceAll( + code, + placeholderFlowEVMBridgeAccessorAddress, + withHexPrefix(bridgeEnv.FlowEVMBridgeAccessorAddress), ) - checkNoErr(tokenChunkUpsert.Err) - nftChunkUpsert := o.Tx("bridge/admin/templates/upsert_contract_code_chunks", - WithSigner("flow-evm-bridge"), - WithArg("forTemplate", "bridgedNFT"), - WithArg("newChunks", nftChunks), + code = strings.ReplaceAll( + code, + placeholderFlowEVMBridgeConfigAddress, + withHexPrefix(bridgeEnv.FlowEVMBridgeConfigAddress), + ) + code = strings.ReplaceAll( + code, + placeholderFlowEVMBridgeHandlersAddress, + withHexPrefix(bridgeEnv.FlowEVMBridgeHandlersAddress), ) - checkNoErr(nftChunkUpsert.Err) - log.Printf("Templates have been added...Unpausing bridge...") + code = strings.ReplaceAll( + code, + placeholderFlowEVMBridgeNFTEscrowAddress, + withHexPrefix(bridgeEnv.FlowEVMBridgeNFTEscrowAddress), + ) - // Unpause the bridge - // unpauseResult := o.Tx("bridge/admin/pause/update_bridge_pause_status", - // WithSigner("flow-evm-bridge"), - // WithArg("pause", false), - // ) - // checkNoErr(unpauseResult.Err) + code = strings.ReplaceAll( + code, + placeholderFlowEVMBridgeResolverAddress, + withHexPrefix(bridgeEnv.FlowEVMBridgeResolverAddress), + ) - // log.Printf("SETUP COMPLETE! Bridge is now unpaused and ready for use.") - log.Printf("SETUP COMPLETE! Bridge is still paused - be sure to unpause before use.") -} + code = strings.ReplaceAll( + code, + placeholderFlowEVMBridgeTemplatesAddress, + withHexPrefix(bridgeEnv.FlowEVMBridgeTemplatesAddress), + ) -func checkDryRun() bool { - if len(os.Args) < 3 { - return false - } - return os.Args[2] == "--dry-run" -} + code = strings.ReplaceAll( + code, + placeholderFlowEVMBridgeTokenEscrowAddress, + withHexPrefix(bridgeEnv.FlowEVMBridgeTokenEscrowAddress), + ) -// Parses the network argument from the command line -// e.g. go run main.go $NETWORK -func getSpecifiedNetwork() string { - if len(os.Args) < 2 { - log.Fatal("Please provide a network as an argument: ", networks) - } - network := os.Args[1] + code = strings.ReplaceAll( + code, + placeholderFlowEVMBridgeUtilsAddress, + withHexPrefix(bridgeEnv.FlowEVMBridgeUtilsAddress), + ) - if !slices.Contains(networks, network) { - log.Fatal("Please provide a valid network as an argument: ", networks) - } - return network -} + code = strings.ReplaceAll( + code, + placeholderArrayUtilsAddress, + withHexPrefix(bridgeEnv.ArrayUtilsAddress), + ) -// Extracts the deployed contract address from the TransactionExecuted event -func getContractAddressFromEVMEvent(res *OverflowResult) string { - evts := res.GetEventsWithName("TransactionExecuted") - contractAddr := evts[0].Fields["contractAddress"] - if contractAddr == nil { - log.Fatal("Contract address not found in event") - } - return strings.ToLower(strings.Split(contractAddr.(string), "x")[1]) -} + code = strings.ReplaceAll( + code, + placeholderScopedFTProvidersAddress, + withHexPrefix(bridgeEnv.ScopedFTProvidersAddress), + ) -// Reads the JSON file at the specified path and returns the compiled solidity bytecode where the -// bytecode is the first element in the JSON array as a Cadence JSON string -func getBytecodeFromArgsJSON(path string) string { - argsData, err := os.ReadFile(path) - checkNoErr(err) + code = strings.ReplaceAll( + code, + placeholderSerializeAddress, + withHexPrefix(bridgeEnv.SerializeAddress), + ) - var args []map[string]string + code = strings.ReplaceAll( + code, + placeholderSerializeMetadataAddress, + withHexPrefix(bridgeEnv.SerializeMetadataAddress), + ) - err = json.Unmarshal(argsData, &args) - checkNoErr(err) + code = strings.ReplaceAll( + code, + placeholderStringUtilsAddress, + withHexPrefix(bridgeEnv.StringUtilsAddress), + ) - return args[0]["value"] + return code } -type Element struct { - Type string `json:"type"` - Value interface{} `json:"value"` -} +func GetCadenceCode(contractPath string, bridgeEnv Environment, coreEnv coreContracts.Environment) []byte { + + fileContent, err := content.ReadFile(contractPath) -// Reads the JSON file at the specified path and returns the code chunks where the code chunks are -// the second element in the JSON array as Cadence JSON string array -func getCodeChunksFromArgsJSON(path string) []string { - file, err := os.Open(path) if err != nil { - log.Fatalf("Failed opening file: %s", err) + log.Fatal(err) } - defer file.Close() - - byteValue, _ := ioutil.ReadAll(file) - var elements []Element - json.Unmarshal(byteValue, &elements) + // Convert []byte to string + code := string(fileContent) - secondElement := elements[1] + code = ReplaceAddresses(code, bridgeEnv, coreEnv) - // Check if the second element is of type "Array" - if secondElement.Type != "Array" { - log.Fatalf("Second element is not of type Array") + if strings.Contains(code, "import \"") { + log.Fatal("Missing import addresses for one or more contracts in the import list!") } - // Assert that the value is a slice of interfaces - values, ok := secondElement.Value.([]interface{}) - if !ok { - log.Fatalf("Failed to assert value to []interface{}") - } - - var strArr []string - for _, v := range values { - // Assert that the value is a map - valueMap, ok := v.(map[string]interface{}) - if !ok { - log.Fatalf("Failed to assert value to map[string]interface{}") - } - - // Get the "value" from the map and assert it to string - str, ok := valueMap["value"].(string) - if !ok { - log.Fatalf("Failed to assert value to string") - } - - strArr = append(strArr, str) - } - - return strArr -} - -func buildUSDCFlowVaultIdentifier(addrString string) string { - return "A." + strings.Split(addrString, "x")[1] + ".USDCFlow.Vault" + return []byte(code) } -func buildUSDCFlowMinterIdentifier(addrString string) string { - return "A." + strings.Split(addrString, "x")[1] + ".USDCFlow.Minter" -} +/** + * This script is used to configure the bridge contracts on various networks. + * The following assumptions about the bridge account are made: + * - The bridge account is named "NETWORK-flow-evm-bridge" in the flow.json + * - The bridge account has a balance to cover funding a COA with 1.0 FLOW tokens (if necessary) + * - The bridge account has enough FLOW to cover the storage required for the deployed contracts + */ -func checkNoErr(err error) { - if err != nil { - log.Fatal(err) - } -} +// Overflow prefixes signer names with the current network - e.g. "crescendo-flow-evm-bridge" +// Ensure accounts in flow.json are named accordingly +// var networks = []string{"crescendo", "emulator", "mainnet", "previewnet", "testnet"} + +// // Pulled from flow.json deployments. Specified here as some contracts have init arg values that +// // are emitted in transaction events and cannot be hardcoded in the deployment config section +// var contracts = []string{ +// "FlowEVMBridgeHandlerInterfaces", +// "ArrayUtils", +// "StringUtils", +// "ScopedFTProviders", +// "Serialize", +// "SerializeMetadata", +// "IBridgePermissions", +// "ICrossVM", +// "ICrossVMAsset", +// "CrossVMNFT", +// "CrossVMToken", +// "FlowEVMBridgeConfig", +// "FlowEVMBridgeUtils", +// "FlowEVMBridgeResolver", +// "FlowEVMBridgeHandlers", +// "FlowEVMBridgeNFTEscrow", +// "FlowEVMBridgeTokenEscrow", +// "FlowEVMBridgeTemplates", +// "IEVMBridgeNFTMinter", +// "IEVMBridgeTokenMinter", +// "IFlowEVMNFTBridge", +// "IFlowEVMTokenBridge", +// "FlowEVMBridge", +// } + +// // To run, execute the following command: +// // go run main.go $NETWORK +// func main() { +// network := getSpecifiedNetwork() + +// dir, err := os.Getwd() +// checkNoErr(err) + +// ctx := context.Background() +// o := Overflow( +// WithNetwork(network), +// WithTransactionFolderName("cadence/transactions"), +// WithScriptFolderName("cadence/scripts"), +// WithGlobalPrintOptions(WithTransactionUrl()), +// ) + +// // Check if the script is a dry run +// if checkDryRun() { +// log.Printf("Dry run detected...running setup script in dry run mode") +// // Run the dry run transaction +// serviceDryRunResult := o.Tx("bridge/admin/dry_run", WithSigner("service-account")) +// checkNoErr(serviceDryRunResult.Err) +// log.Printf("Service Account dry run run successful...") +// bridgeDryRunResult := o.Tx("bridge/admin/dry_run", WithSigner("flow-evm-bridge")) +// checkNoErr(bridgeDryRunResult.Err) +// log.Printf("Bridge Account dry run run successful...") +// log.Printf("Dry run complete...exiting script") +// return +// } + +// // Create a COA in the bridge account if one does not already exist +// bridgeCOAHex, err := o.Script("evm/get_evm_address_string", WithArg("flowAddress", o.Address("flow-evm-bridge"))).GetAsInterface() +// checkNoErr(err) +// if bridgeCOAHex == nil { +// // no COA found, create a COA in the bridge account +// coaCreationTxn := o.Tx("evm/create_account", WithSigner("flow-evm-bridge"), WithArg("amount", 1.0)) +// checkNoErr(coaCreationTxn.Err) +// bridgeCOAHex, err = o.Script("evm/get_evm_address_string", WithArg("flowAddress", o.Address("flow-evm-bridge"))).GetAsInterface() +// checkNoErr(err) +// } +// log.Printf("Bridge COA has EVM address: %s", bridgeCOAHex) + +// /* --- EVM Configuration --- */ + +// gasLimit := 15000000 +// deploymentValue := 0.0 + +// /// Deploy factory /// +// // +// // Get the Cadence args json for the factory deployment args +// factoryArgsPath := filepath.Join(dir, "cadence/args/deploy-factory-args.json") +// // Retrieve the bytecode from the JSON args +// // Future implementations should use flowkit to handle this after fixing dependency issues +// factoryBytecode := getBytecodeFromArgsJSON(factoryArgsPath) +// factoryDeployment := o.Tx("evm/deploy", +// WithSigner("flow-evm-bridge"), +// WithArg("bytecode", factoryBytecode), +// WithArg("gasLimit", gasLimit), +// WithArg("value", deploymentValue), +// ) +// checkNoErr(factoryDeployment.Err) +// factoryAddr := getContractAddressFromEVMEvent(factoryDeployment) + +// log.Printf("Factory deployed to address: %s", factoryAddr) + +// /// Deploy registry /// +// // +// // Get the Cadence args json for the factory deployment args +// registryArgsPath := filepath.Join(dir, "cadence/args/deploy-deployment-registry-args.json") +// // Retrieve the bytecode from the JSON args +// // Future implementations should use flowkit to handle this after fixing dependency issues +// registryBytecode := getBytecodeFromArgsJSON(registryArgsPath) +// registryDeployment := o.Tx("evm/deploy", +// WithSigner("flow-evm-bridge"), +// WithArg("bytecode", registryBytecode), +// WithArg("gasLimit", gasLimit), +// WithArg("value", deploymentValue), +// ) +// checkNoErr(registryDeployment.Err) +// registryAddr := getContractAddressFromEVMEvent(registryDeployment) + +// log.Printf("Registry deployed to address: %s", registryAddr) + +// /// Deploy ERC20 deployer /// +// // +// erc20DeployerArgsPath := filepath.Join(dir, "cadence/args/deploy-erc20-deployer-args.json") +// erc20DeployerBytecode := getBytecodeFromArgsJSON(erc20DeployerArgsPath) +// erc20DeployerDeployment := o.Tx("evm/deploy", +// WithSigner("flow-evm-bridge"), +// WithArg("bytecode", erc20DeployerBytecode), +// WithArg("gasLimit", gasLimit), +// WithArg("value", deploymentValue), +// ) +// checkNoErr(erc20DeployerDeployment.Err) +// erc20DeployerAddr := getContractAddressFromEVMEvent(erc20DeployerDeployment) + +// log.Printf("ERC20 Deployer deployed to address: %s", erc20DeployerAddr) + +// /// Deploy ERC721 deployer /// +// // +// erc721DeployerArgsPath := filepath.Join(dir, "cadence/args/deploy-erc721-deployer-args.json") +// erc721DeployerBytecode := getBytecodeFromArgsJSON(erc721DeployerArgsPath) +// erc721DeployerDeployment := o.Tx("evm/deploy", +// WithSigner("flow-evm-bridge"), +// WithArg("bytecode", erc721DeployerBytecode), +// WithArg("gasLimit", gasLimit), +// WithArg("value", deploymentValue), +// ) +// checkNoErr(erc721DeployerDeployment.Err) +// erc721DeployerAddr := getContractAddressFromEVMEvent(erc721DeployerDeployment) + +// log.Printf("ERC721 Deployer deployed to address: %s", erc721DeployerAddr) + +// /* --- Cadence Configuration --- */ + +// log.Printf("Deploying Cadence contracts...") +// // Iterate over contracts in the contracts map +// for _, name := range contracts { + +// log.Printf("Deploying contract: %s...", name) + +// contract, err := o.State.Config().Contracts.ByName(name) +// checkNoErr(err) +// contractPath := filepath.Join(dir, contract.Location) +// contractCode, err := os.ReadFile(contractPath) +// checkNoErr(err) + +// // If the contract is already deployed as-is, skip deployment +// a, err := o.GetAccount(ctx, "flow-evm-bridge") +// checkNoErr(err) +// log.Printf("Checking if contract %s is already deployed...", name) +// if a.Contracts[name] != nil { +// log.Printf("Contract %s already deployed, skipping...", name) +// continue +// } +// log.Printf("Contract %s not found on %s, deploying...", name, network) + +// var args []cadence.Value +// if name == "FlowEVMBridgeUtils" { +// args = []cadence.Value{cadence.String(factoryAddr)} +// } else { +// args = []cadence.Value{} +// } + +// err = o.AddContract(ctx, "flow-evm-bridge", contractCode, args, contractPath, true) +// checkNoErr(err) +// } +// log.Printf("Cadence contracts deployed...Pausing bridge for setup...") + +// // If emulator, deploy USDCFlow contract +// if network == "emulator" { +// log.Printf("Emulator detected...deploying USDCFlow contract...") + +// usdcContract, err := o.State.Config().Contracts.ByName("USDCFlow") +// checkNoErr(err) + +// usdcPath := filepath.Join(dir, usdcContract.Location) +// usdcCode, err := os.ReadFile(usdcPath) +// checkNoErr(err) + +// err = o.AddContract(ctx, "flow-evm-bridge", usdcCode, []cadence.Value{}, usdcPath, true) +// checkNoErr(err) + +// log.Printf("USDCFlow contract deployed...") +// } + +// // Pause the bridge for setup +// var pauseResult = o.Tx("bridge/admin/pause/update_bridge_pause_status", +// WithSigner("flow-evm-bridge"), +// WithArg("pause", true), +// ) +// checkNoErr(pauseResult.Err) + +// log.Printf("Bridge deployed and paused...") + +// /* --- USDCFlow TokenHandler Configuration --- */ + +// // Add USDCFlow TokenHandler +// // usdcFlowAddr := o.Address("USDCFlow") +// // usdcFlowVaultIdentifier := buildUSDCFlowVaultIdentifier(usdcFlowAddr) +// // usdcFlowMinterIdentifier := buildUSDCFlowMinterIdentifier(usdcFlowAddr) + +// // log.Printf("Bridge pause confirmed...configuring USDCFlow TokenHandler with vault=" + usdcFlowVaultIdentifier + " and minter=" + usdcFlowMinterIdentifier) + +// // // execute create_cadence_native_token_handler transaction +// // createTokenHandlerResult := o.Tx("bridge/admin/token-handler/create_cadence_native_token_handler", +// // WithSigner("flow-evm-bridge"), +// // WithArg("vaultIdentifier", usdcFlowVaultIdentifier), +// // WithArg("minterIdentifier", usdcFlowMinterIdentifier), +// // ) +// // checkNoErr(createTokenHandlerResult.Err) + +// // log.Printf("USDCFlow TokenHandler configured...") + +// /* --- Finish EVM Contract Setup --- */ + +// log.Printf("Integrating EVM-side bridge contracts...") + +// // Set the factory as registrar in the registry +// setRegistrarResult := o.Tx("bridge/admin/evm/set_registrar", +// WithSigner("flow-evm-bridge"), +// WithArg("registryEVMAddressHex", registryAddr), +// ) +// checkNoErr(setRegistrarResult.Err) +// // Add the registry to the factory +// setRegistryResult := o.Tx("bridge/admin/evm/set_deployment_registry", +// WithSigner("flow-evm-bridge"), +// WithArg("registryEVMAddressHex", registryAddr), +// ) +// checkNoErr(setRegistryResult.Err) + +// // Set the factory as delegated deployer in the ERC20 deployer +// setDelegatedDeployerResult := o.Tx("bridge/admin/evm/set_delegated_deployer", +// WithSigner("flow-evm-bridge"), +// WithArg("deployerEVMAddressHex", erc20DeployerAddr), +// ) +// checkNoErr(setDelegatedDeployerResult.Err) + +// // Set the factory as delegated deployer in the ERC721 deployer +// setDelegatedDeployerResult = o.Tx("bridge/admin/evm/set_delegated_deployer", +// WithSigner("flow-evm-bridge"), +// WithArg("deployerEVMAddressHex", erc721DeployerAddr), +// ) +// checkNoErr(setDelegatedDeployerResult.Err) + +// // Add the ERC20 Deployer as a deployer in the factory +// addDeployerResult := o.Tx("bridge/admin/evm/add_deployer", +// WithSigner("flow-evm-bridge"), +// WithArg("deployerTag", "ERC20"), +// WithArg("deployerEVMAddressHex", erc20DeployerAddr), +// ) +// checkNoErr(addDeployerResult.Err) + +// // Add the ERC721 Deployer as a deployer in the factory +// addDeployerResult = o.Tx("bridge/admin/evm/add_deployer", +// WithSigner("flow-evm-bridge"), +// WithArg("deployerTag", "ERC721"), +// WithArg("deployerEVMAddressHex", erc721DeployerAddr), +// ) +// checkNoErr(addDeployerResult.Err) + +// log.Printf("Cross-VM bridge contract integration complete...integrating with EVM contract...") + +// /* --- EVM Contract Integration --- */ + +// // Deploy FlowEVMBridgeAccessor, providing EVM contract host (network service account) as argument +// accessorContract, err := o.State.Config().Contracts.ByName("FlowEVMBridgeAccessor") +// checkNoErr(err) +// // accessorPath := filepath.Join(projectRoot, accessorContract.Location) +// accessorPath := filepath.Join(dir, accessorContract.Location) +// accessorCode, err := os.ReadFile(accessorPath) +// checkNoErr(err) +// evmConfigAddr, err := o.State.Config().Contracts.ByName("EVM") +// checkNoErr(err) +// evmAddr := evmConfigAddr.Aliases.ByNetwork(o.GetNetwork()).Address +// log.Printf("EVM contract address: %s", evmAddr) +// err = o.AddContract(ctx, "flow-evm-bridge", accessorCode, []cadence.Value{cadence.NewAddress(evmAddr)}, accessorPath, false) +// checkNoErr(err) + +// // Integrate the EVM contract with the BridgeAccessor +// integrateResult := o.Tx("bridge/admin/evm-integration/claim_accessor_capability_and_save_router", +// WithSigner("service-account"), +// WithArg("name", "FlowEVMBridgeAccessor"), +// WithArg("provider", o.Address("FlowEVMBridge")), +// ) +// checkNoErr(integrateResult.Err) + +// log.Printf("EVM integration complete...setting fees...") + +// /* --- Set Bridge Fees --- */ + +// onboardFeeResult := o.Tx("bridge/admin/fee/update_onboard_fee", +// WithSigner("flow-evm-bridge"), +// WithArg("newFee", 1.0), +// ) +// checkNoErr(onboardFeeResult.Err) +// baseFeeResult := o.Tx("bridge/admin/fee/update_base_fee", +// WithSigner("flow-evm-bridge"), +// WithArg("newFee", 0.001), +// ) +// checkNoErr(baseFeeResult.Err) + +// /* --- COMPLETE --- */ + +// log.Printf("Bridge setup complete...Adding bridged Token & NFT templates") + +// // TODO: Try to pull args JSON from local file once flowkit ParseJSON is fixed +// tokenChunkPath := filepath.Join( +// dir, +// "cadence/args/bridged-token-code-chunks-args-"+network+".json", +// ) +// nftChunkPath := filepath.Join(dir, "cadence/args/bridged-nft-code-chunks-args-"+network+".json") +// tokenChunks := getCodeChunksFromArgsJSON(tokenChunkPath) +// nftChunks := getCodeChunksFromArgsJSON(nftChunkPath) +// tokenChunkUpsert := o.Tx("bridge/admin/templates/upsert_contract_code_chunks", +// WithSigner("flow-evm-bridge"), +// WithArg("forTemplate", "bridgedToken"), +// WithArg("newChunks", tokenChunks), +// ) +// checkNoErr(tokenChunkUpsert.Err) +// nftChunkUpsert := o.Tx("bridge/admin/templates/upsert_contract_code_chunks", +// WithSigner("flow-evm-bridge"), +// WithArg("forTemplate", "bridgedNFT"), +// WithArg("newChunks", nftChunks), +// ) +// checkNoErr(nftChunkUpsert.Err) + +// log.Printf("Templates have been added...Unpausing bridge...") + +// // Unpause the bridge +// // unpauseResult := o.Tx("bridge/admin/pause/update_bridge_pause_status", +// // WithSigner("flow-evm-bridge"), +// // WithArg("pause", false), +// // ) +// // checkNoErr(unpauseResult.Err) + +// // log.Printf("SETUP COMPLETE! Bridge is now unpaused and ready for use.") +// log.Printf("SETUP COMPLETE! Bridge is still paused - be sure to unpause before use.") +// } + +// func checkDryRun() bool { +// if len(os.Args) < 3 { +// return false +// } +// return os.Args[2] == "--dry-run" +// } + +// // Parses the network argument from the command line +// // e.g. go run main.go $NETWORK +// func getSpecifiedNetwork() string { +// if len(os.Args) < 2 { +// log.Fatal("Please provide a network as an argument: ", networks) +// } +// network := os.Args[1] + +// if !slices.Contains(networks, network) { +// log.Fatal("Please provide a valid network as an argument: ", networks) +// } +// return network +// } + +// // Extracts the deployed contract address from the TransactionExecuted event +// func getContractAddressFromEVMEvent(res *OverflowResult) string { +// evts := res.GetEventsWithName("TransactionExecuted") +// contractAddr := evts[0].Fields["contractAddress"] +// if contractAddr == nil { +// log.Fatal("Contract address not found in event") +// } +// return strings.ToLower(strings.Split(contractAddr.(string), "x")[1]) +// } + +// // Reads the JSON file at the specified path and returns the compiled solidity bytecode where the +// // bytecode is the first element in the JSON array as a Cadence JSON string +// func getBytecodeFromArgsJSON(path string) string { +// argsData, err := os.ReadFile(path) +// checkNoErr(err) + +// var args []map[string]string + +// err = json.Unmarshal(argsData, &args) +// checkNoErr(err) + +// return args[0]["value"] +// } + +// type Element struct { +// Type string `json:"type"` +// Value interface{} `json:"value"` +// } + +// // Reads the JSON file at the specified path and returns the code chunks where the code chunks are +// // the second element in the JSON array as Cadence JSON string array +// func getCodeChunksFromArgsJSON(path string) []string { +// file, err := os.Open(path) +// if err != nil { +// log.Fatalf("Failed opening file: %s", err) +// } +// defer file.Close() + +// byteValue, _ := ioutil.ReadAll(file) + +// var elements []Element +// json.Unmarshal(byteValue, &elements) + +// secondElement := elements[1] + +// // Check if the second element is of type "Array" +// if secondElement.Type != "Array" { +// log.Fatalf("Second element is not of type Array") +// } + +// // Assert that the value is a slice of interfaces +// values, ok := secondElement.Value.([]interface{}) +// if !ok { +// log.Fatalf("Failed to assert value to []interface{}") +// } + +// var strArr []string +// for _, v := range values { +// // Assert that the value is a map +// valueMap, ok := v.(map[string]interface{}) +// if !ok { +// log.Fatalf("Failed to assert value to map[string]interface{}") +// } + +// // Get the "value" from the map and assert it to string +// str, ok := valueMap["value"].(string) +// if !ok { +// log.Fatalf("Failed to assert value to string") +// } + +// strArr = append(strArr, str) +// } + +// return strArr +// } + +// func buildUSDCFlowVaultIdentifier(addrString string) string { +// return "A." + strings.Split(addrString, "x")[1] + ".USDCFlow.Vault" +// } + +// func buildUSDCFlowMinterIdentifier(addrString string) string { +// return "A." + strings.Split(addrString, "x")[1] + ".USDCFlow.Minter" +// } + +// func checkNoErr(err error) { +// if err != nil { +// log.Fatal(err) +// } +// }