feat: transfer native#56
Merged
Merged
Conversation
2374137 to
82f1879
Compare
Contributor
There was a problem hiding this comment.
Pull request overview
Adds an EVM changeset for transferring native funds from the deployer key to a recipient address, with operation/sequence plumbing and simulated-environment tests.
Changes:
- Introduces
TransferNativechangeset with precondition validation and an operation-backed apply path. - Adds native transfer operation/sequence definitions.
- Adds tests for validation, happy path transfer, and insufficient funds behavior.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 10 comments.
| File | Description |
|---|---|
evm/changesets/transfer_native.go |
Adds the native transfer changeset, operation, sequence, and EVM transaction construction. |
evm/changesets/transfer_native_test.go |
Adds simulated EVM tests for preconditions and transfer execution paths. |
Comments suppressed due to low confidence (3)
evm/changesets/transfer_native_test.go:126
- This subtest also runs in parallel against the same simulated chain and shared outer
errvariable as the happy-path subtest. Besides the data race onerr, both cases can observe or mutate the same deployer balance concurrently, making the test flaky undergo test -raceor parallel scheduling.
t.Run("insufficient funds", func(t *testing.T) {
t.Parallel()
evm/changesets/transfer_native_test.go:90
- The test name still refers to
TransferFundswhile the changeset under test isTransferNative; this makes test output/searching inconsistent with the exported type name.
func Test_TransferFundsChangeset(t *testing.T) {
evm/changesets/transfer_native.go:50
- This inline comment is misleading for the same reason:
EstimateGasdoes not prove the transfer will succeed with the selected fees or available balance. Calling it a full success validation can hide the fact that the real balance check happens later inApply.
// Validate the transfer will succeed with simulation
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| if !valid { | ||
| return fmt.Errorf("address string %s cannot be converted to ETH hex address", config.Address) | ||
| } | ||
|
|
Comment on lines
+146
to
+161
| tipCap, err := chain.Client.SuggestGasTipCap(b.GetContext()) | ||
| if err != nil { | ||
| return TransferNativeOutput{}, fmt.Errorf("could not suggest gas tip cap: %w", err) | ||
| } | ||
|
|
||
| latestBlock, err := chain.Client.HeaderByNumber(b.GetContext(), nil) | ||
| if err != nil { | ||
| return TransferNativeOutput{}, fmt.Errorf("could not get latest block: %w", err) | ||
| } | ||
| baseFee := latestBlock.BaseFee | ||
|
|
||
| feeCap := new(big.Int).Add( | ||
| new(big.Int).Mul(baseFee, big.NewInt(2)), | ||
| tipCap, | ||
| ) | ||
|
|
Comment on lines
+141
to
+143
| nonce, err := chain.Client.NonceAt(b.GetContext(), chain.DeployerKey.From, nil) | ||
| if err != nil { | ||
| return TransferNativeOutput{}, fmt.Errorf("could not get latest nonce for deployer key: %w", err) |
Comment on lines
+100
to
+101
| t.Run("happy path", func(t *testing.T) { | ||
| t.Parallel() |
| } | ||
|
|
||
| if config.Amount.Cmp(big.NewInt(0)) < 1 { | ||
| return fmt.Errorf("amount must be positive value: %d", config.Amount) |
| "github.com/smartcontractkit/chainlink-evm/pkg/utils" | ||
| ) | ||
|
|
||
| func Test_TransferFunds_VerifyPreconditions(t *testing.T) { |
|
|
||
| // TransferNativeInput holds the parameters for a native token transfer. | ||
| type TransferNativeInput struct { | ||
| ChainSel uint64 `json:"chainSel" yaml:"chainSel"` |
Comment on lines
+117
to
+119
| ChainSel uint64 | ||
| Address common.Address | ||
| Amount *big.Int |
|
|
||
| e.Logger.Infow("Starting transfer of native funds", "chainSelector", config.ChainSel, "fromAddress", chain.DeployerKey.From, "toAddress", config.Address, "amount", config.Amount) | ||
|
|
||
| _, err := operations.ExecuteSequence( |
| // TransferNative is a changeset that transfers native funds from the deployer key to another address. | ||
| type TransferNative struct{} | ||
|
|
||
| // VerifyPreconditions validates the input and simulates the transfer to ensure it will succeed. |
ecPablo
approved these changes
May 15, 2026
ecPablo
pushed a commit
that referenced
this pull request
May 18, 2026
🤖 I have created a release *beep* *boop* --- ## [0.4.0](v0.3.0...v0.4.0) (2026-05-18) ### Features * add changeset and operation to delete CRE workflow ([#54](#54)) ([f0e341a](f0e341a)) * add support for multiple api key to deploy workflow ([#55](#55)) ([a68f156](a68f156)) * transfer native ([#56](#56)) ([4368e49](4368e49)) ### Bug Fixes * use cache dir for sol programs loading ([#52](#52)) ([b04f4d9](b04f4d9)) --- This PR was generated with [Release Please](https://github.com/googleapis/release-please). See [documentation](https://github.com/googleapis/release-please#release-please). Co-authored-by: app-token-issuer-ops-platform[bot] <275822481+app-token-issuer-ops-platform[bot]@users.noreply.github.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Ports deployment/common/changeset/transfer_native.go from the chainlink repo into evm/changesets/