Skip to content

Commit

Permalink
2.17.0 hedera cherrypick (#14761)
Browse files Browse the repository at this point in the history
* Enabling dynamic gas estimation for Hedera (#14601)

* turned on hedera gas estimation

* added hedera test overrides

* enable dynamic gas Limit for Hedera

* updated chainlink image

(cherry picked from commit 40e9af8)

* Broadcast transactions only to a single healthy RPC instead of all  (#14635)

* Broadcast transactions only to a single healthy RPC instead of all healthy RPCs to avoid redundant relay fees on Hedera

* fix tx test

(cherry picked from commit ee1d6e3)

* Set chainType in chain client (#14719)

* Set chain client chainType

* Added changeset

(cherry picked from commit de9ce67)

* solana: add compute unit limit functionality (#14576)

* solana: add compute unit limit functionality

* fix test: solana node CLI

* fix: e2e test artifact upload to container

* retry build with fresh commit

* changeset

* bump solana to merged commit

(cherry picked from commit 0e35bc7)

---------

Co-authored-by: Dmytro Haidashenko <34754799+dhaidashenko@users.noreply.github.com>
Co-authored-by: amit-momin <108959691+amit-momin@users.noreply.github.com>
Co-authored-by: Aaron Lu <50029043+aalu1418@users.noreply.github.com>
  • Loading branch information
4 people authored Oct 15, 2024
1 parent 5ebb632 commit a41ba42
Show file tree
Hide file tree
Showing 30 changed files with 186 additions and 39 deletions.
5 changes: 5 additions & 0 deletions .changeset/flat-spiders-sing.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"chainlink": patch
---

Set chainType in chain client #internal
5 changes: 5 additions & 0 deletions .changeset/fresh-falcons-cheer.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"chainlink": minor
---

#added solana: compute unit limit configuration and transaction instruction
5 changes: 5 additions & 0 deletions .changeset/three-otters-drum.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"chainlink": patch
---

Hedera chain type: broadcast transactions only to a single healthy RPC instead of all healthy RPCs to avoid redundant relay fees. #changed
8 changes: 8 additions & 0 deletions .github/workflows/integration-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -661,11 +661,19 @@ jobs:
with:
repository: smartcontractkit/chainlink-solana
ref: ${{ needs.get_solana_sha.outputs.sha }}
- name: Download Artifacts
if: (needs.changes.outputs.core_changes == 'true' || github.event_name == 'workflow_dispatch') && needs.solana-test-image-exists.outputs.exists == 'false'
uses: actions/download-artifact@65a9edc5881444af0b9093a5e628f2fe47ea3b2e # v4.1.7
with:
name: artifacts
path: ${{ env.CONTRACT_ARTIFACTS_PATH }}
- name: Build Test Image
if: (needs.changes.outputs.core_changes == 'true' || github.event_name == 'workflow_dispatch') && needs.solana-test-image-exists.outputs.exists == 'false'
uses: smartcontractkit/.github/actions/ctf-build-test-image@a5e4f4c8fbb8e15ab2ad131552eca6ac83c4f4b3 # ctf-build-test-image@0.1.0
with:
repository: chainlink-solana-tests
tag: ${{ needs.get_solana_sha.outputs.sha }}
suites: smoke
QA_AWS_ROLE_TO_ASSUME: ${{ secrets.QA_AWS_ROLE_TO_ASSUME }}
QA_AWS_REGION: ${{ secrets.QA_AWS_REGION }}
QA_AWS_ACCOUNT_NUMBER: ${{ secrets.QA_AWS_ACCOUNT_NUMBER }}
Expand Down
16 changes: 16 additions & 0 deletions core/chains/evm/client/chain_client.go
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,7 @@ func NewChainClient(
return &chainClient{
multiNode: multiNode,
logger: logger.Sugared(lggr),
chainType: chainType,
clientErrors: clientErrors,
}
}
Expand All @@ -174,6 +175,14 @@ func (c *chainClient) BatchCallContext(ctx context.Context, b []rpc.BatchElem) e

// Similar to BatchCallContext, ensure the provided BatchElem slice is passed through
func (c *chainClient) BatchCallContextAll(ctx context.Context, b []rpc.BatchElem) error {
if c.chainType == chaintype.ChainHedera {
activeRPC, err := c.multiNode.SelectNodeRPC()
if err != nil {
return err
}

return activeRPC.BatchCallContext(ctx, b)
}
return c.multiNode.BatchCallContextAll(ctx, b)
}

Expand Down Expand Up @@ -291,6 +300,13 @@ func (c *chainClient) PendingNonceAt(ctx context.Context, account common.Address
}

func (c *chainClient) SendTransaction(ctx context.Context, tx *types.Transaction) error {
if c.chainType == chaintype.ChainHedera {
activeRPC, err := c.multiNode.SelectNodeRPC()
if err != nil {
return err
}
return activeRPC.SendTransaction(ctx, tx)
}
return c.multiNode.SendTransaction(ctx, tx)
}

Expand Down
5 changes: 3 additions & 2 deletions core/chains/evm/client/chain_client_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -874,8 +874,9 @@ func TestEthClient_ErroringClient(t *testing.T) {
err = erroringClient.SendTransaction(ctx, nil)
require.Equal(t, err, commonclient.ErroringNodeError)

code, err := erroringClient.SendTransactionReturnCode(ctx, nil, common.Address{})
require.Equal(t, code, commonclient.Unknown)
tx := testutils.NewLegacyTransaction(uint64(42), testutils.NewAddress(), big.NewInt(142), 242, big.NewInt(342), []byte{1, 2, 3})
code, err := erroringClient.SendTransactionReturnCode(ctx, tx, common.Address{})
require.Equal(t, code, commonclient.Retryable)
require.Equal(t, err, commonclient.ErroringNodeError)

_, err = erroringClient.SequenceAt(ctx, common.Address{}, nil)
Expand Down
6 changes: 5 additions & 1 deletion core/chains/evm/client/errors.go
Original file line number Diff line number Diff line change
Expand Up @@ -390,7 +390,11 @@ func (s *SendError) IsL2Full(configErrors *ClientErrors) bool {

// IsServiceUnavailable indicates if the error was caused by a service being unavailable
func (s *SendError) IsServiceUnavailable(configErrors *ClientErrors) bool {
return s.is(ServiceUnavailable, configErrors)
if s == nil || s.err == nil {
return false
}

return s.is(ServiceUnavailable, configErrors) || pkgerrors.Is(s.err, commonclient.ErroringNodeError)
}

// IsTerminallyStuck indicates if a transaction was stuck without any chance of inclusion
Expand Down
7 changes: 7 additions & 0 deletions core/chains/evm/client/errors_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (
pkgerrors "github.com/pkg/errors"
"github.com/stretchr/testify/assert"

commonclient "github.com/smartcontractkit/chainlink/v2/common/client"
evmclient "github.com/smartcontractkit/chainlink/v2/core/chains/evm/client"
)

Expand Down Expand Up @@ -248,6 +249,12 @@ func Test_Eth_Errors(t *testing.T) {
err = newSendErrorWrapped(test.message)
assert.Equal(t, err.IsServiceUnavailable(clientErrors), test.expect)
}
{
err = evmclient.NewSendError(commonclient.ErroringNodeError)
assert.True(t, err.IsServiceUnavailable(clientErrors))
err = evmclient.NewSendError(fmt.Errorf("failed to send transaction: %w", commonclient.ErroringNodeError))
assert.True(t, err.IsServiceUnavailable(clientErrors))
}
})

t.Run("IsTxFeeExceedsCap", func(t *testing.T) {
Expand Down
2 changes: 2 additions & 0 deletions core/chains/evm/config/toml/defaults/Hedera_Mainnet.toml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ Mode = 'SuggestedPrice'
BumpThreshold = 0
BumpMin = '10 gwei'
BumpPercent = 20
# Dynamic gas estimation is a must Hedera, since Hedera consumes 80% of gaslimit by default, we will end up overpaying for gas
EstimateLimit = true

[Transactions]
# To hit throttling you'd need to maintain 15 m gas /sec over a prolonged period of time.
Expand Down
2 changes: 2 additions & 0 deletions core/chains/evm/config/toml/defaults/Hedera_Testnet.toml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ Mode = 'SuggestedPrice'
BumpThreshold = 0
BumpMin = '10 gwei'
BumpPercent = 20
# Dynamic gas estimation is a must Hedera, since Hedera consumes 80% of gaslimit by default, we will end up overpaying for gas
EstimateLimit = true

[Transactions]
# To hit throttling you'd need to maintain 15 m gas /sec over a prolonged period of time.
Expand Down
16 changes: 8 additions & 8 deletions core/cmd/solana_node_commands_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ import (

func solanaStartNewApplication(t *testing.T, cfgs ...*solcfg.TOMLConfig) *cltest.TestApplication {
for i := range cfgs {
cfgs[i].SetDefaults()
cfgs[i].Chain.SetDefaults()
}
return startNewApplicationV2(t, func(c *chainlink.Config, s *chainlink.Secrets) {
c.Solana = cfgs
Expand Down Expand Up @@ -72,17 +72,17 @@ func TestShell_IndexSolanaNodes(t *testing.T) {
rt := cmd.RendererTable{b}
require.NoError(t, nodes.RenderTable(rt))
renderLines := strings.Split(b.String(), "\n")
assert.Equal(t, 17, len(renderLines))
assert.Equal(t, 19, len(renderLines))
assert.Contains(t, renderLines[2], "Name")
assert.Contains(t, renderLines[2], n1.Name)
assert.Contains(t, renderLines[3], "Chain ID")
assert.Contains(t, renderLines[3], n1.ChainID)
assert.Contains(t, renderLines[4], "State")
assert.Contains(t, renderLines[4], n1.State)
assert.Contains(t, renderLines[9], "Name")
assert.Contains(t, renderLines[9], n2.Name)
assert.Contains(t, renderLines[10], "Chain ID")
assert.Contains(t, renderLines[10], n2.ChainID)
assert.Contains(t, renderLines[11], "State")
assert.Contains(t, renderLines[11], n2.State)
assert.Contains(t, renderLines[10], "Name")
assert.Contains(t, renderLines[10], n2.Name)
assert.Contains(t, renderLines[11], "Chain ID")
assert.Contains(t, renderLines[11], n2.ChainID)
assert.Contains(t, renderLines[12], "State")
assert.Contains(t, renderLines[12], n2.State)
}
4 changes: 4 additions & 0 deletions core/config/docs/chains-solana.toml
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,13 @@ ComputeUnitPriceDefault = 0 # Default
FeeBumpPeriod = '3s' # Default
# BlockHistoryPollPeriod is the rate to poll for blocks in the block history fee estimator
BlockHistoryPollPeriod = '5s' # Default
# ComputeUnitLimitDefault is the compute units limit applied to transactions unless overriden during the txm enqueue
ComputeUnitLimitDefault = 200_000 # Default

[[Solana.Nodes]]
# Name is a unique (per-chain) identifier for this node.
Name = 'primary' # Example
# URL is the HTTP(S) endpoint for this node.
URL = 'http://solana.web' # Example
# SendOnly is a multinode config that only sends transactions to a node and does not read state
SendOnly = false # Default
4 changes: 2 additions & 2 deletions core/scripts/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ require (
github.com/prometheus/client_golang v1.20.0
github.com/shopspring/decimal v1.4.0
github.com/smartcontractkit/chainlink-automation v1.0.4
github.com/smartcontractkit/chainlink-common v0.2.3-0.20240925085218-aded1b263ecc
github.com/smartcontractkit/chainlink-common v0.2.3-0.20240925150249-664dd5a59715
github.com/smartcontractkit/chainlink/v2 v2.0.0-00010101000000-000000000000
github.com/smartcontractkit/libocr v0.0.0-20240717100443-f6226e09bee7
github.com/spf13/cobra v1.8.1
Expand Down Expand Up @@ -275,7 +275,7 @@ require (
github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240911175228-daf2600bb7b7 // indirect
github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240916152957-433914114bd2 // indirect
github.com/smartcontractkit/chainlink-feeds v0.0.0-20240910155501-42f20443189f // indirect
github.com/smartcontractkit/chainlink-solana v1.1.1-0.20240911182932-3c609a6ac664 // indirect
github.com/smartcontractkit/chainlink-solana v1.1.1-0.20240927143737-7e527aa85bff // indirect
github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240911194142-506bc469d8ae // indirect
github.com/smartcontractkit/grpc-proxy v0.0.0-20240830132753-a7e17fec5ab7 // indirect
github.com/smartcontractkit/tdh2/go/ocr2/decryptionplugin v0.0.0-20230906073235-9e478e5e19f1 // indirect
Expand Down
8 changes: 4 additions & 4 deletions core/scripts/go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -1083,16 +1083,16 @@ github.com/smartcontractkit/chainlink-automation v1.0.4 h1:iyW181JjKHLNMnDleI8um
github.com/smartcontractkit/chainlink-automation v1.0.4/go.mod h1:u4NbPZKJ5XiayfKHD/v3z3iflQWqvtdhj13jVZXj/cM=
github.com/smartcontractkit/chainlink-ccip v0.0.0-20240924115754-8858b0423283 h1:f0vdqcOL9kJZwfmWE76roIyEuiZx/R82js0IfXNAvXg=
github.com/smartcontractkit/chainlink-ccip v0.0.0-20240924115754-8858b0423283/go.mod h1:KP82vFCqm+M1G1t6Vos5CewGUGYJkxxCEdxnta4uLlE=
github.com/smartcontractkit/chainlink-common v0.2.3-0.20240925085218-aded1b263ecc h1:ALbyaoRzUSXQ2NhGFKVOyJqO22IB5yQjhjKWbIZGbrI=
github.com/smartcontractkit/chainlink-common v0.2.3-0.20240925085218-aded1b263ecc/go.mod h1:F6WUS6N4mP5ScwpwyTyAJc9/vjR+GXbMCRUOVekQi1g=
github.com/smartcontractkit/chainlink-common v0.2.3-0.20240925150249-664dd5a59715 h1:6s5a5g62qvUiHSyknLLw9h8Y0FfdVEsNHc5o/Q/T9w4=
github.com/smartcontractkit/chainlink-common v0.2.3-0.20240925150249-664dd5a59715/go.mod h1:F6WUS6N4mP5ScwpwyTyAJc9/vjR+GXbMCRUOVekQi1g=
github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240911175228-daf2600bb7b7 h1:lTGIOQYLk1Ufn++X/AvZnt6VOcuhste5yp+C157No/Q=
github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240911175228-daf2600bb7b7/go.mod h1:BMYE1vC/pGmdFSsOJdPrAA0/4gZ0Xo0SxTMdGspBtRo=
github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240916152957-433914114bd2 h1:yRk4ektpx/UxwarqAfgxUXLrsYXlaNeP1NOwzHGrK2Q=
github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240916152957-433914114bd2/go.mod h1:rNhNSrrRMvkgAm5SA6bNTdh2340bTQQZdUVNtZ2o2bk=
github.com/smartcontractkit/chainlink-feeds v0.0.0-20240910155501-42f20443189f h1:p4p3jBT91EQyLuAMvHD+zNJsuAYI/QjJbzuGUJ7wIgg=
github.com/smartcontractkit/chainlink-feeds v0.0.0-20240910155501-42f20443189f/go.mod h1:FLlWBt2hwiMVgt9AcSo6wBJYIRd/nsc8ENbV1Wir1bw=
github.com/smartcontractkit/chainlink-solana v1.1.1-0.20240911182932-3c609a6ac664 h1:JPs35oSO07PK3Qv7Kyv0GJHVLacIE1IkrvefaPyBjKs=
github.com/smartcontractkit/chainlink-solana v1.1.1-0.20240911182932-3c609a6ac664/go.mod h1:iJ9DKYo0F64ue7IogAIELwU2DfrhEAh76eSmZOilT8A=
github.com/smartcontractkit/chainlink-solana v1.1.1-0.20240927143737-7e527aa85bff h1:piMugtrRlbVdcC6xZF37me686eS1YwpLQ0kN2v2b9YE=
github.com/smartcontractkit/chainlink-solana v1.1.1-0.20240927143737-7e527aa85bff/go.mod h1:5jD47oCERRQ4eGi0iNdk9ZV5HMEdolfQwHpUX1+Ix4s=
github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240911194142-506bc469d8ae h1:d+B8y2Nd/PrnPMNoaSPn3eDgUgxcVcIqAxGrvYu/gGw=
github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240911194142-506bc469d8ae/go.mod h1:ec/a20UZ7YRK4oxJcnTBFzp1+DBcJcwqEaerUMsktMs=
github.com/smartcontractkit/grpc-proxy v0.0.0-20240830132753-a7e17fec5ab7 h1:12ijqMM9tvYVEm+nR826WsrNi6zCKpwBhuApq127wHs=
Expand Down
9 changes: 7 additions & 2 deletions core/services/chainlink/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -709,11 +709,12 @@ func TestConfig_Marshal(t *testing.T) {
ComputeUnitPriceDefault: ptr[uint64](100),
FeeBumpPeriod: commoncfg.MustNewDuration(time.Minute),
BlockHistoryPollPeriod: commoncfg.MustNewDuration(time.Minute),
ComputeUnitLimitDefault: ptr[uint32](100_000),
},
Nodes: []*solcfg.Node{
{Name: ptr("primary"), URL: commoncfg.MustParseURL("http://solana.web")},
{Name: ptr("foo"), URL: commoncfg.MustParseURL("http://solana.foo")},
{Name: ptr("bar"), URL: commoncfg.MustParseURL("http://solana.bar")},
{Name: ptr("foo"), URL: commoncfg.MustParseURL("http://solana.foo"), SendOnly: true},
{Name: ptr("bar"), URL: commoncfg.MustParseURL("http://solana.bar"), SendOnly: true},
},
},
}
Expand Down Expand Up @@ -1213,18 +1214,22 @@ ComputeUnitPriceMin = 10
ComputeUnitPriceDefault = 100
FeeBumpPeriod = '1m0s'
BlockHistoryPollPeriod = '1m0s'
ComputeUnitLimitDefault = 100000
[[Solana.Nodes]]
Name = 'primary'
URL = 'http://solana.web'
SendOnly = false
[[Solana.Nodes]]
Name = 'foo'
URL = 'http://solana.foo'
SendOnly = true
[[Solana.Nodes]]
Name = 'bar'
URL = 'http://solana.bar'
SendOnly = true
`},
{"Starknet", Config{Starknet: full.Starknet}, `[[Starknet]]
ChainID = 'foobar'
Expand Down
4 changes: 4 additions & 0 deletions core/services/chainlink/testdata/config-full.toml
Original file line number Diff line number Diff line change
Expand Up @@ -498,18 +498,22 @@ ComputeUnitPriceMin = 10
ComputeUnitPriceDefault = 100
FeeBumpPeriod = '1m0s'
BlockHistoryPollPeriod = '1m0s'
ComputeUnitLimitDefault = 100000

[[Solana.Nodes]]
Name = 'primary'
URL = 'http://solana.web'
SendOnly = false

[[Solana.Nodes]]
Name = 'foo'
URL = 'http://solana.foo'
SendOnly = true

[[Solana.Nodes]]
Name = 'bar'
URL = 'http://solana.bar'
SendOnly = true

[[Starknet]]
ChainID = 'foobar'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -657,10 +657,12 @@ ComputeUnitPriceMin = 0
ComputeUnitPriceDefault = 0
FeeBumpPeriod = '3s'
BlockHistoryPollPeriod = '5s'
ComputeUnitLimitDefault = 200000

[[Solana.Nodes]]
Name = 'primary'
URL = 'http://mainnet.solana.com'
SendOnly = false

[[Solana]]
ChainID = 'testnet'
Expand All @@ -680,10 +682,12 @@ ComputeUnitPriceMin = 0
ComputeUnitPriceDefault = 0
FeeBumpPeriod = '3s'
BlockHistoryPollPeriod = '5s'
ComputeUnitLimitDefault = 200000

[[Solana.Nodes]]
Name = 'secondary'
URL = 'http://testnet.solana.com'
SendOnly = false

[[Starknet]]
ChainID = 'foobar'
Expand Down
2 changes: 2 additions & 0 deletions core/services/chainlink/testdata/config-multi-chain.toml
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@ MaxRetries = 12
[[Solana.Nodes]]
Name = 'primary'
URL = 'http://mainnet.solana.com'
SendOnly = false

[[Solana]]
ChainID = 'testnet'
Expand All @@ -101,6 +102,7 @@ OCR2CachePollPeriod = '1m0s'
[[Solana.Nodes]]
Name = 'secondary'
URL = 'http://testnet.solana.com'
SendOnly = false

[[Starknet]]
ChainID = 'foobar'
Expand Down
4 changes: 4 additions & 0 deletions core/web/resolver/testdata/config-full.toml
Original file line number Diff line number Diff line change
Expand Up @@ -497,18 +497,22 @@ ComputeUnitPriceMin = 0
ComputeUnitPriceDefault = 0
FeeBumpPeriod = '3s'
BlockHistoryPollPeriod = '5s'
ComputeUnitLimitDefault = 200000

[[Solana.Nodes]]
Name = 'primary'
URL = 'http://solana.web'
SendOnly = false

[[Solana.Nodes]]
Name = 'foo'
URL = 'http://solana.foo'
SendOnly = false

[[Solana.Nodes]]
Name = 'bar'
URL = 'http://solana.bar'
SendOnly = false

[[Starknet]]
ChainID = 'foobar'
Expand Down
4 changes: 4 additions & 0 deletions core/web/resolver/testdata/config-multi-chain-effective.toml
Original file line number Diff line number Diff line change
Expand Up @@ -657,10 +657,12 @@ ComputeUnitPriceMin = 0
ComputeUnitPriceDefault = 0
FeeBumpPeriod = '3s'
BlockHistoryPollPeriod = '5s'
ComputeUnitLimitDefault = 200000

[[Solana.Nodes]]
Name = 'primary'
URL = 'http://mainnet.solana.com'
SendOnly = false

[[Solana]]
ChainID = 'testnet'
Expand All @@ -680,10 +682,12 @@ ComputeUnitPriceMin = 0
ComputeUnitPriceDefault = 0
FeeBumpPeriod = '3s'
BlockHistoryPollPeriod = '5s'
ComputeUnitLimitDefault = 200000

[[Solana.Nodes]]
Name = 'secondary'
URL = 'http://testnet.solana.com'
SendOnly = false

[[Starknet]]
ChainID = 'foobar'
Expand Down
2 changes: 2 additions & 0 deletions core/web/resolver/testdata/config-multi-chain.toml
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,7 @@ MaxRetries = 12
[[Solana.Nodes]]
Name = 'primary'
URL = 'http://mainnet.solana.com'
SendOnly = false

[[Solana]]
ChainID = 'testnet'
Expand All @@ -109,6 +110,7 @@ OCR2CachePollPeriod = '1m0s'
[[Solana.Nodes]]
Name = 'secondary'
URL = 'http://testnet.solana.com'
SendOnly = false

[[Starknet]]
ChainID = 'foobar'
Expand Down
Loading

0 comments on commit a41ba42

Please sign in to comment.