mirror of
https://github.com/AthanorLabs/atomic-swap.git
synced 2026-01-08 21:58:07 -05:00
restore price feed (#494)
This commit is contained in:
@@ -169,11 +169,13 @@ func cliApp() *cli.App {
|
||||
Flags: []cli.Flag{
|
||||
&cli.StringFlag{
|
||||
Name: flagMinAmount,
|
||||
Aliases: []string{"min"},
|
||||
Usage: "Minimum amount to be swapped, in XMR",
|
||||
Required: true,
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Name: flagMaxAmount,
|
||||
Aliases: []string{"max"},
|
||||
Usage: "Maximum amount to be swapped, in XMR",
|
||||
Required: true,
|
||||
},
|
||||
@@ -184,15 +186,16 @@ func cliApp() *cli.App {
|
||||
},
|
||||
&cli.BoolFlag{
|
||||
Name: flagDetached,
|
||||
Usage: "Exit immediately instead of subscribing to notifications about the swap's status",
|
||||
Usage: "Exit immediately without subscribing to status notifications",
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Name: flagToken,
|
||||
Usage: "Use to pass the ethereum ERC20 token address to receive instead of ETH",
|
||||
Usage: "Ethereum ERC20 token address to receive instead of ETH",
|
||||
},
|
||||
&cli.BoolFlag{
|
||||
Name: flagUseRelayer,
|
||||
Usage: "Use the relayer even if the receiving account has enough ETH to claim",
|
||||
Name: flagUseRelayer,
|
||||
Usage: "Use the relayer even if the receiving account has enough ETH to claim",
|
||||
Hidden: true, // useful for testing, but no clear end-user use case for the flag
|
||||
},
|
||||
swapdPortFlag,
|
||||
},
|
||||
@@ -215,12 +218,13 @@ func cliApp() *cli.App {
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Name: flagProvidesAmount,
|
||||
Aliases: []string{"pa"},
|
||||
Usage: "Amount of coin to send in the swap",
|
||||
Required: true,
|
||||
},
|
||||
&cli.BoolFlag{
|
||||
Name: flagDetached,
|
||||
Usage: "Exit immediately instead of subscribing to notifications about the swap's status",
|
||||
Usage: "Exit immediately without subscribing to status notifications",
|
||||
},
|
||||
swapdPortFlag,
|
||||
},
|
||||
@@ -251,7 +255,7 @@ func cliApp() *cli.App {
|
||||
},
|
||||
{
|
||||
Name: "cancel",
|
||||
Usage: "Cancel a ongoing swap if possible. Depending on the swap stage, this may not be possible.",
|
||||
Usage: "Cancel ongoing swap, if possible at the current swap stage.",
|
||||
Action: runCancel,
|
||||
Flags: []cli.Flag{
|
||||
&cli.StringFlag{
|
||||
@@ -308,8 +312,8 @@ func cliApp() *cli.App {
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "suggested-exchange-rate",
|
||||
Aliases: []string{"price-feed"},
|
||||
Name: "price-feed",
|
||||
Aliases: []string{"suggested-exchange-rate"},
|
||||
Usage: "Returns the current mainnet exchange rate based on ETH/USD and XMR/USD price feeds.",
|
||||
Action: runSuggestedExchangeRate,
|
||||
Flags: []cli.Flag{swapdPortFlag},
|
||||
|
||||
@@ -28,8 +28,9 @@ const (
|
||||
|
||||
// Ethereum chain IDs
|
||||
const (
|
||||
MainnetChainID = 1
|
||||
SepoliaChainID = 11155111
|
||||
GanacheChainID = 1337
|
||||
HardhatChainID = 31337
|
||||
MainnetChainID = 1
|
||||
OpMainnetChainID = 10 // Optimism
|
||||
SepoliaChainID = 11155111
|
||||
GanacheChainID = 1337
|
||||
HardhatChainID = 31337
|
||||
)
|
||||
|
||||
@@ -21,17 +21,16 @@ import (
|
||||
)
|
||||
|
||||
const (
|
||||
// mainnetEndpoint is a mainnet ethereum endpoint, from
|
||||
// https://chainlist.org/chain/1, which stagenet users get pointed at for
|
||||
// price feeds, as Sepolia doesn't have an XMR feed. Mainnet users will use
|
||||
// the same ethereum endpoint that they use for other swap transactions.
|
||||
mainnetEndpoint = "https://eth-rpc.gateway.pokt.network"
|
||||
// optimismEndpoint is an RPC endpoint for optimism mainnet. Note that we
|
||||
// tried https://mainnet.optimism.io first, but it is severely rate limited
|
||||
// to around 2 requests/second.
|
||||
optimismEndpoint = "https://1rpc.io/op"
|
||||
|
||||
// https://data.chain.link/ethereum/mainnet/crypto-usd/eth-usd
|
||||
chainlinkETHToUSDProxy = "0x5f4ec3df9cbd43714fe2740f5e3616155c5b8419"
|
||||
// https://data.chain.link/optimism/mainnet/crypto-usd/eth-usd
|
||||
chainlinkETHToUSDProxy = "0x13e3ee699d1909e989722e753853ae30b17e08c5"
|
||||
|
||||
// https://data.chain.link/ethereum/mainnet/crypto-usd/xmr-usd
|
||||
chainlinkXMRToUSDProxy = "0xfa66458cce7dd15d8650015c4fce4d278271618f"
|
||||
// https://data.chain.link/optimism/mainnet/crypto-usd/xmr-usd
|
||||
chainlinkXMRToUSDProxy = "0x2a8d91686a048e98e6ccf1a89e82f40d14312672"
|
||||
)
|
||||
|
||||
var (
|
||||
@@ -47,7 +46,6 @@ type PriceFeed struct {
|
||||
}
|
||||
|
||||
// GetETHUSDPrice returns the current ETH/USD price from the Chainlink oracle.
|
||||
// It errors if the chain ID is not the Ethereum mainnet.
|
||||
func GetETHUSDPrice(ctx context.Context, ec *ethclient.Client) (*PriceFeed, error) {
|
||||
chainID, err := ec.ChainID(ctx)
|
||||
if err != nil {
|
||||
@@ -55,11 +53,10 @@ func GetETHUSDPrice(ctx context.Context, ec *ethclient.Client) (*PriceFeed, erro
|
||||
}
|
||||
|
||||
switch chainID.Uint64() {
|
||||
case common.MainnetChainID:
|
||||
case common.OpMainnetChainID:
|
||||
// No extra work to do
|
||||
case common.SepoliaChainID:
|
||||
// Push stagenet/sepolia users to a mainnet endpoint
|
||||
ec, err = ethclient.Dial(mainnetEndpoint)
|
||||
case common.MainnetChainID, common.SepoliaChainID:
|
||||
ec, err = ethclient.Dial(optimismEndpoint)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -78,25 +75,18 @@ func GetETHUSDPrice(ctx context.Context, ec *ethclient.Client) (*PriceFeed, erro
|
||||
}
|
||||
|
||||
// GetXMRUSDPrice returns the current XMR/USD price from the Chainlink oracle.
|
||||
// It errors if the chain ID is not the Ethereum mainnet.
|
||||
func GetXMRUSDPrice(ctx context.Context, ec *ethclient.Client) (*PriceFeed, error) {
|
||||
chainID, err := ec.ChainID(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Temporary hack to return a better error until the issue is resolved.
|
||||
switch chainID.Uint64() {
|
||||
case common.MainnetChainID, common.SepoliaChainID:
|
||||
return nil, errors.New("https://github.com/AthanorLabs/atomic-swap/issues/492")
|
||||
}
|
||||
|
||||
switch chainID.Uint64() {
|
||||
case common.MainnetChainID:
|
||||
case common.OpMainnetChainID:
|
||||
// No extra work to do
|
||||
case common.SepoliaChainID:
|
||||
case common.MainnetChainID, common.SepoliaChainID:
|
||||
// Push stagenet/sepolia users to a mainnet endpoint
|
||||
ec, err = ethclient.Dial(mainnetEndpoint)
|
||||
ec, err = ethclient.Dial(optimismEndpoint)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -7,6 +7,7 @@ import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
"github.com/ethereum/go-ethereum/ethclient"
|
||||
logging "github.com/ipfs/go-log/v2"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
@@ -15,18 +16,28 @@ import (
|
||||
)
|
||||
|
||||
func init() {
|
||||
logging.SetLogLevel("pricefeed", "debug")
|
||||
_ = logging.SetLogLevel("pricefeed", "debug")
|
||||
}
|
||||
|
||||
func TestGetETHUSDPrice_mainnet(t *testing.T) {
|
||||
ec := tests.NewEthMainnetClient(t)
|
||||
|
||||
feed, err := GetETHUSDPrice(context.Background(), ec)
|
||||
func newOptimismClient(t *testing.T) *ethclient.Client {
|
||||
ec, err := ethclient.Dial(optimismEndpoint)
|
||||
require.NoError(t, err)
|
||||
t.Logf("%s is $%s (updated: %s)", feed.Description, feed.Price, feed.UpdatedAt)
|
||||
assert.Equal(t, "ETH / USD", feed.Description)
|
||||
assert.False(t, feed.Price.Negative)
|
||||
assert.False(t, feed.Price.IsZero())
|
||||
t.Cleanup(func() {
|
||||
ec.Close()
|
||||
})
|
||||
|
||||
return ec
|
||||
}
|
||||
|
||||
func TestGetETHUSDPrice_nonDev(t *testing.T) {
|
||||
for _, ec := range []*ethclient.Client{tests.NewEthSepoliaClient(t), newOptimismClient(t)} {
|
||||
feed, err := GetETHUSDPrice(context.Background(), ec)
|
||||
require.NoError(t, err)
|
||||
t.Logf("%s is $%s (updated: %s)", feed.Description, feed.Price, feed.UpdatedAt)
|
||||
assert.Equal(t, "ETH / USD", feed.Description)
|
||||
assert.False(t, feed.Price.Negative)
|
||||
assert.False(t, feed.Price.IsZero())
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetETHUSDPrice_dev(t *testing.T) {
|
||||
@@ -37,16 +48,15 @@ func TestGetETHUSDPrice_dev(t *testing.T) {
|
||||
assert.Equal(t, "1234.12345678", feed.Price.String())
|
||||
}
|
||||
|
||||
func TestGetXMRUSDPrice_mainnet(t *testing.T) {
|
||||
t.Skip("Chainlink XMR price feed is down: https://github.com/AthanorLabs/atomic-swap/issues/492")
|
||||
ec := tests.NewEthMainnetClient(t)
|
||||
|
||||
feed, err := GetXMRUSDPrice(context.Background(), ec)
|
||||
require.NoError(t, err)
|
||||
t.Logf("%s is $%s (updated: %s)", feed.Description, feed.Price, feed.UpdatedAt)
|
||||
assert.Equal(t, "XMR / USD", feed.Description)
|
||||
assert.False(t, feed.Price.Negative)
|
||||
assert.False(t, feed.Price.IsZero())
|
||||
func TestGetXMRUSDPrice_nonDev(t *testing.T) {
|
||||
for _, ec := range []*ethclient.Client{tests.NewEthSepoliaClient(t), newOptimismClient(t)} {
|
||||
feed, err := GetXMRUSDPrice(context.Background(), ec)
|
||||
require.NoError(t, err)
|
||||
t.Logf("%s is $%s (updated: %s)", feed.Description, feed.Price, feed.UpdatedAt)
|
||||
assert.Equal(t, "XMR / USD", feed.Description)
|
||||
assert.False(t, feed.Price.Negative)
|
||||
assert.False(t, feed.Price.IsZero())
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetXMRUSDPrice_dev(t *testing.T) {
|
||||
|
||||
Reference in New Issue
Block a user