diff --git a/apps/hip-3-pusher/config/config.pyth.testnet.toml b/apps/hip-3-pusher/config/config.pyth.testnet.toml new file mode 100644 index 0000000000..26d192c5d3 --- /dev/null +++ b/apps/hip-3-pusher/config/config.pyth.testnet.toml @@ -0,0 +1,61 @@ +stale_price_threshold_seconds = 5 +prometheus_port = 9090 + +[hyperliquid] +hyperliquid_ws_urls = ["wss://api.hyperliquid-testnet.xyz/ws"] +market_name = "pyth" +asset_context_symbols = ["BTC", "pyth:BTC", "pyth:PYTH", "pyth:FOGO"] +use_testnet = true +oracle_pusher_key_path = "oracle-updater-subdeployer-private-key.txt" +publish_interval = 3.0 +publish_timeout = 5.0 +enable_publish = true + +[multisig] +enable_multisig = false + +[kms] +enable_kms = false + +[lazer] +lazer_urls = ["wss://pyth-lazer-0.dourolabs.app/v1/stream", "wss://pyth-lazer-1.dourolabs.app/v1/stream"] +lazer_api_key = "" +feed_ids = [1, 3, 8] # BTC, PYTH, USDT +exponents = [-8, -8, -8] + +[hermes] +hermes_urls = ["wss://hermes.pyth.network/ws"] +feed_ids = [ + "e62df6c8b4a85fe1a67db44dc12de5db330f7ac66b72dc658afedf0f4a415b43", # BTC + "0bbf28e9a841a1cc788f6a361b17ca072d0ea3098a1e5df1c3922d06719579ff", # PYTH + "2b89b9dc8fdf9f34709a5b106b472f0f39bb6ca9ce04b0fd7f2e971688e2e53b" # USDT +] +exponents = [-8, -8, -8] + +[seda] +url = "https://fast-api.testnet.seda.xyz/execute" +poll_interval = 2 +poll_failure_interval = 1 +poll_timeout = 3 + +[price.oracle] +BTC = [ + { source_type = "single", source = { source_name = "hl_oracle", source_id = "BTC" } }, + { source_type = "pair", base_source = { source_name = "lazer", source_id = 1, exponent = -8 }, quote_source = { source_name = "lazer", source_id = 8, exponent = -8 } }, + { source_type = "pair", base_source = { source_name = "hermes", source_id = "e62df6c8b4a85fe1a67db44dc12de5db330f7ac66b72dc658afedf0f4a415b43", exponent = -8 }, quote_source = { source_name = "hermes", source_id = "2b89b9dc8fdf9f34709a5b106b472f0f39bb6ca9ce04b0fd7f2e971688e2e53b", exponent = -8 } }, +] +PYTH = [ + { source_type = "pair", base_source = { source_name = "lazer", source_id = 3, exponent = -8 }, quote_source = { source_name = "lazer", source_id = 8, exponent = -8 } }, + { source_type = "pair", base_source = { source_name = "hermes", source_id = "0bbf28e9a841a1cc788f6a361b17ca072d0ea3098a1e5df1c3922d06719579ff", exponent = -8 }, quote_source = { source_name = "hermes", source_id = "2b89b9dc8fdf9f34709a5b106b472f0f39bb6ca9ce04b0fd7f2e971688e2e53b", exponent = -8 } }, +] +FOGO = [{ source_type = "constant", value = "0.0100" }] + +[price.mark] +BTC = [{ source_type = "oracle_mid_average", symbol = "pyth:BTC" }] +PYTH = [{ source_type = "oracle_mid_average", symbol = "pyth:PYTH" }] +FOGO = [{ source_type = "oracle_mid_average", symbol = "pyth:FOGO" }] + +[price.external] +BTC = [{ source_type = "single", source = { source_name = "hl_mark", source_id = "BTC" } }] +PYTH = [{ source_type = "constant", value = "0.10" },] +FOGO = [{ source_type = "constant", value = "0.0100" },] diff --git a/apps/hip-3-pusher/config/config.sample.toml b/apps/hip-3-pusher/config/config.sample.toml deleted file mode 100644 index f9b9f45bf4..0000000000 --- a/apps/hip-3-pusher/config/config.sample.toml +++ /dev/null @@ -1,43 +0,0 @@ -stale_price_threshold_seconds = 5 -prometheus_port = 9090 - -[hyperliquid] -hyperliquid_ws_urls = ["wss://api.hyperliquid-testnet.xyz/ws"] -market_name = "pyth" -asset_context_symbols = ["BTC"] -use_testnet = false -oracle_pusher_key_path = "/path/to/oracle_pusher_key.txt" -publish_interval = 3.0 -publish_timeout = 5.0 -enable_publish = false - -[multisig] -enable_multisig = false - -[kms] -enable_kms = false -aws_kms_key_id_path = "/path/to/aws_kms_key_id.txt" - -[lazer] -lazer_urls = ["wss://pyth-lazer-0.dourolabs.app/v1/stream", "wss://pyth-lazer-1.dourolabs.app/v1/stream"] -lazer_api_key = "lazer_api_key" -feed_ids = [1, 8] # BTC, USDT - -[hermes] -hermes_urls = ["wss://hermes.pyth.network/ws"] -feed_ids = [ - "e62df6c8b4a85fe1a67db44dc12de5db330f7ac66b72dc658afedf0f4a415b43", # BTC - "2b89b9dc8fdf9f34709a5b106b472f0f39bb6ca9ce04b0fd7f2e971688e2e53b" # USDT -] - -[price.oracle] -BTC = [ - { source_type = "single", source = { source_name = "hl_oracle", source_id = "BTC" } }, - { source_type = "pair", base_source = { source_name = "lazer", source_id = 1, exponent = -8 }, quote_source = { source_name = "lazer", source_id = 8, exponent = -8 } }, - { source_type = "pair", base_source = { source_name = "hermes", source_id = "e62df6c8b4a85fe1a67db44dc12de5db330f7ac66b72dc658afedf0f4a415b43", exponent = -8 }, quote_source = { source_name = "hermes", source_id = "2b89b9dc8fdf9f34709a5b106b472f0f39bb6ca9ce04b0fd7f2e971688e2e53b", exponent = -8 } }, -] - -[price.external] -BTC = [{ source_type = "single", source = { source_name = "hl_mark", source_id = "BTC" } }] -PYTH = [{ source_type = "constant", value = "0.10" }] -FOGO = [{ source_type = "constant", value = "0.01" }] diff --git a/apps/hip-3-pusher/src/scripts/create_key.py b/apps/hip-3-pusher/src/scripts/create_key.py new file mode 100644 index 0000000000..52d187b5d8 --- /dev/null +++ b/apps/hip-3-pusher/src/scripts/create_key.py @@ -0,0 +1,34 @@ +import argparse + +from eth_account import Account + + +def main(): + parser = argparse.ArgumentParser( + description="Create new key" + ) + output = parser.add_mutually_exclusive_group(required=True) + output.add_argument( + "--output-file", + metavar="PATH", + help="Write the private key (in hex) to a file", + ) + output.add_argument( + "--stdout", + action="store_true", + help="Print the private key to stdout", + ) + + args = parser.parse_args() + account = Account.create() + print("address:", account.address) + private_key_hex = account.key.hex() + if args.stdout: + print("private key:", private_key_hex) + else: + open(args.output_file, "w").write(private_key_hex) + print("wrote private key to file:", args.output_file) + + +if __name__ == "__main__": + main() diff --git a/apps/hip-3-pusher/src/scripts/get_user_limit.py b/apps/hip-3-pusher/src/scripts/get_user_limit.py new file mode 100644 index 0000000000..c99ae6270c --- /dev/null +++ b/apps/hip-3-pusher/src/scripts/get_user_limit.py @@ -0,0 +1,41 @@ +import argparse + +from hyperliquid.info import Info +from hyperliquid.utils import constants + + +def main(): + parser = argparse.ArgumentParser( + description="Check user rate limit" + ) + parser.add_argument( + "--address", + required=True, + help="Address", + ) + network = parser.add_mutually_exclusive_group(required=True) + network.add_argument( + "--testnet", + action="store_true", + help="Use testnet", + ) + network.add_argument( + "--mainnet", + action="store_true", + help="Use mainnet", + ) + + args = parser.parse_args() + + network = "testnet" if args.testnet else "mainnet" + base_url = constants.TESTNET_API_URL if args.testnet else constants.MAINNET_API_URL + print(f"Using {network} URL: {base_url}") + print("address:", args.address) + + info = Info(base_url=base_url, skip_ws=True) + print("calling userRateLimit...") + print(info.user_rate_limit(args.address)) + + +if __name__ == "__main__": + main() diff --git a/apps/hip-3-pusher/src/scripts/setoracle_subdeployer.py b/apps/hip-3-pusher/src/scripts/setoracle_subdeployer.py new file mode 100644 index 0000000000..abf5f9952a --- /dev/null +++ b/apps/hip-3-pusher/src/scripts/setoracle_subdeployer.py @@ -0,0 +1,101 @@ +import argparse +from pathlib import Path + +from eth_account import Account +from hyperliquid.exchange import Exchange +from hyperliquid.utils import constants +from hyperliquid.utils.signing import get_timestamp_ms, sign_l1_action + + +def main(): + parser = argparse.ArgumentParser( + description="Permission/depermission subdeployer account for setOracle for HIP-3 dex" + ) + parser.add_argument( + "--private-key-file", + required=True, + help="Path to private key file for deployer account", + ) + parser.add_argument( + "--dex", + required=True, + help="HIP-3 dex name (should be short string)" + ) + parser.add_argument( + "--subdeployer-address", + required=True, + help="Subdeployer address", + ) + enable_disable = parser.add_mutually_exclusive_group(required=True) + enable_disable.add_argument( + "--enable", + action="store_true", + help="Enable subdeployer for setOracle", + ) + enable_disable.add_argument( + "--disable", + action="store_true", + help="Disable subdeployer for setOracle", + ) + network = parser.add_mutually_exclusive_group(required=True) + network.add_argument( + "--testnet", + action="store_true", + help="Use testnet", + ) + network.add_argument( + "--mainnet", + action="store_true", + help="Use mainnet", + ) + parser.add_argument( + "--dry-run", + action="store_true", + help="Only show parameters without sending", + ) + + args = parser.parse_args() + + network = "testnet" if args.testnet else "mainnet" + base_url = constants.TESTNET_API_URL if args.testnet else constants.MAINNET_API_URL + print(f"Using {network} URL: {base_url}") + + deployer_account = Account.from_key(Path(args.private_key_file).read_text().strip()) + deployer_exchange = Exchange(wallet=deployer_account, base_url=base_url) + print("deployer address:", deployer_account.address) + subdeployer_address = args.subdeployer_address + print("dex:", args.dex) + print("subdeployer address:", subdeployer_address) + mode = "enable" if args.enable else "disable" + print("mode:", mode) + + if args.dry_run: + print(f"dry run: {network}: would {mode} setOracle for {subdeployer_address} in dex {args.dex}") + else: + timestamp = get_timestamp_ms() + sub_deployer = { + "variant": "setOracle", + "user": subdeployer_address.lower(), + "allowed": True if args.enable else False, + } + action = { + "type": "perpDeploy", + "setSubDeployers": { + "dex": args.dex, + "subDeployers": [sub_deployer] + } + } + signature = sign_l1_action( + deployer_exchange.wallet, + action, + deployer_exchange.vault_address, + timestamp, + deployer_exchange.expires_after, + deployer_exchange.base_url == constants.MAINNET_API_URL, + ) + print("calling perpDeploy.setSubdeployers...") + print(deployer_exchange._post_action(action, signature, timestamp)) + + +if __name__ == "__main__": + main()