diff --git a/cross-chain/solana/.gitignore b/cross-chain/solana/.gitignore new file mode 100644 index 000000000..3db15d86f --- /dev/null +++ b/cross-chain/solana/.gitignore @@ -0,0 +1,9 @@ + +.anchor +.DS_Store +target +**/*.rs.bk +node_modules +test-ledger +artifacts-mainnet +artifacts-testnet \ No newline at end of file diff --git a/cross-chain/solana/.prettierignore b/cross-chain/solana/.prettierignore new file mode 100644 index 000000000..c1a0b75f0 --- /dev/null +++ b/cross-chain/solana/.prettierignore @@ -0,0 +1,8 @@ + +.anchor +.DS_Store +target +node_modules +dist +build +test-ledger diff --git a/cross-chain/solana/Anchor.toml b/cross-chain/solana/Anchor.toml new file mode 100644 index 000000000..6025a94f1 --- /dev/null +++ b/cross-chain/solana/Anchor.toml @@ -0,0 +1,82 @@ +[features] +seeds = false +skip-lint = false + +[workspace] +members = [ + "programs/tbtc", + "programs/wormhole-gateway", +] + + +[programs.localnet] +tbtc = "HksEtDgsXJV1BqcuhzbLRTmXp5gHgHJktieJCtQd3pG" +wormhole-gateway = "8H9F5JGbEMyERycwaGuzLS5MQnV7dn2wm2h6egJ3Leiu" + +[registry] +url = "https://api.apr.dev" + +[provider] +cluster = "Localnet" +wallet = "~/.config/solana/id.json" + +[scripts] +test = "npx ts-mocha -p ./tsconfig.json -t 1000000 tests/**/*.ts" + +[test] +startup_wait = 10000 + +[test.validator] +url = "https://api.mainnet-beta.solana.com" + +### MPL Token Metadata +[[test.validator.clone]] +address = "metaqbxxUerdq28cj1RbAWkYQm3ybzjb6a8bt518x1s" + +### Wormhole Core Bridge +[[test.validator.clone]] +address = "worm2ZoG2kUd4vFXhvjh93UUH596ayRfgQ2MgjNMTth" + +### Wormhole Token Bridge +[[test.validator.clone]] +address = "wormDTUJ6AWPNvk59vGQbDvGJmqbDTdgWgAqcLBCgUb" + +### Token Bridge -- Wrapped tBTC Mint +[[test.validator.account]] +address = "25rXTx9zDZcHyTav5sRqM6YBvTGu9pPH9yv83uAEqbgG" +filename = "tests/accounts/wrapped_tbtc_mint.json" + +### Token Bridge -- Wrapped tBTC Asset +[[test.validator.account]] +address = "5LEUZpBxUQmoxoNGqmYmFEGAPDuhWbAY5CGt519UixLo" +filename = "tests/accounts/wrapped_tbtc_asset.json" + +### Token Bridge -- Ethereum Foreign Endpoint +[[test.validator.account]] +address = "DujfLgMKW71CT2W8pxknf42FT86VbcK5PjQ6LsutjWKC" +filename = "tests/accounts/ethereum_token_bridge.json" + +### Token Bridge -- Config +[[test.validator.account]] +address = "DapiQYH3BGonhN8cngWcXQ6SrqSm3cwysoznoHr6Sbsx" +filename = "tests/accounts/token_bridge_config.json" + +### Core Bridge -- Bridge +[[test.validator.clone]] +address = "2yVjuQwpsvdsrywzsJJVs9Ueh4zayyo5DYJbBNc3DDpn" +filename = "tests/accounts/core_bridge.json" + +### Core Bridge -- Emitter Sequence (Token Bridge's) +[[test.validator.account]] +address = "GF2ghkjwsR9CHkGk1RvuZrApPZGBZynxMm817VNi51Nf" +filename = "tests/accounts/core_emitter_sequence.json" + +### Core Bridge -- Fee Collector +[[test.validator.account]] +address = "9bFNrXNb2WTx8fMHXCheaZqkLZ3YCCaiqTftHxeintHy" +filename = "tests/accounts/core_fee_collector.json" + +### Core Bridge -- Guardian Set (index == 3) +[[test.validator.account]] +address = "6d3w8mGjJauf6gCAg7WfLezbaPmUHYGuoNutnfYF1RYM" +filename = "tests/accounts/core_guardian_set.json" diff --git a/cross-chain/solana/Cargo.lock b/cross-chain/solana/Cargo.lock new file mode 100644 index 000000000..b01fb264b --- /dev/null +++ b/cross-chain/solana/Cargo.lock @@ -0,0 +1,2107 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "aead" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b613b8e1e3cf911a086f53f03bf286f52fd7a7258e4fa606f0ef220d39d8877" +dependencies = [ + "generic-array", +] + +[[package]] +name = "aes" +version = "0.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e8b47f52ea9bae42228d07ec09eb676433d7c4ed1ebdf0f1d1c29ed446f1ab8" +dependencies = [ + "cfg-if", + "cipher 0.3.0", + "cpufeatures", + "opaque-debug", +] + +[[package]] +name = "aes-gcm-siv" +version = "0.10.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "589c637f0e68c877bbd59a4599bbe849cac8e5f3e4b5a3ebae8f528cd218dcdc" +dependencies = [ + "aead", + "aes", + "cipher 0.3.0", + "ctr", + "polyval", + "subtle", + "zeroize", +] + +[[package]] +name = "ahash" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fcb51a0695d8f838b1ee009b3fbf66bda078cd64590202a864a8f3e8c4315c47" +dependencies = [ + "getrandom 0.2.10", + "once_cell", + "version_check", +] + +[[package]] +name = "aho-corasick" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43f6cb1bf222025340178f382c426f13757b2960e89779dfcb319c32542a5a41" +dependencies = [ + "memchr", +] + +[[package]] +name = "anchor-attribute-access-control" +version = "0.28.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "faa5be5b72abea167f87c868379ba3c2be356bfca9e6f474fd055fa0f7eeb4f2" +dependencies = [ + "anchor-syn", + "anyhow", + "proc-macro2", + "quote", + "regex", + "syn 1.0.109", +] + +[[package]] +name = "anchor-attribute-account" +version = "0.28.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f468970344c7c9f9d03b4da854fd7c54f21305059f53789d0045c1dd803f0018" +dependencies = [ + "anchor-syn", + "anyhow", + "bs58 0.5.0", + "proc-macro2", + "quote", + "rustversion", + "syn 1.0.109", +] + +[[package]] +name = "anchor-attribute-constant" +version = "0.28.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "59948e7f9ef8144c2aefb3f32a40c5fce2798baeec765ba038389e82301017ef" +dependencies = [ + "anchor-syn", + "proc-macro2", + "syn 1.0.109", +] + +[[package]] +name = "anchor-attribute-error" +version = "0.28.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc753c9d1c7981cb8948cf7e162fb0f64558999c0413058e2d43df1df5448086" +dependencies = [ + "anchor-syn", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "anchor-attribute-event" +version = "0.28.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f38b4e172ba1b52078f53fdc9f11e3dc0668ad27997838a0aad2d148afac8c97" +dependencies = [ + "anchor-syn", + "anyhow", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "anchor-attribute-program" +version = "0.28.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4eebd21543606ab61e2d83d9da37d24d3886a49f390f9c43a1964735e8c0f0d5" +dependencies = [ + "anchor-syn", + "anyhow", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "anchor-derive-accounts" +version = "0.28.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec4720d899b3686396cced9508f23dab420f1308344456ec78ef76f98fda42af" +dependencies = [ + "anchor-syn", + "anyhow", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "anchor-derive-space" +version = "0.28.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f495e85480bd96ddeb77b71d499247c7d4e8b501e75ecb234e9ef7ae7bd6552a" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "anchor-lang" +version = "0.28.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d2d4b20100f1310a774aba3471ef268e5c4ba4d5c28c0bbe663c2658acbc414" +dependencies = [ + "anchor-attribute-access-control", + "anchor-attribute-account", + "anchor-attribute-constant", + "anchor-attribute-error", + "anchor-attribute-event", + "anchor-attribute-program", + "anchor-derive-accounts", + "anchor-derive-space", + "arrayref", + "base64 0.13.1", + "bincode", + "borsh", + "bytemuck", + "getrandom 0.2.10", + "solana-program", + "thiserror", +] + +[[package]] +name = "anchor-spl" +version = "0.28.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78f860599da1c2354e7234c768783049eb42e2f54509ecfc942d2e0076a2da7b" +dependencies = [ + "anchor-lang", + "solana-program", + "spl-associated-token-account", + "spl-token", + "spl-token-2022", +] + +[[package]] +name = "anchor-syn" +version = "0.28.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a125e4b0cc046cfec58f5aa25038e34cf440151d58f0db3afc55308251fe936d" +dependencies = [ + "anyhow", + "bs58 0.5.0", + "heck", + "proc-macro2", + "quote", + "serde", + "serde_json", + "sha2 0.10.7", + "syn 1.0.109", + "thiserror", +] + +[[package]] +name = "android-tzdata" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0" + +[[package]] +name = "anyhow" +version = "1.0.72" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b13c32d80ecc7ab747b80c3784bce54ee8a7a0cc4fbda9bf4cda2cf6fe90854" + +[[package]] +name = "arrayref" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6b4930d2cb77ce62f89ee5d5289b4ac049559b1c45539271f5ed4fdc7db34545" + +[[package]] +name = "arrayvec" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" + +[[package]] +name = "assert_matches" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b34d609dfbaf33d6889b2b7106d3ca345eacad44200913df5ba02bfd31d2ba9" + +[[package]] +name = "atty" +version = "0.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" +dependencies = [ + "hermit-abi 0.1.19", + "libc", + "winapi", +] + +[[package]] +name = "autocfg" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" + +[[package]] +name = "base64" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3441f0f7b02788e948e47f457ca01f1d7e6d92c693bc132c22b087d3141c03ff" + +[[package]] +name = "base64" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" + +[[package]] +name = "bincode" +version = "1.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1f45e9417d87227c7a56d22e471c6206462cba514c7590c09aff4cf6d1ddcad" +dependencies = [ + "serde", +] + +[[package]] +name = "bitflags" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" + +[[package]] +name = "bitmaps" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "031043d04099746d8db04daf1fa424b2bc8bd69d92b25962dcde24da39ab64a2" +dependencies = [ + "typenum", +] + +[[package]] +name = "blake3" +version = "1.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a08e53fc5a564bb15bfe6fae56bd71522205f1f91893f9c0116edad6496c183f" +dependencies = [ + "arrayref", + "arrayvec", + "cc", + "cfg-if", + "constant_time_eq", + "digest 0.10.7", +] + +[[package]] +name = "block-buffer" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4152116fd6e9dadb291ae18fc1ec3575ed6d84c29642d97890f4b4a3417297e4" +dependencies = [ + "block-padding", + "generic-array", +] + +[[package]] +name = "block-buffer" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" +dependencies = [ + "generic-array", +] + +[[package]] +name = "block-padding" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8d696c370c750c948ada61c69a0ee2cbbb9c50b1019ddb86d9317157a99c2cae" + +[[package]] +name = "borsh" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "15bf3650200d8bffa99015595e10f1fbd17de07abbc25bb067da79e769939bfa" +dependencies = [ + "borsh-derive", + "hashbrown 0.11.2", +] + +[[package]] +name = "borsh-derive" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6441c552f230375d18e3cc377677914d2ca2b0d36e52129fe15450a2dce46775" +dependencies = [ + "borsh-derive-internal", + "borsh-schema-derive-internal", + "proc-macro-crate 0.1.5", + "proc-macro2", + "syn 1.0.109", +] + +[[package]] +name = "borsh-derive-internal" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5449c28a7b352f2d1e592a8a28bf139bc71afb0764a14f3c02500935d8c44065" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "borsh-schema-derive-internal" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cdbd5696d8bfa21d53d9fe39a714a18538bad11492a42d066dbbc395fb1951c0" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "bs58" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "771fe0050b883fcc3ea2359b1a96bcfbc090b7116eae7c3c512c7a083fdf23d3" + +[[package]] +name = "bs58" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f5353f36341f7451062466f0b755b96ac3a9547e4d7f6b70d603fc721a7d7896" +dependencies = [ + "tinyvec", +] + +[[package]] +name = "bumpalo" +version = "3.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a3e2c3daef883ecc1b5d58c15adae93470a91d425f3532ba1695849656af3fc1" + +[[package]] +name = "bv" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8834bb1d8ee5dc048ee3124f2c7c1afcc6bc9aed03f11e9dfd8c69470a5db340" +dependencies = [ + "feature-probe", + "serde", +] + +[[package]] +name = "bytemuck" +version = "1.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "17febce684fd15d89027105661fec94afb475cb995fbc59d2865198446ba2eea" +dependencies = [ + "bytemuck_derive", +] + +[[package]] +name = "bytemuck_derive" +version = "1.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fdde5c9cd29ebd706ce1b35600920a33550e402fc998a2e53ad3b42c3c47a192" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.28", +] + +[[package]] +name = "byteorder" +version = "1.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" + +[[package]] +name = "cc" +version = "1.0.79" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "50d30906286121d95be3d479533b458f87493b30a4b5f79a607db8f5d11aa91f" +dependencies = [ + "jobserver", +] + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "chrono" +version = "0.4.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec837a71355b28f6556dbd569b37b3f363091c0bd4b2e735674521b4c5fd9bc5" +dependencies = [ + "android-tzdata", + "num-traits", +] + +[[package]] +name = "cipher" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ee52072ec15386f770805afd189a01c8841be8696bed250fa2f13c4c0d6dfb7" +dependencies = [ + "generic-array", +] + +[[package]] +name = "cipher" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "773f3b9af64447d2ce9850330c473515014aa235e6a783b02db81ff39e4a3dad" +dependencies = [ + "crypto-common", + "inout", +] + +[[package]] +name = "console_error_panic_hook" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a06aeb73f470f66dcdbf7223caeebb85984942f22f1adb2a088cf9668146bbbc" +dependencies = [ + "cfg-if", + "wasm-bindgen", +] + +[[package]] +name = "console_log" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e89f72f65e8501878b8a004d5a1afb780987e2ce2b4532c562e367a72c57499f" +dependencies = [ + "log", + "web-sys", +] + +[[package]] +name = "constant_time_eq" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "245097e9a4535ee1e3e3931fcfcd55a796a44c643e8596ff6566d68f09b87bbc" + +[[package]] +name = "cpufeatures" +version = "0.2.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a17b76ff3a4162b0b27f354a0c87015ddad39d35f9c0c36607a3bdd175dde1f1" +dependencies = [ + "libc", +] + +[[package]] +name = "crossbeam-channel" +version = "0.5.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a33c2bf77f2df06183c3aa30d1e96c0695a313d4f9c453cc3762a6db39f99200" +dependencies = [ + "cfg-if", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-deque" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce6fd6f855243022dcecf8702fef0c297d4338e226845fe067f6341ad9fa0cef" +dependencies = [ + "cfg-if", + "crossbeam-epoch", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-epoch" +version = "0.9.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae211234986c545741a7dc064309f67ee1e5ad243d0e48335adc0484d960bcc7" +dependencies = [ + "autocfg", + "cfg-if", + "crossbeam-utils", + "memoffset 0.9.0", + "scopeguard", +] + +[[package]] +name = "crossbeam-utils" +version = "0.8.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a22b2d63d4d1dc0b7f1b6b2747dd0088008a9be28b6ddf0b1e7d335e3037294" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "crunchy" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" + +[[package]] +name = "crypto-common" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" +dependencies = [ + "generic-array", + "typenum", +] + +[[package]] +name = "crypto-mac" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b584a330336237c1eecd3e94266efb216c56ed91225d634cb2991c5f3fd1aeab" +dependencies = [ + "generic-array", + "subtle", +] + +[[package]] +name = "ctr" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "049bb91fb4aaf0e3c7efa6cd5ef877dbbbd15b39dad06d9948de4ec8a75761ea" +dependencies = [ + "cipher 0.3.0", +] + +[[package]] +name = "curve25519-dalek" +version = "3.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90f9d052967f590a76e62eb387bd0bbb1b000182c3cefe5364db6b7211651bc0" +dependencies = [ + "byteorder", + "digest 0.9.0", + "rand_core 0.5.1", + "serde", + "subtle", + "zeroize", +] + +[[package]] +name = "derivation-path" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e5c37193a1db1d8ed868c03ec7b152175f26160a5b740e5e484143877e0adf0" + +[[package]] +name = "digest" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3dd60d1080a57a05ab032377049e0591415d2b31afd7028356dbf3cc6dcb066" +dependencies = [ + "generic-array", +] + +[[package]] +name = "digest" +version = "0.10.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" +dependencies = [ + "block-buffer 0.10.4", + "crypto-common", + "subtle", +] + +[[package]] +name = "ed25519" +version = "1.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91cff35c70bba8a626e3185d8cd48cc11b5437e1a5bcd15b9b5fa3c64b6dfee7" +dependencies = [ + "signature", +] + +[[package]] +name = "ed25519-dalek" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c762bae6dcaf24c4c84667b8579785430908723d5c889f469d76a41d59cc7a9d" +dependencies = [ + "curve25519-dalek", + "ed25519", + "rand", + "serde", + "sha2 0.9.9", + "zeroize", +] + +[[package]] +name = "ed25519-dalek-bip32" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d2be62a4061b872c8c0873ee4fc6f101ce7b889d039f019c5fa2af471a59908" +dependencies = [ + "derivation-path", + "ed25519-dalek", + "hmac 0.12.1", + "sha2 0.10.7", +] + +[[package]] +name = "either" +version = "1.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a26ae43d7bcc3b814de94796a5e736d4029efb0ee900c12e2d54c993ad1a1e07" + +[[package]] +name = "env_logger" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a12e6657c4c97ebab115a42dcee77225f7f482cdd841cf7088c657a42e9e00e7" +dependencies = [ + "atty", + "humantime", + "log", + "regex", + "termcolor", +] + +[[package]] +name = "feature-probe" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "835a3dc7d1ec9e75e2b5fb4ba75396837112d2060b03f7d43bc1897c7f7211da" + +[[package]] +name = "fnv" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" + +[[package]] +name = "generic-array" +version = "0.14.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" +dependencies = [ + "serde", + "typenum", + "version_check", +] + +[[package]] +name = "getrandom" +version = "0.1.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8fc3cb4d91f53b50155bdcfd23f6a4c39ae1969c2ae85982b135750cccaf5fce" +dependencies = [ + "cfg-if", + "js-sys", + "libc", + "wasi 0.9.0+wasi-snapshot-preview1", + "wasm-bindgen", +] + +[[package]] +name = "getrandom" +version = "0.2.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be4136b2a15dd319360be1c07d9933517ccf0be8f16bf62a3bee4f0d618df427" +dependencies = [ + "cfg-if", + "js-sys", + "libc", + "wasi 0.11.0+wasi-snapshot-preview1", + "wasm-bindgen", +] + +[[package]] +name = "hashbrown" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ab5ef0d4909ef3724cc8cce6ccc8572c5c817592e9285f5464f8e86f8bd3726e" +dependencies = [ + "ahash", +] + +[[package]] +name = "hashbrown" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" +dependencies = [ + "ahash", +] + +[[package]] +name = "heck" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d621efb26863f0e9924c6ac577e8275e5e6b77455db64ffa6c65c904e9e132c" +dependencies = [ + "unicode-segmentation", +] + +[[package]] +name = "hermit-abi" +version = "0.1.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33" +dependencies = [ + "libc", +] + +[[package]] +name = "hermit-abi" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "443144c8cdadd93ebf52ddb4056d257f5b52c04d3c804e657d19eb73fc33668b" + +[[package]] +name = "hmac" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "126888268dcc288495a26bf004b38c5fdbb31682f992c84ceb046a1f0fe38840" +dependencies = [ + "crypto-mac", + "digest 0.9.0", +] + +[[package]] +name = "hmac" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" +dependencies = [ + "digest 0.10.7", +] + +[[package]] +name = "hmac-drbg" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "17ea0a1394df5b6574da6e0c1ade9e78868c9fb0a4e5ef4428e32da4676b85b1" +dependencies = [ + "digest 0.9.0", + "generic-array", + "hmac 0.8.1", +] + +[[package]] +name = "humantime" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" + +[[package]] +name = "im" +version = "15.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d0acd33ff0285af998aaf9b57342af478078f53492322fafc47450e09397e0e9" +dependencies = [ + "bitmaps", + "rand_core 0.6.4", + "rand_xoshiro", + "rayon", + "serde", + "sized-chunks", + "typenum", + "version_check", +] + +[[package]] +name = "indexmap" +version = "1.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" +dependencies = [ + "autocfg", + "hashbrown 0.12.3", +] + +[[package]] +name = "inout" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a0c10553d664a4d0bcff9f4215d0aac67a639cc68ef660840afe309b807bc9f5" +dependencies = [ + "generic-array", +] + +[[package]] +name = "itertools" +version = "0.10.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473" +dependencies = [ + "either", +] + +[[package]] +name = "itoa" +version = "1.0.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af150ab688ff2122fcef229be89cb50dd66af9e01a4ff320cc137eecc9bacc38" + +[[package]] +name = "jobserver" +version = "0.1.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "936cfd212a0155903bcbc060e316fb6cc7cbf2e1907329391ebadc1fe0ce77c2" +dependencies = [ + "libc", +] + +[[package]] +name = "js-sys" +version = "0.3.64" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c5f195fe497f702db0f318b07fdd68edb16955aed830df8363d837542f8f935a" +dependencies = [ + "wasm-bindgen", +] + +[[package]] +name = "keccak" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f6d5ed8676d904364de097082f4e7d240b571b67989ced0240f08b7f966f940" +dependencies = [ + "cpufeatures", +] + +[[package]] +name = "lazy_static" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" + +[[package]] +name = "libc" +version = "0.2.147" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b4668fb0ea861c1df094127ac5f1da3409a82116a4ba74fca2e58ef927159bb3" + +[[package]] +name = "libsecp256k1" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c9d220bc1feda2ac231cb78c3d26f27676b8cf82c96971f7aeef3d0cf2797c73" +dependencies = [ + "arrayref", + "base64 0.12.3", + "digest 0.9.0", + "hmac-drbg", + "libsecp256k1-core", + "libsecp256k1-gen-ecmult", + "libsecp256k1-gen-genmult", + "rand", + "serde", + "sha2 0.9.9", + "typenum", +] + +[[package]] +name = "libsecp256k1-core" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d0f6ab710cec28cef759c5f18671a27dae2a5f952cdaaee1d8e2908cb2478a80" +dependencies = [ + "crunchy", + "digest 0.9.0", + "subtle", +] + +[[package]] +name = "libsecp256k1-gen-ecmult" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ccab96b584d38fac86a83f07e659f0deafd0253dc096dab5a36d53efe653c5c3" +dependencies = [ + "libsecp256k1-core", +] + +[[package]] +name = "libsecp256k1-gen-genmult" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67abfe149395e3aa1c48a2beb32b068e2334402df8181f818d3aee2b304c4f5d" +dependencies = [ + "libsecp256k1-core", +] + +[[package]] +name = "lock_api" +version = "0.4.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c1cc9717a20b1bb222f333e6a92fd32f7d8a18ddc5a3191a11af45dcbf4dcd16" +dependencies = [ + "autocfg", + "scopeguard", +] + +[[package]] +name = "log" +version = "0.4.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b06a4cde4c0f271a446782e3eff8de789548ce57dbc8eca9292c27f4a42004b4" + +[[package]] +name = "memchr" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" + +[[package]] +name = "memmap2" +version = "0.5.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "83faa42c0a078c393f6b29d5db232d8be22776a891f8f56e5284faee4a20b327" +dependencies = [ + "libc", +] + +[[package]] +name = "memoffset" +version = "0.6.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5aa361d4faea93603064a027415f07bd8e1d5c88c9fbf68bf56a285428fd79ce" +dependencies = [ + "autocfg", +] + +[[package]] +name = "memoffset" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a634b1c61a95585bd15607c6ab0c4e5b226e695ff2800ba0cdccddf208c406c" +dependencies = [ + "autocfg", +] + +[[package]] +name = "merlin" +version = "3.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "58c38e2799fc0978b65dfff8023ec7843e2330bb462f19198840b34b6582397d" +dependencies = [ + "byteorder", + "keccak", + "rand_core 0.6.4", + "zeroize", +] + +[[package]] +name = "num-derive" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "876a53fff98e03a936a674b29568b0e605f06b29372c2489ff4de23f1949743d" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "num-traits" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f30b0abd723be7e2ffca1272140fac1a2f084c77ec3e123c192b66af1ee9e6c2" +dependencies = [ + "autocfg", +] + +[[package]] +name = "num_cpus" +version = "1.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43" +dependencies = [ + "hermit-abi 0.3.2", + "libc", +] + +[[package]] +name = "num_enum" +version = "0.5.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f646caf906c20226733ed5b1374287eb97e3c2a5c227ce668c1f2ce20ae57c9" +dependencies = [ + "num_enum_derive", +] + +[[package]] +name = "num_enum_derive" +version = "0.5.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dcbff9bc912032c62bf65ef1d5aea88983b420f4f839db1e9b0c281a25c9c799" +dependencies = [ + "proc-macro-crate 1.3.1", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "once_cell" +version = "1.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" + +[[package]] +name = "opaque-debug" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" + +[[package]] +name = "parking_lot" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f" +dependencies = [ + "lock_api", + "parking_lot_core", +] + +[[package]] +name = "parking_lot_core" +version = "0.9.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93f00c865fe7cabf650081affecd3871070f26767e7b2070a3ffae14c654b447" +dependencies = [ + "cfg-if", + "libc", + "redox_syscall", + "smallvec", + "windows-targets", +] + +[[package]] +name = "pbkdf2" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "216eaa586a190f0a738f2f918511eecfa90f13295abec0e457cdebcceda80cbd" +dependencies = [ + "crypto-mac", +] + +[[package]] +name = "pbkdf2" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "83a0692ec44e4cf1ef28ca317f14f8f07da2d95ec3fa01f86e4467b725e60917" +dependencies = [ + "digest 0.10.7", +] + +[[package]] +name = "percent-encoding" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b2a4787296e9989611394c33f193f676704af1686e70b8f8033ab5ba9a35a94" + +[[package]] +name = "polyval" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8419d2b623c7c0896ff2d5d96e2cb4ede590fed28fcc34934f4c33c036e620a1" +dependencies = [ + "cfg-if", + "cpufeatures", + "opaque-debug", + "universal-hash", +] + +[[package]] +name = "ppv-lite86" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" + +[[package]] +name = "proc-macro-crate" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d6ea3c4595b96363c13943497db34af4460fb474a95c43f4446ad341b8c9785" +dependencies = [ + "toml", +] + +[[package]] +name = "proc-macro-crate" +version = "1.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f4c021e1093a56626774e81216a4ce732a735e5bad4868a03f3ed65ca0c3919" +dependencies = [ + "once_cell", + "toml_edit", +] + +[[package]] +name = "proc-macro2" +version = "1.0.66" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "18fb31db3f9bddb2ea821cde30a9f70117e3f119938b5ee630b7403aa6e2ead9" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "qstring" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d464fae65fff2680baf48019211ce37aaec0c78e9264c84a3e484717f965104e" +dependencies = [ + "percent-encoding", +] + +[[package]] +name = "quote" +version = "1.0.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "50f3b39ccfb720540debaa0164757101c08ecb8d326b15358ce76a62c7e85965" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "rand" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03" +dependencies = [ + "getrandom 0.1.16", + "libc", + "rand_chacha", + "rand_core 0.5.1", + "rand_hc", +] + +[[package]] +name = "rand_chacha" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402" +dependencies = [ + "ppv-lite86", + "rand_core 0.5.1", +] + +[[package]] +name = "rand_core" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19" +dependencies = [ + "getrandom 0.1.16", +] + +[[package]] +name = "rand_core" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" +dependencies = [ + "getrandom 0.2.10", +] + +[[package]] +name = "rand_hc" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c" +dependencies = [ + "rand_core 0.5.1", +] + +[[package]] +name = "rand_xoshiro" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6f97cdb2a36ed4183de61b2f824cc45c9f1037f28afe0a322e9fff4c108b5aaa" +dependencies = [ + "rand_core 0.6.4", +] + +[[package]] +name = "rayon" +version = "1.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d2df5196e37bcc87abebc0053e20787d73847bb33134a69841207dd0a47f03b" +dependencies = [ + "either", + "rayon-core", +] + +[[package]] +name = "rayon-core" +version = "1.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4b8f95bd6966f5c87776639160a66bd8ab9895d9d4ab01ddba9fc60661aebe8d" +dependencies = [ + "crossbeam-channel", + "crossbeam-deque", + "crossbeam-utils", + "num_cpus", +] + +[[package]] +name = "redox_syscall" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "567664f262709473930a4bf9e51bf2ebf3348f2e748ccc50dea20646858f8f29" +dependencies = [ + "bitflags", +] + +[[package]] +name = "regex" +version = "1.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2eae68fc220f7cf2532e4494aded17545fce192d59cd996e0fe7887f4ceb575" +dependencies = [ + "aho-corasick", + "memchr", + "regex-automata", + "regex-syntax", +] + +[[package]] +name = "regex-automata" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b7b6d6190b7594385f61bd3911cd1be99dfddcfc365a4160cc2ab5bff4aed294" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax", +] + +[[package]] +name = "regex-syntax" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5ea92a5b6195c6ef2a0295ea818b312502c6fc94dde986c5553242e18fd4ce2" + +[[package]] +name = "rustc-hash" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" + +[[package]] +name = "rustc_version" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" +dependencies = [ + "semver", +] + +[[package]] +name = "rustversion" +version = "1.0.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ffc183a10b4478d04cbbbfc96d0873219d962dd5accaff2ffbd4ceb7df837f4" + +[[package]] +name = "ryu" +version = "1.0.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ad4cc8da4ef723ed60bced201181d83791ad433213d8c24efffda1eec85d741" + +[[package]] +name = "scopeguard" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" + +[[package]] +name = "semver" +version = "1.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0293b4b29daaf487284529cc2f5675b8e57c61f70167ba415a463651fd6a918" + +[[package]] +name = "serde" +version = "1.0.179" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0a5bf42b8d227d4abf38a1ddb08602e229108a517cd4e5bb28f9c7eaafdce5c0" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_bytes" +version = "0.11.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ab33ec92f677585af6d88c65593ae2375adde54efdbf16d597f2cbc7a6d368ff" +dependencies = [ + "serde", +] + +[[package]] +name = "serde_derive" +version = "1.0.179" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "741e124f5485c7e60c03b043f79f320bff3527f4bbf12cf3831750dc46a0ec2c" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.28", +] + +[[package]] +name = "serde_json" +version = "1.0.104" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "076066c5f1078eac5b722a31827a8832fe108bed65dfa75e233c89f8206e976c" +dependencies = [ + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "sha2" +version = "0.9.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4d58a1e1bf39749807d89cf2d98ac2dfa0ff1cb3faa38fbb64dd88ac8013d800" +dependencies = [ + "block-buffer 0.9.0", + "cfg-if", + "cpufeatures", + "digest 0.9.0", + "opaque-debug", +] + +[[package]] +name = "sha2" +version = "0.10.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "479fb9d862239e610720565ca91403019f2f00410f1864c5aa7479b950a76ed8" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest 0.10.7", +] + +[[package]] +name = "sha3" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f81199417d4e5de3f04b1e871023acea7389672c4135918f05aa9cbf2f2fa809" +dependencies = [ + "block-buffer 0.9.0", + "digest 0.9.0", + "keccak", + "opaque-debug", +] + +[[package]] +name = "sha3" +version = "0.10.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75872d278a8f37ef87fa0ddbda7802605cb18344497949862c0d4dcb291eba60" +dependencies = [ + "digest 0.10.7", + "keccak", +] + +[[package]] +name = "signature" +version = "1.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "74233d3b3b2f6d4b006dc19dee745e73e2a6bfb6f93607cd3b02bd5b00797d7c" + +[[package]] +name = "sized-chunks" +version = "0.6.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "16d69225bde7a69b235da73377861095455d298f2b970996eec25ddbb42b3d1e" +dependencies = [ + "bitmaps", + "typenum", +] + +[[package]] +name = "smallvec" +version = "1.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62bb4feee49fdd9f707ef802e22365a35de4b7b299de4763d44bfea899442ff9" + +[[package]] +name = "solana-frozen-abi" +version = "1.14.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7a100b7fa8198c20354eb7256c0d9789107d8a62280221f3efe15f7c9dc4cec" +dependencies = [ + "ahash", + "blake3", + "block-buffer 0.9.0", + "bs58 0.4.0", + "bv", + "byteorder", + "cc", + "either", + "generic-array", + "getrandom 0.1.16", + "hashbrown 0.12.3", + "im", + "lazy_static", + "log", + "memmap2", + "once_cell", + "rand_core 0.6.4", + "rustc_version", + "serde", + "serde_bytes", + "serde_derive", + "serde_json", + "sha2 0.10.7", + "solana-frozen-abi-macro", + "subtle", + "thiserror", +] + +[[package]] +name = "solana-frozen-abi-macro" +version = "1.14.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f527f44601b35dd67d11bc72f2f7512976a466f9304ef574b87dac83ced8a42" +dependencies = [ + "proc-macro2", + "quote", + "rustc_version", + "syn 1.0.109", +] + +[[package]] +name = "solana-logger" +version = "1.14.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8632c8bc480bb5615b70a18b807ede73024aebc7761503ff86a70b7f4906ae47" +dependencies = [ + "env_logger", + "lazy_static", + "log", +] + +[[package]] +name = "solana-program" +version = "1.14.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "51ad5f48743ce505f6139a07e20aecdc689def12da7230fed661c2073ab97df8" +dependencies = [ + "base64 0.13.1", + "bincode", + "bitflags", + "blake3", + "borsh", + "borsh-derive", + "bs58 0.4.0", + "bv", + "bytemuck", + "cc", + "console_error_panic_hook", + "console_log", + "curve25519-dalek", + "getrandom 0.2.10", + "itertools", + "js-sys", + "lazy_static", + "libc", + "libsecp256k1", + "log", + "memoffset 0.6.5", + "num-derive", + "num-traits", + "parking_lot", + "rand", + "rand_chacha", + "rustc_version", + "rustversion", + "serde", + "serde_bytes", + "serde_derive", + "serde_json", + "sha2 0.10.7", + "sha3 0.10.8", + "solana-frozen-abi", + "solana-frozen-abi-macro", + "solana-sdk-macro", + "thiserror", + "tiny-bip39", + "wasm-bindgen", + "zeroize", +] + +[[package]] +name = "solana-sdk" +version = "1.14.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1c515a5a5a5cdc115044c33959eb4d091680f5e7ca8be9eb5218fb0c21bf3568" +dependencies = [ + "assert_matches", + "base64 0.13.1", + "bincode", + "bitflags", + "borsh", + "bs58 0.4.0", + "bytemuck", + "byteorder", + "chrono", + "derivation-path", + "digest 0.10.7", + "ed25519-dalek", + "ed25519-dalek-bip32", + "generic-array", + "hmac 0.12.1", + "itertools", + "js-sys", + "lazy_static", + "libsecp256k1", + "log", + "memmap2", + "num-derive", + "num-traits", + "pbkdf2 0.11.0", + "qstring", + "rand", + "rand_chacha", + "rustc_version", + "rustversion", + "serde", + "serde_bytes", + "serde_derive", + "serde_json", + "sha2 0.10.7", + "sha3 0.10.8", + "solana-frozen-abi", + "solana-frozen-abi-macro", + "solana-logger", + "solana-program", + "solana-sdk-macro", + "thiserror", + "uriparse", + "wasm-bindgen", +] + +[[package]] +name = "solana-sdk-macro" +version = "1.14.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4bbc3ab3070c090e1a18fd5a0a07d729d0db2bc8524414dc3e16504286d38049" +dependencies = [ + "bs58 0.4.0", + "proc-macro2", + "quote", + "rustversion", + "syn 1.0.109", +] + +[[package]] +name = "solana-zk-token-sdk" +version = "1.14.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d51d131cdefcb621a8034321ce487c4f788e813f81ce81e4f65eed8d4b4f2aa" +dependencies = [ + "aes-gcm-siv", + "arrayref", + "base64 0.13.1", + "bincode", + "bytemuck", + "byteorder", + "cipher 0.4.4", + "curve25519-dalek", + "getrandom 0.1.16", + "itertools", + "lazy_static", + "merlin", + "num-derive", + "num-traits", + "rand", + "serde", + "serde_json", + "sha3 0.9.1", + "solana-program", + "solana-sdk", + "subtle", + "thiserror", + "zeroize", +] + +[[package]] +name = "spl-associated-token-account" +version = "1.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "978dba3bcbe88d0c2c58366c254d9ea41c5f73357e72fc0bdee4d6b5fc99c8f4" +dependencies = [ + "assert_matches", + "borsh", + "num-derive", + "num-traits", + "solana-program", + "spl-token", + "spl-token-2022", + "thiserror", +] + +[[package]] +name = "spl-memo" +version = "3.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd0dc6f70db6bacea7ff25870b016a65ba1d1b6013536f08e4fd79a8f9005325" +dependencies = [ + "solana-program", +] + +[[package]] +name = "spl-token" +version = "3.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e85e168a785e82564160dcb87b2a8e04cee9bfd1f4d488c729d53d6a4bd300d" +dependencies = [ + "arrayref", + "bytemuck", + "num-derive", + "num-traits", + "num_enum", + "solana-program", + "thiserror", +] + +[[package]] +name = "spl-token-2022" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0043b590232c400bad5ee9eb983ced003d15163c4c5d56b090ac6d9a57457b47" +dependencies = [ + "arrayref", + "bytemuck", + "num-derive", + "num-traits", + "num_enum", + "solana-program", + "solana-zk-token-sdk", + "spl-memo", + "spl-token", + "thiserror", +] + +[[package]] +name = "subtle" +version = "2.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601" + +[[package]] +name = "syn" +version = "1.0.109" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "syn" +version = "2.0.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "04361975b3f5e348b2189d8dc55bc942f278b2d482a6a0365de5bdd62d351567" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "tbtc" +version = "0.1.0" +dependencies = [ + "anchor-lang", + "anchor-spl", + "solana-program", +] + +[[package]] +name = "termcolor" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be55cf8942feac5c765c2c993422806843c9a9a45d4d5c407ad6dd2ea95eb9b6" +dependencies = [ + "winapi-util", +] + +[[package]] +name = "thiserror" +version = "1.0.44" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "611040a08a0439f8248d1990b111c95baa9c704c805fa1f62104b39655fd7f90" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.44" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "090198534930841fab3a5d1bb637cde49e339654e606195f8d9c76eeb081dc96" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.28", +] + +[[package]] +name = "tiny-bip39" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ffc59cb9dfc85bb312c3a78fd6aa8a8582e310b0fa885d5bb877f6dcc601839d" +dependencies = [ + "anyhow", + "hmac 0.8.1", + "once_cell", + "pbkdf2 0.4.0", + "rand", + "rustc-hash", + "sha2 0.9.9", + "thiserror", + "unicode-normalization", + "wasm-bindgen", + "zeroize", +] + +[[package]] +name = "tinyvec" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87cc5ceb3875bb20c2890005a4e226a4651264a5c75edb2421b52861a0a0cb50" +dependencies = [ + "tinyvec_macros", +] + +[[package]] +name = "tinyvec_macros" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" + +[[package]] +name = "toml" +version = "0.5.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4f7f0dd8d50a853a531c426359045b1998f04219d88799810762cd4ad314234" +dependencies = [ + "serde", +] + +[[package]] +name = "toml_datetime" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3ab8ed2edee10b50132aed5f331333428b011c99402b5a534154ed15746f9622" + +[[package]] +name = "toml_edit" +version = "0.19.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "239410c8609e8125456927e6707163a3b1fdb40561e4b803bc041f466ccfdc13" +dependencies = [ + "indexmap", + "toml_datetime", + "winnow", +] + +[[package]] +name = "typenum" +version = "1.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "497961ef93d974e23eb6f433eb5fe1b7930b659f06d12dec6fc44a8f554c0bba" + +[[package]] +name = "unicode-ident" +version = "1.0.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "301abaae475aa91687eb82514b328ab47a211a533026cb25fc3e519b86adfc3c" + +[[package]] +name = "unicode-normalization" +version = "0.1.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c5713f0fc4b5db668a2ac63cdb7bb4469d8c9fed047b1d0292cc7b0ce2ba921" +dependencies = [ + "tinyvec", +] + +[[package]] +name = "unicode-segmentation" +version = "1.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1dd624098567895118886609431a7c3b8f516e41d30e0643f03d94592a147e36" + +[[package]] +name = "universal-hash" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9f214e8f697e925001e66ec2c6e37a4ef93f0f78c2eed7814394e10c62025b05" +dependencies = [ + "generic-array", + "subtle", +] + +[[package]] +name = "uriparse" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0200d0fc04d809396c2ad43f3c95da3582a2556eba8d453c1087f4120ee352ff" +dependencies = [ + "fnv", + "lazy_static", +] + +[[package]] +name = "version_check" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" + +[[package]] +name = "wasi" +version = "0.9.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519" + +[[package]] +name = "wasi" +version = "0.11.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" + +[[package]] +name = "wasm-bindgen" +version = "0.2.87" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7706a72ab36d8cb1f80ffbf0e071533974a60d0a308d01a5d0375bf60499a342" +dependencies = [ + "cfg-if", + "wasm-bindgen-macro", +] + +[[package]] +name = "wasm-bindgen-backend" +version = "0.2.87" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5ef2b6d3c510e9625e5fe6f509ab07d66a760f0885d858736483c32ed7809abd" +dependencies = [ + "bumpalo", + "log", + "once_cell", + "proc-macro2", + "quote", + "syn 2.0.28", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.87" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dee495e55982a3bd48105a7b947fd2a9b4a8ae3010041b9e0faab3f9cd028f1d" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.87" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "54681b18a46765f095758388f2d0cf16eb8d4169b639ab575a8f5693af210c7b" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.28", + "wasm-bindgen-backend", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.87" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca6ad05a4870b2bf5fe995117d3728437bd27d7cd5f06f13c17443ef369775a1" + +[[package]] +name = "web-sys" +version = "0.3.64" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b85cbef8c220a6abc02aefd892dfc0fc23afb1c6a426316ec33253a3877249b" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-util" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178" +dependencies = [ + "winapi", +] + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + +[[package]] +name = "windows-targets" +version = "0.48.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05d4b17490f70499f20b9e791dcf6a299785ce8af4d709018206dc5b4953e95f" +dependencies = [ + "windows_aarch64_gnullvm", + "windows_aarch64_msvc", + "windows_i686_gnu", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91ae572e1b79dba883e0d315474df7305d12f569b400fcf90581b06062f7e1bc" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2ef27e0d7bdfcfc7b868b317c1d32c641a6fe4629c171b8928c7b08d98d7cf3" + +[[package]] +name = "windows_i686_gnu" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "622a1962a7db830d6fd0a69683c80a18fda201879f0f447f065a3b7467daa241" + +[[package]] +name = "windows_i686_msvc" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4542c6e364ce21bf45d69fdd2a8e455fa38d316158cfd43b3ac1c5b1b19f8e00" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca2b8a661f7628cbd23440e50b05d705db3686f894fc9580820623656af974b1" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7896dbc1f41e08872e9d5e8f8baa8fdd2677f29468c4e156210174edc7f7b953" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a515f5799fe4961cb532f983ce2b23082366b898e52ffbce459c86f67c8378a" + +[[package]] +name = "winnow" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae8970b36c66498d8ff1d66685dc86b91b29db0c7739899012f63a63814b4b28" +dependencies = [ + "memchr", +] + +[[package]] +name = "wormhole-anchor-sdk" +version = "0.1.0" +source = "git+https://github.com/wormhole-foundation/wormhole-scaffolding?rev=f8d5ba04bfd449ab3693b15c818fd3e85e30f758#f8d5ba04bfd449ab3693b15c818fd3e85e30f758" +dependencies = [ + "anchor-lang", + "anchor-spl", + "cfg-if", +] + +[[package]] +name = "wormhole-gateway" +version = "0.1.0" +dependencies = [ + "anchor-lang", + "anchor-spl", + "tbtc", + "wormhole-anchor-sdk", +] + +[[package]] +name = "zeroize" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4756f7db3f7b5574938c3eb1c117038b8e07f95ee6718c0efad4ac21508f1efd" +dependencies = [ + "zeroize_derive", +] + +[[package]] +name = "zeroize_derive" +version = "1.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.28", +] diff --git a/cross-chain/solana/Cargo.toml b/cross-chain/solana/Cargo.toml new file mode 100644 index 000000000..ef17a63c0 --- /dev/null +++ b/cross-chain/solana/Cargo.toml @@ -0,0 +1,13 @@ +[workspace] +members = [ + "programs/*" +] + +[profile.release] +overflow-checks = true +lto = "fat" +codegen-units = 1 +[profile.release.build-override] +opt-level = 3 +incremental = false +codegen-units = 1 diff --git a/cross-chain/solana/Makefile b/cross-chain/solana/Makefile new file mode 100644 index 000000000..6fe96802c --- /dev/null +++ b/cross-chain/solana/Makefile @@ -0,0 +1,26 @@ + +out_solana-devnet=artifacts-testnet +out_mainnet=artifacts-mainnet + +.PHONY: all clean build test + +all: test + +clean: + anchor clean + rm -rf node_modules artifacts-mainnet artifacts-testnet + +node_modules: + npm ci + +build: $(out_$(NETWORK)) + +$(out_$(NETWORK)): +ifdef out_$(NETWORK) + anchor build --arch sbf -- --features "$(NETWORK)" -- --no-default-features + mkdir -p $(out_$(NETWORK)) + cp target/deploy/*.so $(out_$(NETWORK))/ +endif + +test: node_modules + anchor test --arch sbf diff --git a/cross-chain/solana/migrations/deploy.ts b/cross-chain/solana/migrations/deploy.ts new file mode 100644 index 000000000..82fb175fa --- /dev/null +++ b/cross-chain/solana/migrations/deploy.ts @@ -0,0 +1,12 @@ +// Migrations are an early feature. Currently, they're nothing more than this +// single deploy script that's invoked from the CLI, injecting a provider +// configured from the workspace's Anchor.toml. + +const anchor = require("@coral-xyz/anchor"); + +module.exports = async function (provider) { + // Configure client to use the provider. + anchor.setProvider(provider); + + // Add your deploy script here. +}; diff --git a/cross-chain/solana/package-lock.json b/cross-chain/solana/package-lock.json new file mode 100644 index 000000000..ddcd6cb2d --- /dev/null +++ b/cross-chain/solana/package-lock.json @@ -0,0 +1,5505 @@ +{ + "name": "solana", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "dependencies": { + "@coral-xyz/anchor": "^0.28.0" + }, + "devDependencies": { + "@certusone/wormhole-sdk": "^0.9.22", + "@solana/spl-token": "^0.3.8", + "@solana/web3.js": "^1.77.3", + "@types/bn.js": "^5.1.0", + "@types/chai": "^4.3.0", + "@types/mocha": "^9.0.0", + "chai": "^4.3.4", + "mocha": "^9.0.3", + "prettier": "^2.6.2", + "ts-mocha": "^10.0.0", + "typescript": "^4.3.5" + } + }, + "node_modules/@apollo/client": { + "version": "3.7.17", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "@graphql-typed-document-node/core": "^3.1.1", + "@wry/context": "^0.7.0", + "@wry/equality": "^0.5.0", + "@wry/trie": "^0.4.0", + "graphql-tag": "^2.12.6", + "hoist-non-react-statics": "^3.3.2", + "optimism": "^0.16.2", + "prop-types": "^15.7.2", + "response-iterator": "^0.2.6", + "symbol-observable": "^4.0.0", + "ts-invariant": "^0.10.3", + "tslib": "^2.3.0", + "zen-observable-ts": "^1.2.5" + }, + "peerDependencies": { + "graphql": "^14.0.0 || ^15.0.0 || ^16.0.0", + "graphql-ws": "^5.5.5", + "react": "^16.8.0 || ^17.0.0 || ^18.0.0", + "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0", + "subscriptions-transport-ws": "^0.9.0 || ^0.11.0" + }, + "peerDependenciesMeta": { + "graphql-ws": { + "optional": true + }, + "react": { + "optional": true + }, + "react-dom": { + "optional": true + }, + "subscriptions-transport-ws": { + "optional": true + } + } + }, + "node_modules/@babel/runtime": { + "version": "7.22.6", + "license": "MIT", + "dependencies": { + "regenerator-runtime": "^0.13.11" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@certusone/wormhole-sdk": { + "version": "0.9.22", + "resolved": "https://registry.npmjs.org/@certusone/wormhole-sdk/-/wormhole-sdk-0.9.22.tgz", + "integrity": "sha512-4wZFyqqSQBtTq5S42TCrTAircnRjd0t0OZnFRyMe5qtqk96l5iDwIztKBaIccUW+XDXoGfBhSGooW15tH/IpIQ==", + "dev": true, + "dependencies": { + "@certusone/wormhole-sdk-proto-web": "0.0.6", + "@certusone/wormhole-sdk-wasm": "^0.0.1", + "@coral-xyz/borsh": "0.2.6", + "@mysten/sui.js": "0.32.2", + "@project-serum/anchor": "^0.25.0", + "@solana/spl-token": "^0.3.5", + "@solana/web3.js": "^1.66.2", + "@terra-money/terra.js": "3.1.9", + "@xpla/xpla.js": "^0.2.1", + "algosdk": "^1.15.0", + "aptos": "1.5.0", + "axios": "^0.24.0", + "bech32": "^2.0.0", + "binary-parser": "^2.2.1", + "bs58": "^4.0.1", + "elliptic": "^6.5.4", + "js-base64": "^3.6.1", + "near-api-js": "^1.0.0" + }, + "optionalDependencies": { + "@injectivelabs/networks": "1.10.12", + "@injectivelabs/sdk-ts": "1.10.72", + "@injectivelabs/utils": "1.10.12" + } + }, + "node_modules/@certusone/wormhole-sdk-proto-web": { + "version": "0.0.6", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@improbable-eng/grpc-web": "^0.15.0", + "protobufjs": "^7.0.0", + "rxjs": "^7.5.6" + } + }, + "node_modules/@certusone/wormhole-sdk-proto-web/node_modules/@improbable-eng/grpc-web": { + "version": "0.15.0", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "browser-headers": "^0.4.1" + }, + "peerDependencies": { + "google-protobuf": "^3.14.0" + } + }, + "node_modules/@certusone/wormhole-sdk-proto-web/node_modules/long": { + "version": "5.2.3", + "dev": true, + "license": "Apache-2.0" + }, + "node_modules/@certusone/wormhole-sdk-proto-web/node_modules/protobufjs": { + "version": "7.2.4", + "dev": true, + "hasInstallScript": true, + "license": "BSD-3-Clause", + "dependencies": { + "@protobufjs/aspromise": "^1.1.2", + "@protobufjs/base64": "^1.1.2", + "@protobufjs/codegen": "^2.0.4", + "@protobufjs/eventemitter": "^1.1.0", + "@protobufjs/fetch": "^1.1.0", + "@protobufjs/float": "^1.0.2", + "@protobufjs/inquire": "^1.1.0", + "@protobufjs/path": "^1.1.2", + "@protobufjs/pool": "^1.1.0", + "@protobufjs/utf8": "^1.1.0", + "@types/node": ">=13.7.0", + "long": "^5.0.0" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/@certusone/wormhole-sdk-wasm": { + "version": "0.0.1", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@types/long": "^4.0.2", + "@types/node": "^18.0.3" + } + }, + "node_modules/@certusone/wormhole-sdk-wasm/node_modules/@types/node": { + "version": "18.17.1", + "dev": true, + "license": "MIT" + }, + "node_modules/@certusone/wormhole-sdk/node_modules/@injectivelabs/networks": { + "version": "1.10.12", + "dev": true, + "hasInstallScript": true, + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "@injectivelabs/exceptions": "^1.10.12", + "@injectivelabs/ts-types": "^1.10.12", + "@injectivelabs/utils": "^1.10.12", + "link-module-alias": "^1.2.0", + "shx": "^0.3.2" + } + }, + "node_modules/@certusone/wormhole-sdk/node_modules/@injectivelabs/networks/dist": { + "extraneous": true + }, + "node_modules/@certusone/wormhole-sdk/node_modules/@injectivelabs/networks/node_modules/@injectivelabs/utils": { + "version": "1.11.0", + "dev": true, + "hasInstallScript": true, + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "@injectivelabs/exceptions": "^1.11.0", + "@injectivelabs/ts-types": "^1.11.0", + "axios": "^0.21.1", + "bignumber.js": "^9.0.1", + "http-status-codes": "^2.2.0", + "link-module-alias": "^1.2.0", + "shx": "^0.3.2", + "snakecase-keys": "^5.1.2", + "store2": "^2.12.0" + } + }, + "node_modules/@certusone/wormhole-sdk/node_modules/@injectivelabs/networks/node_modules/@injectivelabs/utils/dist": { + "extraneous": true + }, + "node_modules/@certusone/wormhole-sdk/node_modules/@injectivelabs/networks/node_modules/axios": { + "version": "0.21.4", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "follow-redirects": "^1.14.0" + } + }, + "node_modules/@certusone/wormhole-sdk/node_modules/@injectivelabs/utils": { + "version": "1.10.12", + "dev": true, + "hasInstallScript": true, + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "@injectivelabs/exceptions": "^1.10.12", + "@injectivelabs/ts-types": "^1.10.12", + "axios": "^0.21.1", + "bignumber.js": "^9.0.1", + "http-status-codes": "^2.2.0", + "link-module-alias": "^1.2.0", + "shx": "^0.3.2", + "snakecase-keys": "^5.1.2", + "store2": "^2.12.0" + } + }, + "node_modules/@certusone/wormhole-sdk/node_modules/@injectivelabs/utils/dist": { + "extraneous": true + }, + "node_modules/@certusone/wormhole-sdk/node_modules/@injectivelabs/utils/node_modules/axios": { + "version": "0.21.4", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "follow-redirects": "^1.14.0" + } + }, + "node_modules/@certusone/wormhole-sdk/node_modules/axios": { + "version": "0.24.0", + "dev": true, + "license": "MIT", + "dependencies": { + "follow-redirects": "^1.14.4" + } + }, + "node_modules/@classic-terra/terra.proto": { + "version": "1.1.0", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@improbable-eng/grpc-web": "^0.14.1", + "google-protobuf": "^3.17.3", + "long": "^4.0.0", + "protobufjs": "~6.11.2" + } + }, + "node_modules/@confio/ics23": { + "version": "0.6.8", + "dev": true, + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "@noble/hashes": "^1.0.0", + "protobufjs": "^6.8.8" + } + }, + "node_modules/@coral-xyz/anchor": { + "version": "0.28.0", + "license": "(MIT OR Apache-2.0)", + "dependencies": { + "@coral-xyz/borsh": "^0.28.0", + "@solana/web3.js": "^1.68.0", + "base64-js": "^1.5.1", + "bn.js": "^5.1.2", + "bs58": "^4.0.1", + "buffer-layout": "^1.2.2", + "camelcase": "^6.3.0", + "cross-fetch": "^3.1.5", + "crypto-hash": "^1.3.0", + "eventemitter3": "^4.0.7", + "js-sha256": "^0.9.0", + "pako": "^2.0.3", + "snake-case": "^3.0.4", + "superstruct": "^0.15.4", + "toml": "^3.0.0" + }, + "engines": { + "node": ">=11" + } + }, + "node_modules/@coral-xyz/anchor/node_modules/@coral-xyz/borsh": { + "version": "0.28.0", + "license": "Apache-2.0", + "dependencies": { + "bn.js": "^5.1.2", + "buffer-layout": "^1.2.0" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "@solana/web3.js": "^1.68.0" + } + }, + "node_modules/@coral-xyz/borsh": { + "version": "0.2.6", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "bn.js": "^5.1.2", + "buffer-layout": "^1.2.0" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "@solana/web3.js": "^1.2.0" + } + }, + "node_modules/@cosmjs/amino": { + "version": "0.30.1", + "dev": true, + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "@cosmjs/crypto": "^0.30.1", + "@cosmjs/encoding": "^0.30.1", + "@cosmjs/math": "^0.30.1", + "@cosmjs/utils": "^0.30.1" + } + }, + "node_modules/@cosmjs/crypto": { + "version": "0.30.1", + "dev": true, + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "@cosmjs/encoding": "^0.30.1", + "@cosmjs/math": "^0.30.1", + "@cosmjs/utils": "^0.30.1", + "@noble/hashes": "^1", + "bn.js": "^5.2.0", + "elliptic": "^6.5.4", + "libsodium-wrappers": "^0.7.6" + } + }, + "node_modules/@cosmjs/encoding": { + "version": "0.30.1", + "dev": true, + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "base64-js": "^1.3.0", + "bech32": "^1.1.4", + "readonly-date": "^1.0.0" + } + }, + "node_modules/@cosmjs/encoding/node_modules/bech32": { + "version": "1.1.4", + "dev": true, + "license": "MIT", + "optional": true + }, + "node_modules/@cosmjs/json-rpc": { + "version": "0.30.1", + "dev": true, + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "@cosmjs/stream": "^0.30.1", + "xstream": "^11.14.0" + } + }, + "node_modules/@cosmjs/math": { + "version": "0.30.1", + "dev": true, + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "bn.js": "^5.2.0" + } + }, + "node_modules/@cosmjs/proto-signing": { + "version": "0.30.1", + "dev": true, + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "@cosmjs/amino": "^0.30.1", + "@cosmjs/crypto": "^0.30.1", + "@cosmjs/encoding": "^0.30.1", + "@cosmjs/math": "^0.30.1", + "@cosmjs/utils": "^0.30.1", + "cosmjs-types": "^0.7.1", + "long": "^4.0.0" + } + }, + "node_modules/@cosmjs/socket": { + "version": "0.30.1", + "dev": true, + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "@cosmjs/stream": "^0.30.1", + "isomorphic-ws": "^4.0.1", + "ws": "^7", + "xstream": "^11.14.0" + } + }, + "node_modules/@cosmjs/stargate": { + "version": "0.30.1", + "dev": true, + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "@confio/ics23": "^0.6.8", + "@cosmjs/amino": "^0.30.1", + "@cosmjs/encoding": "^0.30.1", + "@cosmjs/math": "^0.30.1", + "@cosmjs/proto-signing": "^0.30.1", + "@cosmjs/stream": "^0.30.1", + "@cosmjs/tendermint-rpc": "^0.30.1", + "@cosmjs/utils": "^0.30.1", + "cosmjs-types": "^0.7.1", + "long": "^4.0.0", + "protobufjs": "~6.11.3", + "xstream": "^11.14.0" + } + }, + "node_modules/@cosmjs/stream": { + "version": "0.30.1", + "dev": true, + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "xstream": "^11.14.0" + } + }, + "node_modules/@cosmjs/tendermint-rpc": { + "version": "0.30.1", + "dev": true, + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "@cosmjs/crypto": "^0.30.1", + "@cosmjs/encoding": "^0.30.1", + "@cosmjs/json-rpc": "^0.30.1", + "@cosmjs/math": "^0.30.1", + "@cosmjs/socket": "^0.30.1", + "@cosmjs/stream": "^0.30.1", + "@cosmjs/utils": "^0.30.1", + "axios": "^0.21.2", + "readonly-date": "^1.0.0", + "xstream": "^11.14.0" + } + }, + "node_modules/@cosmjs/utils": { + "version": "0.30.1", + "dev": true, + "license": "Apache-2.0", + "optional": true + }, + "node_modules/@ethereumjs/common": { + "version": "2.6.5", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "crc-32": "^1.2.0", + "ethereumjs-util": "^7.1.5" + } + }, + "node_modules/@ethereumjs/tx": { + "version": "3.5.2", + "dev": true, + "license": "MPL-2.0", + "optional": true, + "dependencies": { + "@ethereumjs/common": "^2.6.4", + "ethereumjs-util": "^7.1.5" + } + }, + "node_modules/@ethersproject/abi": { + "version": "5.7.0", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "optional": true, + "dependencies": { + "@ethersproject/address": "^5.7.0", + "@ethersproject/bignumber": "^5.7.0", + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/constants": "^5.7.0", + "@ethersproject/hash": "^5.7.0", + "@ethersproject/keccak256": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "@ethersproject/properties": "^5.7.0", + "@ethersproject/strings": "^5.7.0" + } + }, + "node_modules/@ethersproject/abstract-provider": { + "version": "5.7.0", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "optional": true, + "dependencies": { + "@ethersproject/bignumber": "^5.7.0", + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "@ethersproject/networks": "^5.7.0", + "@ethersproject/properties": "^5.7.0", + "@ethersproject/transactions": "^5.7.0", + "@ethersproject/web": "^5.7.0" + } + }, + "node_modules/@ethersproject/abstract-signer": { + "version": "5.7.0", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "optional": true, + "dependencies": { + "@ethersproject/abstract-provider": "^5.7.0", + "@ethersproject/bignumber": "^5.7.0", + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "@ethersproject/properties": "^5.7.0" + } + }, + "node_modules/@ethersproject/address": { + "version": "5.7.0", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "optional": true, + "dependencies": { + "@ethersproject/bignumber": "^5.7.0", + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/keccak256": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "@ethersproject/rlp": "^5.7.0" + } + }, + "node_modules/@ethersproject/base64": { + "version": "5.7.0", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "optional": true, + "dependencies": { + "@ethersproject/bytes": "^5.7.0" + } + }, + "node_modules/@ethersproject/basex": { + "version": "5.7.0", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "optional": true, + "dependencies": { + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/properties": "^5.7.0" + } + }, + "node_modules/@ethersproject/bignumber": { + "version": "5.7.0", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "optional": true, + "dependencies": { + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "bn.js": "^5.2.1" + } + }, + "node_modules/@ethersproject/bytes": { + "version": "5.7.0", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/logger": "^5.7.0" + } + }, + "node_modules/@ethersproject/constants": { + "version": "5.7.0", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "optional": true, + "dependencies": { + "@ethersproject/bignumber": "^5.7.0" + } + }, + "node_modules/@ethersproject/contracts": { + "version": "5.7.0", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "optional": true, + "dependencies": { + "@ethersproject/abi": "^5.7.0", + "@ethersproject/abstract-provider": "^5.7.0", + "@ethersproject/abstract-signer": "^5.7.0", + "@ethersproject/address": "^5.7.0", + "@ethersproject/bignumber": "^5.7.0", + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/constants": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "@ethersproject/properties": "^5.7.0", + "@ethersproject/transactions": "^5.7.0" + } + }, + "node_modules/@ethersproject/hash": { + "version": "5.7.0", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "optional": true, + "dependencies": { + "@ethersproject/abstract-signer": "^5.7.0", + "@ethersproject/address": "^5.7.0", + "@ethersproject/base64": "^5.7.0", + "@ethersproject/bignumber": "^5.7.0", + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/keccak256": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "@ethersproject/properties": "^5.7.0", + "@ethersproject/strings": "^5.7.0" + } + }, + "node_modules/@ethersproject/hdnode": { + "version": "5.7.0", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "optional": true, + "dependencies": { + "@ethersproject/abstract-signer": "^5.7.0", + "@ethersproject/basex": "^5.7.0", + "@ethersproject/bignumber": "^5.7.0", + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "@ethersproject/pbkdf2": "^5.7.0", + "@ethersproject/properties": "^5.7.0", + "@ethersproject/sha2": "^5.7.0", + "@ethersproject/signing-key": "^5.7.0", + "@ethersproject/strings": "^5.7.0", + "@ethersproject/transactions": "^5.7.0", + "@ethersproject/wordlists": "^5.7.0" + } + }, + "node_modules/@ethersproject/json-wallets": { + "version": "5.7.0", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "optional": true, + "dependencies": { + "@ethersproject/abstract-signer": "^5.7.0", + "@ethersproject/address": "^5.7.0", + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/hdnode": "^5.7.0", + "@ethersproject/keccak256": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "@ethersproject/pbkdf2": "^5.7.0", + "@ethersproject/properties": "^5.7.0", + "@ethersproject/random": "^5.7.0", + "@ethersproject/strings": "^5.7.0", + "@ethersproject/transactions": "^5.7.0", + "aes-js": "3.0.0", + "scrypt-js": "3.0.1" + } + }, + "node_modules/@ethersproject/keccak256": { + "version": "5.7.0", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/bytes": "^5.7.0", + "js-sha3": "0.8.0" + } + }, + "node_modules/@ethersproject/logger": { + "version": "5.7.0", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT" + }, + "node_modules/@ethersproject/networks": { + "version": "5.7.1", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "optional": true, + "dependencies": { + "@ethersproject/logger": "^5.7.0" + } + }, + "node_modules/@ethersproject/pbkdf2": { + "version": "5.7.0", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "optional": true, + "dependencies": { + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/sha2": "^5.7.0" + } + }, + "node_modules/@ethersproject/properties": { + "version": "5.7.0", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/logger": "^5.7.0" + } + }, + "node_modules/@ethersproject/providers": { + "version": "5.7.2", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "optional": true, + "dependencies": { + "@ethersproject/abstract-provider": "^5.7.0", + "@ethersproject/abstract-signer": "^5.7.0", + "@ethersproject/address": "^5.7.0", + "@ethersproject/base64": "^5.7.0", + "@ethersproject/basex": "^5.7.0", + "@ethersproject/bignumber": "^5.7.0", + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/constants": "^5.7.0", + "@ethersproject/hash": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "@ethersproject/networks": "^5.7.0", + "@ethersproject/properties": "^5.7.0", + "@ethersproject/random": "^5.7.0", + "@ethersproject/rlp": "^5.7.0", + "@ethersproject/sha2": "^5.7.0", + "@ethersproject/strings": "^5.7.0", + "@ethersproject/transactions": "^5.7.0", + "@ethersproject/web": "^5.7.0", + "bech32": "1.1.4", + "ws": "7.4.6" + } + }, + "node_modules/@ethersproject/providers/node_modules/bech32": { + "version": "1.1.4", + "dev": true, + "license": "MIT", + "optional": true + }, + "node_modules/@ethersproject/providers/node_modules/ws": { + "version": "7.4.6", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">=8.3.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": "^5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "node_modules/@ethersproject/random": { + "version": "5.7.0", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "optional": true, + "dependencies": { + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/logger": "^5.7.0" + } + }, + "node_modules/@ethersproject/rlp": { + "version": "5.7.0", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "optional": true, + "dependencies": { + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/logger": "^5.7.0" + } + }, + "node_modules/@ethersproject/sha2": { + "version": "5.7.0", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "optional": true, + "dependencies": { + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "hash.js": "1.1.7" + } + }, + "node_modules/@ethersproject/signing-key": { + "version": "5.7.0", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "@ethersproject/properties": "^5.7.0", + "bn.js": "^5.2.1", + "elliptic": "6.5.4", + "hash.js": "1.1.7" + } + }, + "node_modules/@ethersproject/solidity": { + "version": "5.7.0", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "optional": true, + "dependencies": { + "@ethersproject/bignumber": "^5.7.0", + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/keccak256": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "@ethersproject/sha2": "^5.7.0", + "@ethersproject/strings": "^5.7.0" + } + }, + "node_modules/@ethersproject/strings": { + "version": "5.7.0", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "optional": true, + "dependencies": { + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/constants": "^5.7.0", + "@ethersproject/logger": "^5.7.0" + } + }, + "node_modules/@ethersproject/transactions": { + "version": "5.7.0", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "optional": true, + "dependencies": { + "@ethersproject/address": "^5.7.0", + "@ethersproject/bignumber": "^5.7.0", + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/constants": "^5.7.0", + "@ethersproject/keccak256": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "@ethersproject/properties": "^5.7.0", + "@ethersproject/rlp": "^5.7.0", + "@ethersproject/signing-key": "^5.7.0" + } + }, + "node_modules/@ethersproject/units": { + "version": "5.7.0", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "optional": true, + "dependencies": { + "@ethersproject/bignumber": "^5.7.0", + "@ethersproject/constants": "^5.7.0", + "@ethersproject/logger": "^5.7.0" + } + }, + "node_modules/@ethersproject/wallet": { + "version": "5.7.0", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "optional": true, + "dependencies": { + "@ethersproject/abstract-provider": "^5.7.0", + "@ethersproject/abstract-signer": "^5.7.0", + "@ethersproject/address": "^5.7.0", + "@ethersproject/bignumber": "^5.7.0", + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/hash": "^5.7.0", + "@ethersproject/hdnode": "^5.7.0", + "@ethersproject/json-wallets": "^5.7.0", + "@ethersproject/keccak256": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "@ethersproject/properties": "^5.7.0", + "@ethersproject/random": "^5.7.0", + "@ethersproject/signing-key": "^5.7.0", + "@ethersproject/transactions": "^5.7.0", + "@ethersproject/wordlists": "^5.7.0" + } + }, + "node_modules/@ethersproject/web": { + "version": "5.7.1", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "optional": true, + "dependencies": { + "@ethersproject/base64": "^5.7.0", + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "@ethersproject/properties": "^5.7.0", + "@ethersproject/strings": "^5.7.0" + } + }, + "node_modules/@ethersproject/wordlists": { + "version": "5.7.0", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "optional": true, + "dependencies": { + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/hash": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "@ethersproject/properties": "^5.7.0", + "@ethersproject/strings": "^5.7.0" + } + }, + "node_modules/@graphql-typed-document-node/core": { + "version": "3.2.0", + "dev": true, + "license": "MIT", + "optional": true, + "peerDependencies": { + "graphql": "^0.8.0 || ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0" + } + }, + "node_modules/@improbable-eng/grpc-web": { + "version": "0.14.1", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "browser-headers": "^0.4.1" + }, + "peerDependencies": { + "google-protobuf": "^3.14.0" + } + }, + "node_modules/@injectivelabs/core-proto-ts": { + "version": "0.0.14", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "@injectivelabs/grpc-web": "^0.0.1", + "google-protobuf": "^3.14.0", + "protobufjs": "^7.0.0", + "rxjs": "^7.4.0" + } + }, + "node_modules/@injectivelabs/core-proto-ts/node_modules/long": { + "version": "5.2.3", + "dev": true, + "license": "Apache-2.0", + "optional": true + }, + "node_modules/@injectivelabs/core-proto-ts/node_modules/protobufjs": { + "version": "7.2.4", + "dev": true, + "hasInstallScript": true, + "license": "BSD-3-Clause", + "optional": true, + "dependencies": { + "@protobufjs/aspromise": "^1.1.2", + "@protobufjs/base64": "^1.1.2", + "@protobufjs/codegen": "^2.0.4", + "@protobufjs/eventemitter": "^1.1.0", + "@protobufjs/fetch": "^1.1.0", + "@protobufjs/float": "^1.0.2", + "@protobufjs/inquire": "^1.1.0", + "@protobufjs/path": "^1.1.2", + "@protobufjs/pool": "^1.1.0", + "@protobufjs/utf8": "^1.1.0", + "@types/node": ">=13.7.0", + "long": "^5.0.0" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/@injectivelabs/exceptions": { + "version": "1.11.0", + "dev": true, + "hasInstallScript": true, + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "@injectivelabs/grpc-web": "^0.0.1", + "@injectivelabs/ts-types": "^1.11.0", + "http-status-codes": "^2.2.0", + "link-module-alias": "^1.2.0", + "shx": "^0.3.2" + } + }, + "node_modules/@injectivelabs/exceptions/dist": { + "extraneous": true + }, + "node_modules/@injectivelabs/grpc-web": { + "version": "0.0.1", + "dev": true, + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "browser-headers": "^0.4.1" + }, + "peerDependencies": { + "google-protobuf": "^3.14.0" + } + }, + "node_modules/@injectivelabs/grpc-web-node-http-transport": { + "version": "0.0.2", + "dev": true, + "license": "Apache-2.0", + "optional": true, + "peerDependencies": { + "@injectivelabs/grpc-web": ">=0.0.1" + } + }, + "node_modules/@injectivelabs/grpc-web-react-native-transport": { + "version": "0.0.2", + "dev": true, + "license": "Apache-2.0", + "optional": true, + "peerDependencies": { + "@injectivelabs/grpc-web": ">=0.0.1" + } + }, + "node_modules/@injectivelabs/indexer-proto-ts": { + "version": "1.10.8-rc.4", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "@injectivelabs/grpc-web": "^0.0.1", + "google-protobuf": "^3.14.0", + "protobufjs": "^7.0.0", + "rxjs": "^7.4.0" + } + }, + "node_modules/@injectivelabs/indexer-proto-ts/node_modules/long": { + "version": "5.2.3", + "dev": true, + "license": "Apache-2.0", + "optional": true + }, + "node_modules/@injectivelabs/indexer-proto-ts/node_modules/protobufjs": { + "version": "7.2.4", + "dev": true, + "hasInstallScript": true, + "license": "BSD-3-Clause", + "optional": true, + "dependencies": { + "@protobufjs/aspromise": "^1.1.2", + "@protobufjs/base64": "^1.1.2", + "@protobufjs/codegen": "^2.0.4", + "@protobufjs/eventemitter": "^1.1.0", + "@protobufjs/fetch": "^1.1.0", + "@protobufjs/float": "^1.0.2", + "@protobufjs/inquire": "^1.1.0", + "@protobufjs/path": "^1.1.2", + "@protobufjs/pool": "^1.1.0", + "@protobufjs/utf8": "^1.1.0", + "@types/node": ">=13.7.0", + "long": "^5.0.0" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/@injectivelabs/mito-proto-ts": { + "version": "1.0.9", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "@injectivelabs/grpc-web": "^0.0.1", + "google-protobuf": "^3.14.0", + "protobufjs": "^7.0.0", + "rxjs": "^7.4.0" + } + }, + "node_modules/@injectivelabs/mito-proto-ts/node_modules/long": { + "version": "5.2.3", + "dev": true, + "license": "Apache-2.0", + "optional": true + }, + "node_modules/@injectivelabs/mito-proto-ts/node_modules/protobufjs": { + "version": "7.2.4", + "dev": true, + "hasInstallScript": true, + "license": "BSD-3-Clause", + "optional": true, + "dependencies": { + "@protobufjs/aspromise": "^1.1.2", + "@protobufjs/base64": "^1.1.2", + "@protobufjs/codegen": "^2.0.4", + "@protobufjs/eventemitter": "^1.1.0", + "@protobufjs/fetch": "^1.1.0", + "@protobufjs/float": "^1.0.2", + "@protobufjs/inquire": "^1.1.0", + "@protobufjs/path": "^1.1.2", + "@protobufjs/pool": "^1.1.0", + "@protobufjs/utf8": "^1.1.0", + "@types/node": ">=13.7.0", + "long": "^5.0.0" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/@injectivelabs/networks": { + "version": "1.11.0", + "dev": true, + "hasInstallScript": true, + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "@injectivelabs/exceptions": "^1.11.0", + "@injectivelabs/ts-types": "^1.11.0", + "@injectivelabs/utils": "^1.11.0", + "link-module-alias": "^1.2.0", + "shx": "^0.3.2" + } + }, + "node_modules/@injectivelabs/networks/dist": { + "extraneous": true + }, + "node_modules/@injectivelabs/sdk-ts": { + "version": "1.10.72", + "dev": true, + "hasInstallScript": true, + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "@apollo/client": "^3.5.8", + "@cosmjs/amino": "^0.30.1", + "@cosmjs/proto-signing": "^0.30.1", + "@cosmjs/stargate": "^0.30.1", + "@ethersproject/bytes": "^5.7.0", + "@injectivelabs/core-proto-ts": "^0.0.14", + "@injectivelabs/exceptions": "^1.10.12", + "@injectivelabs/grpc-web": "^0.0.1", + "@injectivelabs/grpc-web-node-http-transport": "^0.0.2", + "@injectivelabs/grpc-web-react-native-transport": "^0.0.2", + "@injectivelabs/indexer-proto-ts": "1.10.8-rc.4", + "@injectivelabs/mito-proto-ts": "1.0.9", + "@injectivelabs/networks": "^1.10.12", + "@injectivelabs/test-utils": "^1.10.12", + "@injectivelabs/token-metadata": "^1.10.42", + "@injectivelabs/ts-types": "^1.10.12", + "@injectivelabs/utils": "^1.10.12", + "@metamask/eth-sig-util": "^4.0.0", + "axios": "^0.27.2", + "bech32": "^2.0.0", + "bip39": "^3.0.4", + "cosmjs-types": "^0.7.1", + "eth-crypto": "^2.6.0", + "ethereumjs-util": "^7.1.4", + "ethers": "^5.7.2", + "google-protobuf": "^3.21.0", + "graphql": "^16.3.0", + "http-status-codes": "^2.2.0", + "js-sha3": "^0.8.0", + "jscrypto": "^1.0.3", + "keccak256": "^1.0.6", + "link-module-alias": "^1.2.0", + "rxjs": "^7.8.0", + "secp256k1": "^4.0.3", + "shx": "^0.3.2", + "snakecase-keys": "^5.4.1" + } + }, + "node_modules/@injectivelabs/sdk-ts/dist": { + "extraneous": true + }, + "node_modules/@injectivelabs/sdk-ts/node_modules/axios": { + "version": "0.27.2", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "follow-redirects": "^1.14.9", + "form-data": "^4.0.0" + } + }, + "node_modules/@injectivelabs/test-utils": { + "version": "1.11.0", + "dev": true, + "hasInstallScript": true, + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "axios": "^0.21.1", + "bignumber.js": "^9.0.1", + "link-module-alias": "^1.2.0", + "shx": "^0.3.2", + "snakecase-keys": "^5.1.2", + "store2": "^2.12.0" + } + }, + "node_modules/@injectivelabs/test-utils/dist": { + "extraneous": true + }, + "node_modules/@injectivelabs/token-metadata": { + "version": "1.11.0", + "dev": true, + "hasInstallScript": true, + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "@injectivelabs/exceptions": "^1.11.0", + "@injectivelabs/networks": "^1.11.0", + "@injectivelabs/ts-types": "^1.11.0", + "@injectivelabs/utils": "^1.11.0", + "@types/lodash.values": "^4.3.6", + "copyfiles": "^2.4.1", + "jsonschema": "^1.4.0", + "link-module-alias": "^1.2.0", + "lodash": "^4.17.21", + "lodash.values": "^4.3.0", + "shx": "^0.3.2" + } + }, + "node_modules/@injectivelabs/token-metadata/dist": { + "extraneous": true + }, + "node_modules/@injectivelabs/ts-types": { + "version": "1.11.0", + "dev": true, + "hasInstallScript": true, + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "link-module-alias": "^1.2.0", + "shx": "^0.3.2" + } + }, + "node_modules/@injectivelabs/ts-types/dist": { + "extraneous": true + }, + "node_modules/@injectivelabs/utils": { + "version": "1.11.0", + "dev": true, + "hasInstallScript": true, + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "@injectivelabs/exceptions": "^1.11.0", + "@injectivelabs/ts-types": "^1.11.0", + "axios": "^0.21.1", + "bignumber.js": "^9.0.1", + "http-status-codes": "^2.2.0", + "link-module-alias": "^1.2.0", + "shx": "^0.3.2", + "snakecase-keys": "^5.1.2", + "store2": "^2.12.0" + } + }, + "node_modules/@injectivelabs/utils/dist": { + "extraneous": true + }, + "node_modules/@metamask/eth-sig-util": { + "version": "4.0.1", + "dev": true, + "license": "ISC", + "optional": true, + "dependencies": { + "ethereumjs-abi": "^0.6.8", + "ethereumjs-util": "^6.2.1", + "ethjs-util": "^0.1.6", + "tweetnacl": "^1.0.3", + "tweetnacl-util": "^0.15.1" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/@metamask/eth-sig-util/node_modules/@types/bn.js": { + "version": "4.11.6", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@metamask/eth-sig-util/node_modules/bn.js": { + "version": "4.12.0", + "dev": true, + "license": "MIT", + "optional": true + }, + "node_modules/@metamask/eth-sig-util/node_modules/ethereumjs-util": { + "version": "6.2.1", + "dev": true, + "license": "MPL-2.0", + "optional": true, + "dependencies": { + "@types/bn.js": "^4.11.3", + "bn.js": "^4.11.0", + "create-hash": "^1.1.2", + "elliptic": "^6.5.2", + "ethereum-cryptography": "^0.1.3", + "ethjs-util": "0.1.6", + "rlp": "^2.2.3" + } + }, + "node_modules/@mysten/bcs": { + "version": "0.7.1", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "bs58": "^5.0.0" + } + }, + "node_modules/@mysten/bcs/node_modules/base-x": { + "version": "4.0.0", + "dev": true, + "license": "MIT" + }, + "node_modules/@mysten/bcs/node_modules/bs58": { + "version": "5.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "base-x": "^4.0.0" + } + }, + "node_modules/@mysten/sui.js": { + "version": "0.32.2", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@mysten/bcs": "0.7.1", + "@noble/curves": "^1.0.0", + "@noble/hashes": "^1.3.0", + "@scure/bip32": "^1.3.0", + "@scure/bip39": "^1.2.0", + "@suchipi/femver": "^1.0.0", + "jayson": "^4.0.0", + "rpc-websockets": "^7.5.1", + "superstruct": "^1.0.3", + "tweetnacl": "^1.0.3" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/@mysten/sui.js/node_modules/@scure/bip39": { + "version": "1.2.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@noble/hashes": "~1.3.0", + "@scure/base": "~1.1.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@mysten/sui.js/node_modules/superstruct": { + "version": "1.0.3", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@noble/curves": { + "version": "1.1.0", + "license": "MIT", + "dependencies": { + "@noble/hashes": "1.3.1" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@noble/hashes": { + "version": "1.3.1", + "license": "MIT", + "engines": { + "node": ">= 16" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@project-serum/anchor": { + "version": "0.25.0", + "dev": true, + "license": "(MIT OR Apache-2.0)", + "dependencies": { + "@project-serum/borsh": "^0.2.5", + "@solana/web3.js": "^1.36.0", + "base64-js": "^1.5.1", + "bn.js": "^5.1.2", + "bs58": "^4.0.1", + "buffer-layout": "^1.2.2", + "camelcase": "^5.3.1", + "cross-fetch": "^3.1.5", + "crypto-hash": "^1.3.0", + "eventemitter3": "^4.0.7", + "js-sha256": "^0.9.0", + "pako": "^2.0.3", + "snake-case": "^3.0.4", + "superstruct": "^0.15.4", + "toml": "^3.0.0" + }, + "engines": { + "node": ">=11" + } + }, + "node_modules/@project-serum/anchor/node_modules/camelcase": { + "version": "5.3.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/@project-serum/borsh": { + "version": "0.2.5", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "bn.js": "^5.1.2", + "buffer-layout": "^1.2.0" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "@solana/web3.js": "^1.2.0" + } + }, + "node_modules/@protobufjs/aspromise": { + "version": "1.1.2", + "dev": true, + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/base64": { + "version": "1.1.2", + "dev": true, + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/codegen": { + "version": "2.0.4", + "dev": true, + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/eventemitter": { + "version": "1.1.0", + "dev": true, + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/fetch": { + "version": "1.1.0", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "@protobufjs/aspromise": "^1.1.1", + "@protobufjs/inquire": "^1.1.0" + } + }, + "node_modules/@protobufjs/float": { + "version": "1.0.2", + "dev": true, + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/inquire": { + "version": "1.1.0", + "dev": true, + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/path": { + "version": "1.1.2", + "dev": true, + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/pool": { + "version": "1.1.0", + "dev": true, + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/utf8": { + "version": "1.1.0", + "dev": true, + "license": "BSD-3-Clause" + }, + "node_modules/@scure/base": { + "version": "1.1.1", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + ], + "license": "MIT" + }, + "node_modules/@scure/bip32": { + "version": "1.3.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@noble/curves": "~1.1.0", + "@noble/hashes": "~1.3.1", + "@scure/base": "~1.1.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@scure/bip39": { + "version": "1.1.0", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + ], + "license": "MIT", + "dependencies": { + "@noble/hashes": "~1.1.1", + "@scure/base": "~1.1.0" + } + }, + "node_modules/@scure/bip39/node_modules/@noble/hashes": { + "version": "1.1.5", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + ], + "license": "MIT" + }, + "node_modules/@solana/buffer-layout": { + "version": "4.0.1", + "license": "MIT", + "dependencies": { + "buffer": "~6.0.3" + }, + "engines": { + "node": ">=5.10" + } + }, + "node_modules/@solana/buffer-layout-utils": { + "version": "0.2.0", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@solana/buffer-layout": "^4.0.0", + "@solana/web3.js": "^1.32.0", + "bigint-buffer": "^1.1.5", + "bignumber.js": "^9.0.1" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/@solana/spl-token": { + "version": "0.3.8", + "resolved": "https://registry.npmjs.org/@solana/spl-token/-/spl-token-0.3.8.tgz", + "integrity": "sha512-ogwGDcunP9Lkj+9CODOWMiVJEdRtqHAtX2rWF62KxnnSWtMZtV9rDhTrZFshiyJmxDnRL/1nKE1yJHg4jjs3gg==", + "dev": true, + "dependencies": { + "@solana/buffer-layout": "^4.0.0", + "@solana/buffer-layout-utils": "^0.2.0", + "buffer": "^6.0.3" + }, + "engines": { + "node": ">=16" + }, + "peerDependencies": { + "@solana/web3.js": "^1.47.4" + } + }, + "node_modules/@solana/web3.js": { + "version": "1.78.2", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.22.6", + "@noble/curves": "^1.0.0", + "@noble/hashes": "^1.3.0", + "@solana/buffer-layout": "^4.0.0", + "agentkeepalive": "^4.2.1", + "bigint-buffer": "^1.1.5", + "bn.js": "^5.2.1", + "borsh": "^0.7.0", + "bs58": "^4.0.1", + "buffer": "6.0.3", + "fast-stable-stringify": "^1.0.0", + "jayson": "^4.1.0", + "node-fetch": "^2.6.12", + "rpc-websockets": "^7.5.1", + "superstruct": "^0.14.2" + } + }, + "node_modules/@solana/web3.js/node_modules/superstruct": { + "version": "0.14.2", + "license": "MIT" + }, + "node_modules/@suchipi/femver": { + "version": "1.0.0", + "dev": true, + "license": "MIT" + }, + "node_modules/@terra-money/legacy.proto": { + "name": "@terra-money/terra.proto", + "version": "0.1.7", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "google-protobuf": "^3.17.3", + "long": "^4.0.0", + "protobufjs": "~6.11.2" + } + }, + "node_modules/@terra-money/terra.js": { + "version": "3.1.9", + "dev": true, + "license": "MIT", + "dependencies": { + "@classic-terra/terra.proto": "^1.1.0", + "@terra-money/terra.proto": "^2.1.0", + "axios": "^0.27.2", + "bech32": "^2.0.0", + "bip32": "^2.0.6", + "bip39": "^3.0.3", + "bufferutil": "^4.0.3", + "decimal.js": "^10.2.1", + "jscrypto": "^1.0.1", + "readable-stream": "^3.6.0", + "secp256k1": "^4.0.2", + "tmp": "^0.2.1", + "utf-8-validate": "^5.0.5", + "ws": "^7.5.9" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/@terra-money/terra.js/node_modules/axios": { + "version": "0.27.2", + "dev": true, + "license": "MIT", + "dependencies": { + "follow-redirects": "^1.14.9", + "form-data": "^4.0.0" + } + }, + "node_modules/@terra-money/terra.proto": { + "version": "2.1.0", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@improbable-eng/grpc-web": "^0.14.1", + "google-protobuf": "^3.17.3", + "long": "^4.0.0", + "protobufjs": "~6.11.2" + } + }, + "node_modules/@types/bn.js": { + "version": "5.1.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/chai": { + "version": "4.3.5", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/connect": { + "version": "3.4.35", + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/json5": { + "version": "0.0.29", + "dev": true, + "license": "MIT", + "optional": true + }, + "node_modules/@types/lodash": { + "version": "4.14.196", + "dev": true, + "license": "MIT", + "optional": true + }, + "node_modules/@types/lodash.values": { + "version": "4.3.7", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "@types/lodash": "*" + } + }, + "node_modules/@types/long": { + "version": "4.0.2", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/mocha": { + "version": "9.1.1", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/node": { + "version": "20.4.5", + "license": "MIT" + }, + "node_modules/@types/pbkdf2": { + "version": "3.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/secp256k1": { + "version": "4.0.3", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/ws": { + "version": "7.4.7", + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@ungap/promise-all-settled": { + "version": "1.1.2", + "dev": true, + "license": "ISC" + }, + "node_modules/@wry/context": { + "version": "0.7.3", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.3.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@wry/equality": { + "version": "0.5.6", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.3.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@wry/trie": { + "version": "0.4.3", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.3.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@xpla/xpla.js": { + "version": "0.2.3", + "dev": true, + "license": "MIT", + "dependencies": { + "@ethersproject/bytes": "^5.6.1", + "@ethersproject/keccak256": "^5.6.1", + "@ethersproject/signing-key": "^5.6.2", + "@terra-money/legacy.proto": "npm:@terra-money/terra.proto@^0.1.7", + "@terra-money/terra.proto": "^2.1.0", + "axios": "^0.26.1", + "bech32": "^2.0.0", + "bip32": "^2.0.6", + "bip39": "^3.0.3", + "bufferutil": "^4.0.3", + "crypto-addr-codec": "^0.1.7", + "decimal.js": "^10.2.1", + "elliptic": "^6.5.4", + "ethereumjs-util": "^7.1.5", + "jscrypto": "^1.0.1", + "readable-stream": "^3.6.0", + "secp256k1": "^4.0.2", + "tmp": "^0.2.1", + "utf-8-validate": "^5.0.5", + "ws": "^7.5.8" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/@xpla/xpla.js/node_modules/axios": { + "version": "0.26.1", + "dev": true, + "license": "MIT", + "dependencies": { + "follow-redirects": "^1.14.8" + } + }, + "node_modules/acorn": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.1.1.tgz", + "integrity": "sha512-add7dgA5ppRPxCFJoAGfMDi7PIBXq1RtGo7BhbLaxwrXPOmw8gq48Y9ozT01hUKy9byMjlR20EJhu5zlkErEkg==", + "dev": true, + "optional": true, + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/aes-js": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "optional": true + }, + "node_modules/agentkeepalive": { + "version": "4.3.0", + "license": "MIT", + "dependencies": { + "debug": "^4.1.0", + "depd": "^2.0.0", + "humanize-ms": "^1.2.1" + }, + "engines": { + "node": ">= 8.0.0" + } + }, + "node_modules/agentkeepalive/node_modules/debug": { + "version": "4.3.4", + "license": "MIT", + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/algo-msgpack-with-bigint": { + "version": "2.1.1", + "dev": true, + "license": "ISC", + "engines": { + "node": ">= 10" + } + }, + "node_modules/algosdk": { + "version": "1.24.1", + "dev": true, + "license": "MIT", + "dependencies": { + "algo-msgpack-with-bigint": "^2.1.1", + "buffer": "^6.0.2", + "cross-fetch": "^3.1.5", + "hi-base32": "^0.5.1", + "js-sha256": "^0.9.0", + "js-sha3": "^0.8.0", + "js-sha512": "^0.8.0", + "json-bigint": "^1.0.0", + "tweetnacl": "^1.0.3", + "vlq": "^2.0.4" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/ansi-colors": { + "version": "4.1.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/ansi-regex": { + "version": "5.0.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-styles": { + "version": "4.3.0", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/anymatch": { + "version": "3.1.3", + "dev": true, + "license": "ISC", + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/aptos": { + "version": "1.5.0", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@noble/hashes": "1.1.3", + "@scure/bip39": "1.1.0", + "axios": "0.27.2", + "form-data": "4.0.0", + "tweetnacl": "1.0.3" + }, + "engines": { + "node": ">=11.0.0" + } + }, + "node_modules/aptos/node_modules/@noble/hashes": { + "version": "1.1.3", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + ], + "license": "MIT" + }, + "node_modules/aptos/node_modules/axios": { + "version": "0.27.2", + "dev": true, + "license": "MIT", + "dependencies": { + "follow-redirects": "^1.14.9", + "form-data": "^4.0.0" + } + }, + "node_modules/argparse": { + "version": "2.0.1", + "dev": true, + "license": "Python-2.0" + }, + "node_modules/arrify": { + "version": "1.0.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/assertion-error": { + "version": "1.1.0", + "dev": true, + "license": "MIT", + "engines": { + "node": "*" + } + }, + "node_modules/asynckit": { + "version": "0.4.0", + "dev": true, + "license": "MIT" + }, + "node_modules/axios": { + "version": "0.21.4", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "follow-redirects": "^1.14.0" + } + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "dev": true, + "license": "MIT" + }, + "node_modules/base-x": { + "version": "3.0.9", + "license": "MIT", + "dependencies": { + "safe-buffer": "^5.0.1" + } + }, + "node_modules/base64-js": { + "version": "1.5.1", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/bech32": { + "version": "2.0.0", + "dev": true, + "license": "MIT" + }, + "node_modules/big-integer": { + "version": "1.6.36", + "dev": true, + "license": "Unlicense", + "engines": { + "node": ">=0.6" + } + }, + "node_modules/bigint-buffer": { + "version": "1.1.5", + "hasInstallScript": true, + "license": "Apache-2.0", + "dependencies": { + "bindings": "^1.3.0" + }, + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/bignumber.js": { + "version": "9.1.1", + "dev": true, + "license": "MIT", + "engines": { + "node": "*" + } + }, + "node_modules/binary-extensions": { + "version": "2.2.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/binary-parser": { + "version": "2.2.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + } + }, + "node_modules/bindings": { + "version": "1.5.0", + "license": "MIT", + "dependencies": { + "file-uri-to-path": "1.0.0" + } + }, + "node_modules/bip32": { + "version": "2.0.6", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "10.12.18", + "bs58check": "^2.1.1", + "create-hash": "^1.2.0", + "create-hmac": "^1.1.7", + "tiny-secp256k1": "^1.1.3", + "typeforce": "^1.11.5", + "wif": "^2.0.6" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/bip32/node_modules/@types/node": { + "version": "10.12.18", + "dev": true, + "license": "MIT" + }, + "node_modules/bip39": { + "version": "3.1.0", + "dev": true, + "license": "ISC", + "dependencies": { + "@noble/hashes": "^1.2.0" + } + }, + "node_modules/bip66": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/bip66/-/bip66-1.1.5.tgz", + "integrity": "sha512-nemMHz95EmS38a26XbbdxIYj5csHd3RMP3H5bwQknX0WYHF01qhpufP42mLOwVICuH2JmhIhXiWs89MfUGL7Xw==", + "dev": true, + "optional": true, + "dependencies": { + "safe-buffer": "^5.0.1" + } + }, + "node_modules/blakejs": { + "version": "1.2.1", + "dev": true, + "license": "MIT" + }, + "node_modules/bn.js": { + "version": "5.2.1", + "license": "MIT" + }, + "node_modules/borsh": { + "version": "0.7.0", + "license": "Apache-2.0", + "dependencies": { + "bn.js": "^5.2.0", + "bs58": "^4.0.0", + "text-encoding-utf-8": "^1.0.2" + } + }, + "node_modules/brace-expansion": { + "version": "1.1.11", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/braces": { + "version": "3.0.2", + "dev": true, + "license": "MIT", + "dependencies": { + "fill-range": "^7.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/brorand": { + "version": "1.1.0", + "dev": true, + "license": "MIT" + }, + "node_modules/browser-headers": { + "version": "0.4.1", + "dev": true, + "license": "Apache-2.0" + }, + "node_modules/browser-stdout": { + "version": "1.3.1", + "dev": true, + "license": "ISC" + }, + "node_modules/browserify-aes": { + "version": "1.2.0", + "dev": true, + "license": "MIT", + "dependencies": { + "buffer-xor": "^1.0.3", + "cipher-base": "^1.0.0", + "create-hash": "^1.1.0", + "evp_bytestokey": "^1.0.3", + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "node_modules/bs58": { + "version": "4.0.1", + "license": "MIT", + "dependencies": { + "base-x": "^3.0.2" + } + }, + "node_modules/bs58check": { + "version": "2.1.2", + "dev": true, + "license": "MIT", + "dependencies": { + "bs58": "^4.0.0", + "create-hash": "^1.1.0", + "safe-buffer": "^5.1.2" + } + }, + "node_modules/buffer": { + "version": "6.0.3", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.2.1" + } + }, + "node_modules/buffer-from": { + "version": "1.1.2", + "dev": true, + "license": "MIT" + }, + "node_modules/buffer-layout": { + "version": "1.2.2", + "license": "MIT", + "engines": { + "node": ">=4.5" + } + }, + "node_modules/buffer-xor": { + "version": "1.0.3", + "dev": true, + "license": "MIT" + }, + "node_modules/bufferutil": { + "version": "4.0.7", + "devOptional": true, + "hasInstallScript": true, + "license": "MIT", + "dependencies": { + "node-gyp-build": "^4.3.0" + }, + "engines": { + "node": ">=6.14.2" + } + }, + "node_modules/camelcase": { + "version": "6.3.0", + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/capability": { + "version": "0.2.5", + "dev": true, + "license": "MIT" + }, + "node_modules/chai": { + "version": "4.3.7", + "dev": true, + "license": "MIT", + "dependencies": { + "assertion-error": "^1.1.0", + "check-error": "^1.0.2", + "deep-eql": "^4.1.2", + "get-func-name": "^2.0.0", + "loupe": "^2.3.1", + "pathval": "^1.1.1", + "type-detect": "^4.0.5" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/chalk": { + "version": "2.4.2", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/chalk/node_modules/ansi-styles": { + "version": "3.2.1", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/chalk/node_modules/color-convert": { + "version": "1.9.3", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/chalk/node_modules/color-name": { + "version": "1.1.3", + "dev": true, + "license": "MIT", + "optional": true + }, + "node_modules/chalk/node_modules/escape-string-regexp": { + "version": "1.0.5", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/chalk/node_modules/has-flag": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/chalk/node_modules/supports-color": { + "version": "5.5.0", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/check-error": { + "version": "1.0.2", + "dev": true, + "license": "MIT", + "engines": { + "node": "*" + } + }, + "node_modules/chokidar": { + "version": "3.5.3", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + ], + "license": "MIT", + "dependencies": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + }, + "engines": { + "node": ">= 8.10.0" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/cipher-base": { + "version": "1.0.4", + "dev": true, + "license": "MIT", + "dependencies": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "node_modules/cliui": { + "version": "7.0.4", + "dev": true, + "license": "ISC", + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^7.0.0" + } + }, + "node_modules/color-convert": { + "version": "2.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "dev": true, + "license": "MIT" + }, + "node_modules/combined-stream": { + "version": "1.0.8", + "dev": true, + "license": "MIT", + "dependencies": { + "delayed-stream": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/commander": { + "version": "2.20.3", + "license": "MIT" + }, + "node_modules/concat-map": { + "version": "0.0.1", + "dev": true, + "license": "MIT" + }, + "node_modules/copyfiles": { + "version": "2.4.1", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "glob": "^7.0.5", + "minimatch": "^3.0.3", + "mkdirp": "^1.0.4", + "noms": "0.0.0", + "through2": "^2.0.1", + "untildify": "^4.0.0", + "yargs": "^16.1.0" + }, + "bin": { + "copyfiles": "copyfiles", + "copyup": "copyfiles" + } + }, + "node_modules/copyfiles/node_modules/mkdirp": { + "version": "1.0.4", + "dev": true, + "license": "MIT", + "optional": true, + "bin": { + "mkdirp": "bin/cmd.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/core-util-is": { + "version": "1.0.3", + "dev": true, + "license": "MIT", + "optional": true + }, + "node_modules/cosmjs-types": { + "version": "0.7.2", + "dev": true, + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "long": "^4.0.0", + "protobufjs": "~6.11.2" + } + }, + "node_modules/crc-32": { + "version": "1.2.2", + "dev": true, + "license": "Apache-2.0", + "optional": true, + "bin": { + "crc32": "bin/crc32.njs" + }, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/create-hash": { + "version": "1.2.0", + "dev": true, + "license": "MIT", + "dependencies": { + "cipher-base": "^1.0.1", + "inherits": "^2.0.1", + "md5.js": "^1.3.4", + "ripemd160": "^2.0.1", + "sha.js": "^2.4.0" + } + }, + "node_modules/create-hmac": { + "version": "1.1.7", + "dev": true, + "license": "MIT", + "dependencies": { + "cipher-base": "^1.0.3", + "create-hash": "^1.1.0", + "inherits": "^2.0.1", + "ripemd160": "^2.0.0", + "safe-buffer": "^5.0.1", + "sha.js": "^2.4.8" + } + }, + "node_modules/cross-fetch": { + "version": "3.1.8", + "license": "MIT", + "dependencies": { + "node-fetch": "^2.6.12" + } + }, + "node_modules/crypto-addr-codec": { + "version": "0.1.7", + "dev": true, + "license": "MIT", + "dependencies": { + "base-x": "^3.0.8", + "big-integer": "1.6.36", + "blakejs": "^1.1.0", + "bs58": "^4.0.1", + "ripemd160-min": "0.0.6", + "safe-buffer": "^5.2.0", + "sha3": "^2.1.1" + } + }, + "node_modules/crypto-hash": { + "version": "1.3.0", + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/debug": { + "version": "4.3.3", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/decamelize": { + "version": "4.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/decimal.js": { + "version": "10.4.3", + "dev": true, + "license": "MIT" + }, + "node_modules/deep-eql": { + "version": "4.1.3", + "dev": true, + "license": "MIT", + "dependencies": { + "type-detect": "^4.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/define-properties": { + "version": "1.2.0", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "has-property-descriptors": "^1.0.0", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/delay": { + "version": "5.0.0", + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/delayed-stream": { + "version": "1.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/depd": { + "version": "2.0.0", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/diff": { + "version": "5.0.0", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.3.1" + } + }, + "node_modules/dot-case": { + "version": "3.0.4", + "license": "MIT", + "dependencies": { + "no-case": "^3.0.4", + "tslib": "^2.0.3" + } + }, + "node_modules/drbg.js": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/drbg.js/-/drbg.js-1.0.1.tgz", + "integrity": "sha512-F4wZ06PvqxYLFEZKkFxTDcns9oFNk34hvmJSEwdzsxVQ8YI5YaxtACgQatkYgv2VI2CFkUd2Y+xosPQnHv809g==", + "dev": true, + "optional": true, + "dependencies": { + "browserify-aes": "^1.0.6", + "create-hash": "^1.1.2", + "create-hmac": "^1.1.4" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/eccrypto": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/eccrypto/-/eccrypto-1.1.6.tgz", + "integrity": "sha512-d78ivVEzu7Tn0ZphUUaL43+jVPKTMPFGtmgtz1D0LrFn7cY3K8CdrvibuLz2AAkHBLKZtR8DMbB2ukRYFk987A==", + "dev": true, + "hasInstallScript": true, + "optional": true, + "dependencies": { + "acorn": "7.1.1", + "elliptic": "6.5.4", + "es6-promise": "4.2.8", + "nan": "2.14.0" + }, + "optionalDependencies": { + "secp256k1": "3.7.1" + } + }, + "node_modules/eccrypto/node_modules/bn.js": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", + "dev": true, + "optional": true + }, + "node_modules/eccrypto/node_modules/nan": { + "version": "2.14.0", + "resolved": "https://registry.npmjs.org/nan/-/nan-2.14.0.tgz", + "integrity": "sha512-INOFj37C7k3AfaNTtX8RhsTw7qRy7eLET14cROi9+5HAVbbHuIWUHEauBv5qT4Av2tWasiTY1Jw6puUNqRJXQg==", + "dev": true, + "optional": true + }, + "node_modules/eccrypto/node_modules/secp256k1": { + "version": "3.7.1", + "resolved": "https://registry.npmjs.org/secp256k1/-/secp256k1-3.7.1.tgz", + "integrity": "sha512-1cf8sbnRreXrQFdH6qsg2H71Xw91fCCS9Yp021GnUNJzWJS/py96fS4lHbnTnouLp08Xj6jBoBB6V78Tdbdu5g==", + "dev": true, + "hasInstallScript": true, + "optional": true, + "dependencies": { + "bindings": "^1.5.0", + "bip66": "^1.1.5", + "bn.js": "^4.11.8", + "create-hash": "^1.2.0", + "drbg.js": "^1.0.1", + "elliptic": "^6.4.1", + "nan": "^2.14.0", + "safe-buffer": "^5.1.2" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/elliptic": { + "version": "6.5.4", + "dev": true, + "license": "MIT", + "dependencies": { + "bn.js": "^4.11.9", + "brorand": "^1.1.0", + "hash.js": "^1.0.0", + "hmac-drbg": "^1.0.1", + "inherits": "^2.0.4", + "minimalistic-assert": "^1.0.1", + "minimalistic-crypto-utils": "^1.0.1" + } + }, + "node_modules/elliptic/node_modules/bn.js": { + "version": "4.12.0", + "dev": true, + "license": "MIT" + }, + "node_modules/emoji-regex": { + "version": "8.0.0", + "dev": true, + "license": "MIT" + }, + "node_modules/error-polyfill": { + "version": "0.1.3", + "dev": true, + "license": "MIT", + "dependencies": { + "capability": "^0.2.5", + "o3": "^1.0.3", + "u3": "^0.1.1" + } + }, + "node_modules/es6-promise": { + "version": "4.2.8", + "license": "MIT" + }, + "node_modules/es6-promisify": { + "version": "5.0.0", + "license": "MIT", + "dependencies": { + "es6-promise": "^4.0.3" + } + }, + "node_modules/escalade": { + "version": "3.1.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/escape-string-regexp": { + "version": "4.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eth-crypto": { + "version": "2.6.0", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "@babel/runtime": "7.20.13", + "@ethereumjs/tx": "3.5.2", + "@types/bn.js": "5.1.1", + "eccrypto": "1.1.6", + "ethereumjs-util": "7.1.5", + "ethers": "5.7.2", + "secp256k1": "5.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/pubkey" + } + }, + "node_modules/eth-crypto/node_modules/@babel/runtime": { + "version": "7.20.13", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "regenerator-runtime": "^0.13.11" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/eth-crypto/node_modules/node-addon-api": { + "version": "5.1.0", + "dev": true, + "license": "MIT", + "optional": true + }, + "node_modules/eth-crypto/node_modules/secp256k1": { + "version": "5.0.0", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "dependencies": { + "elliptic": "^6.5.4", + "node-addon-api": "^5.0.0", + "node-gyp-build": "^4.2.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/ethereum-cryptography": { + "version": "0.1.3", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/pbkdf2": "^3.0.0", + "@types/secp256k1": "^4.0.1", + "blakejs": "^1.1.0", + "browserify-aes": "^1.2.0", + "bs58check": "^2.1.2", + "create-hash": "^1.2.0", + "create-hmac": "^1.1.7", + "hash.js": "^1.1.7", + "keccak": "^3.0.0", + "pbkdf2": "^3.0.17", + "randombytes": "^2.1.0", + "safe-buffer": "^5.1.2", + "scrypt-js": "^3.0.0", + "secp256k1": "^4.0.1", + "setimmediate": "^1.0.5" + } + }, + "node_modules/ethereumjs-abi": { + "version": "0.6.8", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "bn.js": "^4.11.8", + "ethereumjs-util": "^6.0.0" + } + }, + "node_modules/ethereumjs-abi/node_modules/@types/bn.js": { + "version": "4.11.6", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/ethereumjs-abi/node_modules/bn.js": { + "version": "4.12.0", + "dev": true, + "license": "MIT", + "optional": true + }, + "node_modules/ethereumjs-abi/node_modules/ethereumjs-util": { + "version": "6.2.1", + "dev": true, + "license": "MPL-2.0", + "optional": true, + "dependencies": { + "@types/bn.js": "^4.11.3", + "bn.js": "^4.11.0", + "create-hash": "^1.1.2", + "elliptic": "^6.5.2", + "ethereum-cryptography": "^0.1.3", + "ethjs-util": "0.1.6", + "rlp": "^2.2.3" + } + }, + "node_modules/ethereumjs-util": { + "version": "7.1.5", + "dev": true, + "license": "MPL-2.0", + "dependencies": { + "@types/bn.js": "^5.1.0", + "bn.js": "^5.1.2", + "create-hash": "^1.1.2", + "ethereum-cryptography": "^0.1.3", + "rlp": "^2.2.4" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/ethers": { + "version": "5.7.2", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "optional": true, + "dependencies": { + "@ethersproject/abi": "5.7.0", + "@ethersproject/abstract-provider": "5.7.0", + "@ethersproject/abstract-signer": "5.7.0", + "@ethersproject/address": "5.7.0", + "@ethersproject/base64": "5.7.0", + "@ethersproject/basex": "5.7.0", + "@ethersproject/bignumber": "5.7.0", + "@ethersproject/bytes": "5.7.0", + "@ethersproject/constants": "5.7.0", + "@ethersproject/contracts": "5.7.0", + "@ethersproject/hash": "5.7.0", + "@ethersproject/hdnode": "5.7.0", + "@ethersproject/json-wallets": "5.7.0", + "@ethersproject/keccak256": "5.7.0", + "@ethersproject/logger": "5.7.0", + "@ethersproject/networks": "5.7.1", + "@ethersproject/pbkdf2": "5.7.0", + "@ethersproject/properties": "5.7.0", + "@ethersproject/providers": "5.7.2", + "@ethersproject/random": "5.7.0", + "@ethersproject/rlp": "5.7.0", + "@ethersproject/sha2": "5.7.0", + "@ethersproject/signing-key": "5.7.0", + "@ethersproject/solidity": "5.7.0", + "@ethersproject/strings": "5.7.0", + "@ethersproject/transactions": "5.7.0", + "@ethersproject/units": "5.7.0", + "@ethersproject/wallet": "5.7.0", + "@ethersproject/web": "5.7.1", + "@ethersproject/wordlists": "5.7.0" + } + }, + "node_modules/ethjs-util": { + "version": "0.1.6", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "is-hex-prefixed": "1.0.0", + "strip-hex-prefix": "1.0.0" + }, + "engines": { + "node": ">=6.5.0", + "npm": ">=3" + } + }, + "node_modules/eventemitter3": { + "version": "4.0.7", + "license": "MIT" + }, + "node_modules/evp_bytestokey": { + "version": "1.0.3", + "dev": true, + "license": "MIT", + "dependencies": { + "md5.js": "^1.3.4", + "safe-buffer": "^5.1.1" + } + }, + "node_modules/eyes": { + "version": "0.1.8", + "engines": { + "node": "> 0.1.90" + } + }, + "node_modules/fast-stable-stringify": { + "version": "1.0.0", + "license": "MIT" + }, + "node_modules/file-uri-to-path": { + "version": "1.0.0", + "license": "MIT" + }, + "node_modules/fill-range": { + "version": "7.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/find-up": { + "version": "5.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/flat": { + "version": "5.0.2", + "dev": true, + "license": "BSD-3-Clause", + "bin": { + "flat": "cli.js" + } + }, + "node_modules/follow-redirects": { + "version": "1.15.2", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/RubenVerborgh" + } + ], + "license": "MIT", + "engines": { + "node": ">=4.0" + }, + "peerDependenciesMeta": { + "debug": { + "optional": true + } + } + }, + "node_modules/form-data": { + "version": "4.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "dev": true, + "license": "ISC" + }, + "node_modules/function-bind": { + "version": "1.1.1", + "dev": true, + "license": "MIT", + "optional": true + }, + "node_modules/get-caller-file": { + "version": "2.0.5", + "dev": true, + "license": "ISC", + "engines": { + "node": "6.* || 8.* || >= 10.*" + } + }, + "node_modules/get-func-name": { + "version": "2.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": "*" + } + }, + "node_modules/get-intrinsic": { + "version": "1.2.1", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-proto": "^1.0.1", + "has-symbols": "^1.0.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/glob": { + "version": "7.2.3", + "dev": true, + "license": "ISC", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/glob-parent": { + "version": "5.1.2", + "dev": true, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/globalthis": { + "version": "1.0.3", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "define-properties": "^1.1.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/google-protobuf": { + "version": "3.21.2", + "dev": true, + "license": "(BSD-3-Clause AND Apache-2.0)" + }, + "node_modules/graphql": { + "version": "16.7.1", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": "^12.22.0 || ^14.16.0 || ^16.0.0 || >=17.0.0" + } + }, + "node_modules/graphql-tag": { + "version": "2.12.6", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.1.0" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "graphql": "^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0" + } + }, + "node_modules/growl": { + "version": "1.10.5", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4.x" + } + }, + "node_modules/has": { + "version": "1.0.3", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "function-bind": "^1.1.1" + }, + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/has-flag": { + "version": "4.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/has-property-descriptors": { + "version": "1.0.0", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "get-intrinsic": "^1.1.1" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-proto": { + "version": "1.0.1", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-symbols": { + "version": "1.0.3", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/hash-base": { + "version": "3.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "inherits": "^2.0.4", + "readable-stream": "^3.6.0", + "safe-buffer": "^5.2.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/hash.js": { + "version": "1.1.7", + "dev": true, + "license": "MIT", + "dependencies": { + "inherits": "^2.0.3", + "minimalistic-assert": "^1.0.1" + } + }, + "node_modules/he": { + "version": "1.2.0", + "dev": true, + "license": "MIT", + "bin": { + "he": "bin/he" + } + }, + "node_modules/hi-base32": { + "version": "0.5.1", + "dev": true, + "license": "MIT" + }, + "node_modules/hmac-drbg": { + "version": "1.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "hash.js": "^1.0.3", + "minimalistic-assert": "^1.0.0", + "minimalistic-crypto-utils": "^1.0.1" + } + }, + "node_modules/hoist-non-react-statics": { + "version": "3.3.2", + "dev": true, + "license": "BSD-3-Clause", + "optional": true, + "dependencies": { + "react-is": "^16.7.0" + } + }, + "node_modules/http-errors": { + "version": "1.8.1", + "dev": true, + "license": "MIT", + "dependencies": { + "depd": "~1.1.2", + "inherits": "2.0.4", + "setprototypeof": "1.2.0", + "statuses": ">= 1.5.0 < 2", + "toidentifier": "1.0.1" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/http-errors/node_modules/depd": { + "version": "1.1.2", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/http-status-codes": { + "version": "2.2.0", + "dev": true, + "license": "MIT", + "optional": true + }, + "node_modules/humanize-ms": { + "version": "1.2.1", + "license": "MIT", + "dependencies": { + "ms": "^2.0.0" + } + }, + "node_modules/humanize-ms/node_modules/ms": { + "version": "2.1.3", + "license": "MIT" + }, + "node_modules/ieee754": { + "version": "1.2.1", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "BSD-3-Clause" + }, + "node_modules/inflight": { + "version": "1.0.6", + "dev": true, + "license": "ISC", + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "dev": true, + "license": "ISC" + }, + "node_modules/interpret": { + "version": "1.4.0", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/is-binary-path": { + "version": "2.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "binary-extensions": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-core-module": { + "version": "2.12.1", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "has": "^1.0.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "dev": true, + "license": "MIT", + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-hex-prefixed": { + "version": "1.0.0", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">=6.5.0", + "npm": ">=3" + } + }, + "node_modules/is-number": { + "version": "7.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/is-plain-obj": { + "version": "2.1.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/is-unicode-supported": { + "version": "0.1.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/isarray": { + "version": "0.0.1", + "dev": true, + "license": "MIT", + "optional": true + }, + "node_modules/isexe": { + "version": "2.0.0", + "dev": true, + "license": "ISC" + }, + "node_modules/isomorphic-ws": { + "version": "4.0.1", + "license": "MIT", + "peerDependencies": { + "ws": "*" + } + }, + "node_modules/jayson": { + "version": "4.1.0", + "license": "MIT", + "dependencies": { + "@types/connect": "^3.4.33", + "@types/node": "^12.12.54", + "@types/ws": "^7.4.4", + "commander": "^2.20.3", + "delay": "^5.0.0", + "es6-promisify": "^5.0.0", + "eyes": "^0.1.8", + "isomorphic-ws": "^4.0.1", + "json-stringify-safe": "^5.0.1", + "JSONStream": "^1.3.5", + "uuid": "^8.3.2", + "ws": "^7.4.5" + }, + "bin": { + "jayson": "bin/jayson.js" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jayson/node_modules/@types/node": { + "version": "12.20.55", + "license": "MIT" + }, + "node_modules/js-base64": { + "version": "3.7.5", + "dev": true, + "license": "BSD-3-Clause" + }, + "node_modules/js-sha256": { + "version": "0.9.0", + "license": "MIT" + }, + "node_modules/js-sha3": { + "version": "0.8.0", + "dev": true, + "license": "MIT" + }, + "node_modules/js-sha512": { + "version": "0.8.0", + "dev": true, + "license": "MIT" + }, + "node_modules/js-tokens": { + "version": "4.0.0", + "dev": true, + "license": "MIT", + "optional": true + }, + "node_modules/js-yaml": { + "version": "4.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/jscrypto": { + "version": "1.0.3", + "dev": true, + "license": "MIT", + "bin": { + "jscrypto": "bin/cli.js" + } + }, + "node_modules/json-bigint": { + "version": "1.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "bignumber.js": "^9.0.0" + } + }, + "node_modules/json-stringify-safe": { + "version": "5.0.1", + "license": "ISC" + }, + "node_modules/json5": { + "version": "1.0.2", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "minimist": "^1.2.0" + }, + "bin": { + "json5": "lib/cli.js" + } + }, + "node_modules/jsonparse": { + "version": "1.3.1", + "engines": [ + "node >= 0.2.0" + ], + "license": "MIT" + }, + "node_modules/jsonschema": { + "version": "1.4.1", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": "*" + } + }, + "node_modules/JSONStream": { + "version": "1.3.5", + "license": "(MIT OR Apache-2.0)", + "dependencies": { + "jsonparse": "^1.2.0", + "through": ">=2.2.7 <3" + }, + "bin": { + "JSONStream": "bin.js" + }, + "engines": { + "node": "*" + } + }, + "node_modules/keccak": { + "version": "3.0.3", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "dependencies": { + "node-addon-api": "^2.0.0", + "node-gyp-build": "^4.2.0", + "readable-stream": "^3.6.0" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/keccak256": { + "version": "1.0.6", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "bn.js": "^5.2.0", + "buffer": "^6.0.3", + "keccak": "^3.0.2" + } + }, + "node_modules/libsodium": { + "version": "0.7.11", + "dev": true, + "license": "ISC", + "optional": true + }, + "node_modules/libsodium-wrappers": { + "version": "0.7.11", + "dev": true, + "license": "ISC", + "optional": true, + "dependencies": { + "libsodium": "^0.7.11" + } + }, + "node_modules/link-module-alias": { + "version": "1.2.0", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "chalk": "^2.4.1" + }, + "bin": { + "link-module-alias": "index.js" + }, + "engines": { + "node": "> 8.0.0" + } + }, + "node_modules/locate-path": { + "version": "6.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "p-locate": "^5.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/lodash": { + "version": "4.17.21", + "dev": true, + "license": "MIT", + "optional": true + }, + "node_modules/lodash.values": { + "version": "4.3.0", + "dev": true, + "license": "MIT", + "optional": true + }, + "node_modules/log-symbols": { + "version": "4.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "chalk": "^4.1.0", + "is-unicode-supported": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/log-symbols/node_modules/chalk": { + "version": "4.1.2", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/log-symbols/node_modules/supports-color": { + "version": "7.2.0", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/long": { + "version": "4.0.0", + "dev": true, + "license": "Apache-2.0" + }, + "node_modules/loose-envify": { + "version": "1.4.0", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "js-tokens": "^3.0.0 || ^4.0.0" + }, + "bin": { + "loose-envify": "cli.js" + } + }, + "node_modules/loupe": { + "version": "2.3.6", + "dev": true, + "license": "MIT", + "dependencies": { + "get-func-name": "^2.0.0" + } + }, + "node_modules/lower-case": { + "version": "2.0.2", + "license": "MIT", + "dependencies": { + "tslib": "^2.0.3" + } + }, + "node_modules/make-error": { + "version": "1.3.6", + "dev": true, + "license": "ISC" + }, + "node_modules/map-obj": { + "version": "4.3.0", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/md5.js": { + "version": "1.3.5", + "dev": true, + "license": "MIT", + "dependencies": { + "hash-base": "^3.0.0", + "inherits": "^2.0.1", + "safe-buffer": "^5.1.2" + } + }, + "node_modules/mime-db": { + "version": "1.52.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.35", + "dev": true, + "license": "MIT", + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/minimalistic-assert": { + "version": "1.0.1", + "dev": true, + "license": "ISC" + }, + "node_modules/minimalistic-crypto-utils": { + "version": "1.0.1", + "dev": true, + "license": "MIT" + }, + "node_modules/minimatch": { + "version": "3.1.2", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/minimist": { + "version": "1.2.8", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/mkdirp": { + "version": "0.5.6", + "dev": true, + "license": "MIT", + "dependencies": { + "minimist": "^1.2.6" + }, + "bin": { + "mkdirp": "bin/cmd.js" + } + }, + "node_modules/mocha": { + "version": "9.2.2", + "dev": true, + "license": "MIT", + "dependencies": { + "@ungap/promise-all-settled": "1.1.2", + "ansi-colors": "4.1.1", + "browser-stdout": "1.3.1", + "chokidar": "3.5.3", + "debug": "4.3.3", + "diff": "5.0.0", + "escape-string-regexp": "4.0.0", + "find-up": "5.0.0", + "glob": "7.2.0", + "growl": "1.10.5", + "he": "1.2.0", + "js-yaml": "4.1.0", + "log-symbols": "4.1.0", + "minimatch": "4.2.1", + "ms": "2.1.3", + "nanoid": "3.3.1", + "serialize-javascript": "6.0.0", + "strip-json-comments": "3.1.1", + "supports-color": "8.1.1", + "which": "2.0.2", + "workerpool": "6.2.0", + "yargs": "16.2.0", + "yargs-parser": "20.2.4", + "yargs-unparser": "2.0.0" + }, + "bin": { + "_mocha": "bin/_mocha", + "mocha": "bin/mocha" + }, + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mochajs" + } + }, + "node_modules/mocha/node_modules/glob": { + "version": "7.2.0", + "dev": true, + "license": "ISC", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/mocha/node_modules/glob/node_modules/minimatch": { + "version": "3.1.2", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/mocha/node_modules/minimatch": { + "version": "4.2.1", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/mocha/node_modules/ms": { + "version": "2.1.3", + "dev": true, + "license": "MIT" + }, + "node_modules/ms": { + "version": "2.1.2", + "license": "MIT" + }, + "node_modules/mustache": { + "version": "4.2.0", + "dev": true, + "license": "MIT", + "bin": { + "mustache": "bin/mustache" + } + }, + "node_modules/nan": { + "version": "2.17.0", + "dev": true, + "license": "MIT" + }, + "node_modules/nanoid": { + "version": "3.3.1", + "dev": true, + "license": "MIT", + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/near-api-js": { + "version": "1.1.0", + "dev": true, + "license": "(MIT AND Apache-2.0)", + "dependencies": { + "bn.js": "5.2.1", + "borsh": "^0.7.0", + "bs58": "^4.0.0", + "depd": "^2.0.0", + "error-polyfill": "^0.1.3", + "http-errors": "^1.7.2", + "js-sha256": "^0.9.0", + "mustache": "^4.0.0", + "node-fetch": "^2.6.1", + "text-encoding-utf-8": "^1.0.2", + "tweetnacl": "^1.0.1" + } + }, + "node_modules/no-case": { + "version": "3.0.4", + "license": "MIT", + "dependencies": { + "lower-case": "^2.0.2", + "tslib": "^2.0.3" + } + }, + "node_modules/node-addon-api": { + "version": "2.0.2", + "dev": true, + "license": "MIT" + }, + "node_modules/node-fetch": { + "version": "2.6.12", + "license": "MIT", + "dependencies": { + "whatwg-url": "^5.0.0" + }, + "engines": { + "node": "4.x || >=6.0.0" + }, + "peerDependencies": { + "encoding": "^0.1.0" + }, + "peerDependenciesMeta": { + "encoding": { + "optional": true + } + } + }, + "node_modules/node-gyp-build": { + "version": "4.6.0", + "devOptional": true, + "license": "MIT", + "bin": { + "node-gyp-build": "bin.js", + "node-gyp-build-optional": "optional.js", + "node-gyp-build-test": "build-test.js" + } + }, + "node_modules/noms": { + "version": "0.0.0", + "dev": true, + "license": "ISC", + "optional": true, + "dependencies": { + "inherits": "^2.0.1", + "readable-stream": "~1.0.31" + } + }, + "node_modules/noms/node_modules/readable-stream": { + "version": "1.0.34", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "0.0.1", + "string_decoder": "~0.10.x" + } + }, + "node_modules/noms/node_modules/string_decoder": { + "version": "0.10.31", + "dev": true, + "license": "MIT", + "optional": true + }, + "node_modules/normalize-path": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/o3": { + "version": "1.0.3", + "dev": true, + "license": "MIT", + "dependencies": { + "capability": "^0.2.5" + } + }, + "node_modules/object-assign": { + "version": "4.1.1", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-keys": { + "version": "1.1.1", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/once": { + "version": "1.4.0", + "dev": true, + "license": "ISC", + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/optimism": { + "version": "0.16.2", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "@wry/context": "^0.7.0", + "@wry/trie": "^0.3.0" + } + }, + "node_modules/optimism/node_modules/@wry/trie": { + "version": "0.3.2", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.3.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/p-limit": { + "version": "3.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-locate": { + "version": "5.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "p-limit": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/pako": { + "version": "2.1.0", + "license": "(MIT AND Zlib)" + }, + "node_modules/path-exists": { + "version": "4.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/path-is-absolute": { + "version": "1.0.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/path-parse": { + "version": "1.0.7", + "dev": true, + "license": "MIT", + "optional": true + }, + "node_modules/pathval": { + "version": "1.1.1", + "dev": true, + "license": "MIT", + "engines": { + "node": "*" + } + }, + "node_modules/pbkdf2": { + "version": "3.1.2", + "dev": true, + "license": "MIT", + "dependencies": { + "create-hash": "^1.1.2", + "create-hmac": "^1.1.4", + "ripemd160": "^2.0.1", + "safe-buffer": "^5.0.1", + "sha.js": "^2.4.8" + }, + "engines": { + "node": ">=0.12" + } + }, + "node_modules/picomatch": { + "version": "2.3.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/prettier": { + "version": "2.8.8", + "dev": true, + "license": "MIT", + "bin": { + "prettier": "bin-prettier.js" + }, + "engines": { + "node": ">=10.13.0" + }, + "funding": { + "url": "https://github.com/prettier/prettier?sponsor=1" + } + }, + "node_modules/process-nextick-args": { + "version": "2.0.1", + "dev": true, + "license": "MIT", + "optional": true + }, + "node_modules/prop-types": { + "version": "15.8.1", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "loose-envify": "^1.4.0", + "object-assign": "^4.1.1", + "react-is": "^16.13.1" + } + }, + "node_modules/protobufjs": { + "version": "6.11.3", + "dev": true, + "hasInstallScript": true, + "license": "BSD-3-Clause", + "dependencies": { + "@protobufjs/aspromise": "^1.1.2", + "@protobufjs/base64": "^1.1.2", + "@protobufjs/codegen": "^2.0.4", + "@protobufjs/eventemitter": "^1.1.0", + "@protobufjs/fetch": "^1.1.0", + "@protobufjs/float": "^1.0.2", + "@protobufjs/inquire": "^1.1.0", + "@protobufjs/path": "^1.1.2", + "@protobufjs/pool": "^1.1.0", + "@protobufjs/utf8": "^1.1.0", + "@types/long": "^4.0.1", + "@types/node": ">=13.7.0", + "long": "^4.0.0" + }, + "bin": { + "pbjs": "bin/pbjs", + "pbts": "bin/pbts" + } + }, + "node_modules/randombytes": { + "version": "2.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "safe-buffer": "^5.1.0" + } + }, + "node_modules/react-is": { + "version": "16.13.1", + "dev": true, + "license": "MIT", + "optional": true + }, + "node_modules/readable-stream": { + "version": "3.6.2", + "dev": true, + "license": "MIT", + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/readdirp": { + "version": "3.6.0", + "dev": true, + "license": "MIT", + "dependencies": { + "picomatch": "^2.2.1" + }, + "engines": { + "node": ">=8.10.0" + } + }, + "node_modules/readonly-date": { + "version": "1.0.0", + "dev": true, + "license": "Apache-2.0", + "optional": true + }, + "node_modules/rechoir": { + "version": "0.6.2", + "dev": true, + "optional": true, + "dependencies": { + "resolve": "^1.1.6" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/regenerator-runtime": { + "version": "0.13.11", + "license": "MIT" + }, + "node_modules/require-directory": { + "version": "2.1.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/resolve": { + "version": "1.22.2", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "is-core-module": "^2.11.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/response-iterator": { + "version": "0.2.6", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/rimraf": { + "version": "3.0.2", + "dev": true, + "license": "ISC", + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/ripemd160": { + "version": "2.0.2", + "dev": true, + "license": "MIT", + "dependencies": { + "hash-base": "^3.0.0", + "inherits": "^2.0.1" + } + }, + "node_modules/ripemd160-min": { + "version": "0.0.6", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/rlp": { + "version": "2.2.7", + "dev": true, + "license": "MPL-2.0", + "dependencies": { + "bn.js": "^5.2.0" + }, + "bin": { + "rlp": "bin/rlp" + } + }, + "node_modules/rpc-websockets": { + "version": "7.5.1", + "license": "LGPL-3.0-only", + "dependencies": { + "@babel/runtime": "^7.17.2", + "eventemitter3": "^4.0.7", + "uuid": "^8.3.2", + "ws": "^8.5.0" + }, + "funding": { + "type": "paypal", + "url": "https://paypal.me/kozjak" + }, + "optionalDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": "^5.0.2" + } + }, + "node_modules/rpc-websockets/node_modules/ws": { + "version": "8.13.0", + "license": "MIT", + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": ">=5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "node_modules/rxjs": { + "version": "7.8.1", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.1.0" + } + }, + "node_modules/safe-buffer": { + "version": "5.2.1", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/scrypt-js": { + "version": "3.0.1", + "dev": true, + "license": "MIT" + }, + "node_modules/secp256k1": { + "version": "4.0.3", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "dependencies": { + "elliptic": "^6.5.4", + "node-addon-api": "^2.0.0", + "node-gyp-build": "^4.2.0" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/serialize-javascript": { + "version": "6.0.0", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "randombytes": "^2.1.0" + } + }, + "node_modules/setimmediate": { + "version": "1.0.5", + "dev": true, + "license": "MIT" + }, + "node_modules/setprototypeof": { + "version": "1.2.0", + "dev": true, + "license": "ISC" + }, + "node_modules/sha.js": { + "version": "2.4.11", + "dev": true, + "license": "(MIT AND BSD-3-Clause)", + "dependencies": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + }, + "bin": { + "sha.js": "bin.js" + } + }, + "node_modules/sha3": { + "version": "2.1.4", + "dev": true, + "license": "MIT", + "dependencies": { + "buffer": "6.0.3" + } + }, + "node_modules/shelljs": { + "version": "0.8.5", + "dev": true, + "license": "BSD-3-Clause", + "optional": true, + "dependencies": { + "glob": "^7.0.0", + "interpret": "^1.0.0", + "rechoir": "^0.6.2" + }, + "bin": { + "shjs": "bin/shjs" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/shx": { + "version": "0.3.4", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "minimist": "^1.2.3", + "shelljs": "^0.8.5" + }, + "bin": { + "shx": "lib/cli.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/snake-case": { + "version": "3.0.4", + "license": "MIT", + "dependencies": { + "dot-case": "^3.0.4", + "tslib": "^2.0.3" + } + }, + "node_modules/snakecase-keys": { + "version": "5.4.6", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "map-obj": "^4.1.0", + "snake-case": "^3.0.4", + "type-fest": "^2.5.2" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/source-map": { + "version": "0.6.1", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/source-map-support": { + "version": "0.5.21", + "dev": true, + "license": "MIT", + "dependencies": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "node_modules/statuses": { + "version": "1.5.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/store2": { + "version": "2.14.2", + "dev": true, + "license": "(MIT OR GPL-3.0)", + "optional": true + }, + "node_modules/string_decoder": { + "version": "1.3.0", + "dev": true, + "license": "MIT", + "dependencies": { + "safe-buffer": "~5.2.0" + } + }, + "node_modules/string-width": { + "version": "4.2.3", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi": { + "version": "6.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-bom": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/strip-hex-prefix": { + "version": "1.0.0", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "is-hex-prefixed": "1.0.0" + }, + "engines": { + "node": ">=6.5.0", + "npm": ">=3" + } + }, + "node_modules/strip-json-comments": { + "version": "3.1.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/superstruct": { + "version": "0.15.5", + "license": "MIT" + }, + "node_modules/supports-color": { + "version": "8.1.1", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, + "node_modules/supports-preserve-symlinks-flag": { + "version": "1.0.0", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/symbol-observable": { + "version": "4.0.0", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/text-encoding-utf-8": { + "version": "1.0.2" + }, + "node_modules/through": { + "version": "2.3.8", + "license": "MIT" + }, + "node_modules/through2": { + "version": "2.0.5", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "readable-stream": "~2.3.6", + "xtend": "~4.0.1" + } + }, + "node_modules/through2/node_modules/isarray": { + "version": "1.0.0", + "dev": true, + "license": "MIT", + "optional": true + }, + "node_modules/through2/node_modules/readable-stream": { + "version": "2.3.8", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/through2/node_modules/safe-buffer": { + "version": "5.1.2", + "dev": true, + "license": "MIT", + "optional": true + }, + "node_modules/through2/node_modules/string_decoder": { + "version": "1.1.1", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, + "node_modules/tiny-secp256k1": { + "version": "1.1.6", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "dependencies": { + "bindings": "^1.3.0", + "bn.js": "^4.11.8", + "create-hmac": "^1.1.7", + "elliptic": "^6.4.0", + "nan": "^2.13.2" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/tiny-secp256k1/node_modules/bn.js": { + "version": "4.12.0", + "dev": true, + "license": "MIT" + }, + "node_modules/tmp": { + "version": "0.2.1", + "dev": true, + "license": "MIT", + "dependencies": { + "rimraf": "^3.0.0" + }, + "engines": { + "node": ">=8.17.0" + } + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/toidentifier": { + "version": "1.0.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.6" + } + }, + "node_modules/toml": { + "version": "3.0.0", + "license": "MIT" + }, + "node_modules/tr46": { + "version": "0.0.3", + "license": "MIT" + }, + "node_modules/ts-invariant": { + "version": "0.10.3", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/ts-mocha": { + "version": "10.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "ts-node": "7.0.1" + }, + "bin": { + "ts-mocha": "bin/ts-mocha" + }, + "engines": { + "node": ">= 6.X.X" + }, + "optionalDependencies": { + "tsconfig-paths": "^3.5.0" + }, + "peerDependencies": { + "mocha": "^3.X.X || ^4.X.X || ^5.X.X || ^6.X.X || ^7.X.X || ^8.X.X || ^9.X.X || ^10.X.X" + } + }, + "node_modules/ts-node": { + "version": "7.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "arrify": "^1.0.0", + "buffer-from": "^1.1.0", + "diff": "^3.1.0", + "make-error": "^1.1.1", + "minimist": "^1.2.0", + "mkdirp": "^0.5.1", + "source-map-support": "^0.5.6", + "yn": "^2.0.0" + }, + "bin": { + "ts-node": "dist/bin.js" + }, + "engines": { + "node": ">=4.2.0" + } + }, + "node_modules/ts-node/node_modules/diff": { + "version": "3.5.0", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.3.1" + } + }, + "node_modules/tsconfig-paths": { + "version": "3.14.2", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "@types/json5": "^0.0.29", + "json5": "^1.0.2", + "minimist": "^1.2.6", + "strip-bom": "^3.0.0" + } + }, + "node_modules/tslib": { + "version": "2.6.1", + "license": "0BSD" + }, + "node_modules/tweetnacl": { + "version": "1.0.3", + "dev": true, + "license": "Unlicense" + }, + "node_modules/tweetnacl-util": { + "version": "0.15.1", + "dev": true, + "license": "Unlicense", + "optional": true + }, + "node_modules/type-detect": { + "version": "4.0.8", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/type-fest": { + "version": "2.19.0", + "dev": true, + "license": "(MIT OR CC0-1.0)", + "optional": true, + "engines": { + "node": ">=12.20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/typeforce": { + "version": "1.18.0", + "dev": true, + "license": "MIT" + }, + "node_modules/typescript": { + "version": "4.9.5", + "dev": true, + "license": "Apache-2.0", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=4.2.0" + } + }, + "node_modules/u3": { + "version": "0.1.1", + "dev": true, + "license": "MIT" + }, + "node_modules/untildify": { + "version": "4.0.0", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/utf-8-validate": { + "version": "5.0.10", + "devOptional": true, + "hasInstallScript": true, + "license": "MIT", + "dependencies": { + "node-gyp-build": "^4.3.0" + }, + "engines": { + "node": ">=6.14.2" + } + }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "dev": true, + "license": "MIT" + }, + "node_modules/uuid": { + "version": "8.3.2", + "license": "MIT", + "bin": { + "uuid": "dist/bin/uuid" + } + }, + "node_modules/vlq": { + "version": "2.0.4", + "dev": true, + "license": "MIT" + }, + "node_modules/webidl-conversions": { + "version": "3.0.1", + "license": "BSD-2-Clause" + }, + "node_modules/whatwg-url": { + "version": "5.0.0", + "license": "MIT", + "dependencies": { + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" + } + }, + "node_modules/which": { + "version": "2.0.2", + "dev": true, + "license": "ISC", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/wif": { + "version": "2.0.6", + "dev": true, + "license": "MIT", + "dependencies": { + "bs58check": "<3.0.0" + } + }, + "node_modules/workerpool": { + "version": "6.2.0", + "dev": true, + "license": "Apache-2.0" + }, + "node_modules/wrap-ansi": { + "version": "7.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrappy": { + "version": "1.0.2", + "dev": true, + "license": "ISC" + }, + "node_modules/ws": { + "version": "7.5.9", + "license": "MIT", + "engines": { + "node": ">=8.3.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": "^5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "node_modules/xstream": { + "version": "11.14.0", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "globalthis": "^1.0.1", + "symbol-observable": "^2.0.3" + } + }, + "node_modules/xstream/node_modules/symbol-observable": { + "version": "2.0.3", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/xtend": { + "version": "4.0.2", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">=0.4" + } + }, + "node_modules/y18n": { + "version": "5.0.8", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=10" + } + }, + "node_modules/yargs": { + "version": "16.2.0", + "dev": true, + "license": "MIT", + "dependencies": { + "cliui": "^7.0.2", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.0", + "y18n": "^5.0.5", + "yargs-parser": "^20.2.2" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/yargs-parser": { + "version": "20.2.4", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=10" + } + }, + "node_modules/yargs-unparser": { + "version": "2.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "camelcase": "^6.0.0", + "decamelize": "^4.0.0", + "flat": "^5.0.2", + "is-plain-obj": "^2.1.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/yargs/node_modules/yargs-parser": { + "version": "20.2.9", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=10" + } + }, + "node_modules/yn": { + "version": "2.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/yocto-queue": { + "version": "0.1.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/zen-observable": { + "version": "0.8.15", + "dev": true, + "license": "MIT", + "optional": true + }, + "node_modules/zen-observable-ts": { + "version": "1.2.5", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "zen-observable": "0.8.15" + } + } + } +} diff --git a/cross-chain/solana/package.json b/cross-chain/solana/package.json new file mode 100644 index 000000000..a18adfd59 --- /dev/null +++ b/cross-chain/solana/package.json @@ -0,0 +1,22 @@ +{ + "scripts": { + "lint:fix": "prettier */*.js \"*/**/*{.js,.ts}\" -w", + "lint": "prettier */*.js \"*/**/*{.js,.ts}\" --check" + }, + "dependencies": { + "@coral-xyz/anchor": "^0.28.0" + }, + "devDependencies": { + "@certusone/wormhole-sdk": "^0.9.22", + "@solana/spl-token": "^0.3.8", + "@solana/web3.js": "^1.77.3", + "@types/bn.js": "^5.1.0", + "@types/chai": "^4.3.0", + "@types/mocha": "^9.0.0", + "chai": "^4.3.4", + "mocha": "^9.0.3", + "prettier": "^2.6.2", + "ts-mocha": "^10.0.0", + "typescript": "^4.3.5" + } +} diff --git a/cross-chain/solana/programs/tbtc/Cargo.toml b/cross-chain/solana/programs/tbtc/Cargo.toml new file mode 100644 index 000000000..18e88c859 --- /dev/null +++ b/cross-chain/solana/programs/tbtc/Cargo.toml @@ -0,0 +1,23 @@ +[package] +name = "tbtc" +version = "0.1.0" +description = "Created with Anchor" +edition = "2021" + +[lib] +crate-type = ["cdylib", "lib"] +name = "tbtc" + +[features] +default = [] +mainnet = [] +solana-devnet = [] +no-entrypoint = [] +no-idl = [] +no-log-ix-name = [] +cpi = ["no-entrypoint"] + +[dependencies] +anchor-lang = { version = "=0.28.0", features = ["derive", "init-if-needed"] } +anchor-spl = "=0.28.0" +solana-program = "=1.14.20" diff --git a/cross-chain/solana/programs/tbtc/Xargo.toml b/cross-chain/solana/programs/tbtc/Xargo.toml new file mode 100644 index 000000000..475fb71ed --- /dev/null +++ b/cross-chain/solana/programs/tbtc/Xargo.toml @@ -0,0 +1,2 @@ +[target.bpfel-unknown-unknown.dependencies.std] +features = [] diff --git a/cross-chain/solana/programs/tbtc/src/constants.rs b/cross-chain/solana/programs/tbtc/src/constants.rs new file mode 100644 index 000000000..35f37b14b --- /dev/null +++ b/cross-chain/solana/programs/tbtc/src/constants.rs @@ -0,0 +1,4 @@ +use anchor_lang::prelude::constant; + +#[constant] +pub const SEED_PREFIX_TBTC_MINT: &[u8] = b"tbtc-mint"; diff --git a/cross-chain/solana/programs/tbtc/src/error.rs b/cross-chain/solana/programs/tbtc/src/error.rs new file mode 100644 index 000000000..5e1b279d5 --- /dev/null +++ b/cross-chain/solana/programs/tbtc/src/error.rs @@ -0,0 +1,10 @@ +use anchor_lang::prelude::error_code; + +#[error_code] +pub enum TbtcError { + IsPaused, + IsNotPaused, + IsNotAuthority, + IsNotPendingAuthority, + NoPendingAuthorityChange, +} diff --git a/cross-chain/solana/programs/tbtc/src/event.rs b/cross-chain/solana/programs/tbtc/src/event.rs new file mode 100644 index 000000000..6a385a50a --- /dev/null +++ b/cross-chain/solana/programs/tbtc/src/event.rs @@ -0,0 +1,21 @@ +use anchor_lang::prelude::*; + +#[event] +pub struct MinterAdded { + pub minter: Pubkey, +} + +#[event] +pub struct MinterRemoved { + pub minter: Pubkey, +} + +#[event] +pub struct GuardianAdded { + pub guardian: Pubkey, +} + +#[event] +pub struct GuardianRemoved { + pub guardian: Pubkey, +} \ No newline at end of file diff --git a/cross-chain/solana/programs/tbtc/src/lib.rs b/cross-chain/solana/programs/tbtc/src/lib.rs new file mode 100644 index 000000000..f2604b0f9 --- /dev/null +++ b/cross-chain/solana/programs/tbtc/src/lib.rs @@ -0,0 +1,74 @@ +#![allow(clippy::result_large_err)] + +mod constants; +pub use constants::*; + +pub mod error; + +mod processor; +pub(crate) use processor::*; + +mod state; +pub use state::*; + +use anchor_lang::prelude::*; + +declare_id!("HksEtDgsXJV1BqcuhzbLRTmXp5gHgHJktieJCtQd3pG"); + +#[derive(Clone)] +pub struct Tbtc; + +impl Id for Tbtc { + fn id() -> Pubkey { + ID + } +} + +#[program] +pub mod tbtc { + use super::*; + + pub fn initialize(ctx: Context) -> Result<()> { + processor::initialize(ctx) + } + + pub fn change_authority(ctx: Context) -> Result<()> { + processor::change_authority(ctx) + } + + pub fn cancel_authority_change(ctx: Context) -> Result<()> { + processor::cancel_authority_change(ctx) + } + + pub fn take_authority(ctx: Context) -> Result<()> { + processor::take_authority(ctx) + } + + pub fn add_minter(ctx: Context) -> Result<()> { + processor::add_minter(ctx) + } + + pub fn remove_minter(ctx: Context) -> Result<()> { + processor::remove_minter(ctx) + } + + pub fn add_guardian(ctx: Context) -> Result<()> { + processor::add_guardian(ctx) + } + + pub fn remove_guardian(ctx: Context) -> Result<()> { + processor::remove_guardian(ctx) + } + + pub fn pause(ctx: Context) -> Result<()> { + processor::pause(ctx) + } + + pub fn unpause(ctx: Context) -> Result<()> { + processor::unpause(ctx) + } + + pub fn mint(ctx: Context, amount: u64) -> Result<()> { + processor::mint(ctx, amount) + } +} diff --git a/cross-chain/solana/programs/tbtc/src/processor/admin/add_guardian.rs b/cross-chain/solana/programs/tbtc/src/processor/admin/add_guardian.rs new file mode 100644 index 000000000..422bac905 --- /dev/null +++ b/cross-chain/solana/programs/tbtc/src/processor/admin/add_guardian.rs @@ -0,0 +1,43 @@ +use crate::{ + error::TbtcError, + state::{Config, GuardianInfo}, +}; +use anchor_lang::prelude::*; + +#[derive(Accounts)] +pub struct AddGuardian<'info> { + #[account( + mut, + seeds = [Config::SEED_PREFIX], + bump, + has_one = authority @ TbtcError::IsNotAuthority + )] + config: Account<'info, Config>, + + #[account(mut)] + authority: Signer<'info>, + + #[account( + init, + payer = authority, + space = 8 + GuardianInfo::INIT_SPACE, + seeds = [GuardianInfo::SEED_PREFIX, guardian.key().as_ref()], + bump + )] + guardian_info: Account<'info, GuardianInfo>, + + /// CHECK: Required authority to pause contract. This pubkey lives in `GuardianInfo`. + guardian: AccountInfo<'info>, + + system_program: Program<'info, System>, +} + +pub fn add_guardian(ctx: Context) -> Result<()> { + ctx.accounts.guardian_info.set_inner(GuardianInfo { + guardian: ctx.accounts.guardian.key(), + bump: ctx.bumps["guardian_info"], + }); + + ctx.accounts.config.num_guardians += 1; + Ok(()) +} diff --git a/cross-chain/solana/programs/tbtc/src/processor/admin/add_minter.rs b/cross-chain/solana/programs/tbtc/src/processor/admin/add_minter.rs new file mode 100644 index 000000000..ccb8620cb --- /dev/null +++ b/cross-chain/solana/programs/tbtc/src/processor/admin/add_minter.rs @@ -0,0 +1,43 @@ +use crate::{ + error::TbtcError, + state::{Config, MinterInfo}, +}; +use anchor_lang::prelude::*; + +#[derive(Accounts)] +pub struct AddMinter<'info> { + #[account( + mut, + seeds = [Config::SEED_PREFIX], + bump, + has_one = authority @ TbtcError::IsNotAuthority + )] + config: Account<'info, Config>, + + #[account(mut)] + authority: Signer<'info>, + + #[account( + init, + payer = authority, + space = 8 + MinterInfo::INIT_SPACE, + seeds = [MinterInfo::SEED_PREFIX, minter.key().as_ref()], + bump + )] + minter_info: Account<'info, MinterInfo>, + + /// CHECK: Required authority to mint tokens. This pubkey lives in `MinterInfo`. + minter: AccountInfo<'info>, + + system_program: Program<'info, System>, +} + +pub fn add_minter(ctx: Context) -> Result<()> { + ctx.accounts.minter_info.set_inner(MinterInfo { + minter: ctx.accounts.minter.key(), + bump: ctx.bumps["minter_info"], + }); + + ctx.accounts.config.num_minters += 1; + Ok(()) +} diff --git a/cross-chain/solana/programs/tbtc/src/processor/admin/cancel_authority_change.rs b/cross-chain/solana/programs/tbtc/src/processor/admin/cancel_authority_change.rs new file mode 100644 index 000000000..92000cca0 --- /dev/null +++ b/cross-chain/solana/programs/tbtc/src/processor/admin/cancel_authority_change.rs @@ -0,0 +1,22 @@ +use crate::{error::TbtcError, state::Config}; +use anchor_lang::prelude::*; + +#[derive(Accounts)] + +pub struct CancelAuthorityChange<'info> { + #[account( + mut, + seeds = [Config::SEED_PREFIX], + bump, + has_one = authority @ TbtcError::IsNotAuthority, + constraint = config.pending_authority.is_some() @ TbtcError::NoPendingAuthorityChange + )] + config: Account<'info, Config>, + + authority: Signer<'info>, +} + +pub fn cancel_authority_change(ctx: Context) -> Result<()> { + ctx.accounts.config.pending_authority = None; + Ok(()) +} diff --git a/cross-chain/solana/programs/tbtc/src/processor/admin/change_authority.rs b/cross-chain/solana/programs/tbtc/src/processor/admin/change_authority.rs new file mode 100644 index 000000000..0581396c0 --- /dev/null +++ b/cross-chain/solana/programs/tbtc/src/processor/admin/change_authority.rs @@ -0,0 +1,23 @@ +use crate::{error::TbtcError, state::Config}; +use anchor_lang::prelude::*; + +#[derive(Accounts)] +pub struct ChangeAuthority<'info> { + #[account( + mut, + seeds = [Config::SEED_PREFIX], + bump, + has_one = authority @ TbtcError::IsNotAuthority + )] + config: Account<'info, Config>, + + authority: Signer<'info>, + + /// CHECK: New authority. + new_authority: AccountInfo<'info>, +} + +pub fn change_authority(ctx: Context) -> Result<()> { + ctx.accounts.config.pending_authority = Some(ctx.accounts.new_authority.key()); + Ok(()) +} diff --git a/cross-chain/solana/programs/tbtc/src/processor/admin/initialize.rs b/cross-chain/solana/programs/tbtc/src/processor/admin/initialize.rs new file mode 100644 index 000000000..e32ebc5bb --- /dev/null +++ b/cross-chain/solana/programs/tbtc/src/processor/admin/initialize.rs @@ -0,0 +1,47 @@ +use crate::{constants::SEED_PREFIX_TBTC_MINT, state::Config}; +use anchor_lang::prelude::*; +use anchor_spl::token; + +#[derive(Accounts)] +pub struct Initialize<'info> { + // Use PDA for the mint address + // so we can sign for it from the program + #[account( + init, + seeds = [SEED_PREFIX_TBTC_MINT], + bump, + payer = authority, + mint::decimals = 9, + mint::authority = config, + )] + mint: Account<'info, token::Mint>, + + #[account( + init, + payer = authority, + space = 8 + Config::INIT_SPACE, + seeds = [Config::SEED_PREFIX], + bump, + )] + config: Account<'info, Config>, + + #[account(mut)] + authority: Signer<'info>, + + token_program: Program<'info, token::Token>, + system_program: Program<'info, System>, +} + +pub fn initialize(ctx: Context) -> Result<()> { + ctx.accounts.config.set_inner(Config { + bump: ctx.bumps["config"], + authority: ctx.accounts.authority.key(), + pending_authority: None, + mint: ctx.accounts.mint.key(), + mint_bump: ctx.bumps["mint"], + num_minters: 0, + num_guardians: 0, + paused: false, + }); + Ok(()) +} diff --git a/cross-chain/solana/programs/tbtc/src/processor/admin/mod.rs b/cross-chain/solana/programs/tbtc/src/processor/admin/mod.rs new file mode 100644 index 000000000..4e9b75a5c --- /dev/null +++ b/cross-chain/solana/programs/tbtc/src/processor/admin/mod.rs @@ -0,0 +1,29 @@ +mod add_guardian; +pub use add_guardian::*; + +mod add_minter; +pub use add_minter::*; + +mod cancel_authority_change; +pub use cancel_authority_change::*; + +mod change_authority; +pub use change_authority::*; + +mod initialize; +pub use initialize::*; + +mod pause; +pub use pause::*; + +mod remove_guardian; +pub use remove_guardian::*; + +mod remove_minter; +pub use remove_minter::*; + +mod take_authority; +pub use take_authority::*; + +mod unpause; +pub use unpause::*; diff --git a/cross-chain/solana/programs/tbtc/src/processor/admin/pause.rs b/cross-chain/solana/programs/tbtc/src/processor/admin/pause.rs new file mode 100644 index 000000000..239635a62 --- /dev/null +++ b/cross-chain/solana/programs/tbtc/src/processor/admin/pause.rs @@ -0,0 +1,38 @@ +use crate::{ + error::TbtcError, + state::{Config, GuardianInfo}, +}; +use anchor_lang::prelude::*; + +#[derive(Accounts)] +pub struct Pause<'info> { + #[account( + mut, + seeds = [Config::SEED_PREFIX], + bump, + )] + config: Account<'info, Config>, + + #[account( + has_one = guardian, + seeds = [GuardianInfo::SEED_PREFIX, guardian.key().as_ref()], + bump = guardian_info.bump + )] + guardian_info: Account<'info, GuardianInfo>, + + guardian: Signer<'info>, +} + +impl<'info> Pause<'info> { + fn constraints(ctx: &Context) -> Result<()> { + require!(!ctx.accounts.config.paused, TbtcError::IsPaused); + + Ok(()) + } +} + +#[access_control(Pause::constraints(&ctx))] +pub fn pause(ctx: Context) -> Result<()> { + ctx.accounts.config.paused = true; + Ok(()) +} diff --git a/cross-chain/solana/programs/tbtc/src/processor/admin/remove_guardian.rs b/cross-chain/solana/programs/tbtc/src/processor/admin/remove_guardian.rs new file mode 100644 index 000000000..777edf865 --- /dev/null +++ b/cross-chain/solana/programs/tbtc/src/processor/admin/remove_guardian.rs @@ -0,0 +1,33 @@ +use crate::{ + error::TbtcError, + state::{Config, GuardianInfo}, +}; +use anchor_lang::prelude::*; + +#[derive(Accounts)] +pub struct RemoveGuardian<'info> { + #[account( + mut, + has_one = authority @ TbtcError::IsNotAuthority, + )] + config: Account<'info, Config>, + + authority: Signer<'info>, + + #[account( + mut, + has_one = guardian, + close = authority, + seeds = [GuardianInfo::SEED_PREFIX, guardian.key().as_ref()], + bump = guardian_info.bump, + )] + guardian_info: Account<'info, GuardianInfo>, + + /// CHECK: Required authority to pause contract. This pubkey lives in `GuardianInfo`. + guardian: AccountInfo<'info>, +} + +pub fn remove_guardian(ctx: Context) -> Result<()> { + ctx.accounts.config.num_guardians -= 1; + Ok(()) +} diff --git a/cross-chain/solana/programs/tbtc/src/processor/admin/remove_minter.rs b/cross-chain/solana/programs/tbtc/src/processor/admin/remove_minter.rs new file mode 100644 index 000000000..83aa5a07d --- /dev/null +++ b/cross-chain/solana/programs/tbtc/src/processor/admin/remove_minter.rs @@ -0,0 +1,35 @@ +use crate::{ + error::TbtcError, + state::{Config, MinterInfo}, +}; +use anchor_lang::prelude::*; + +#[derive(Accounts)] +pub struct RemoveMinter<'info> { + #[account( + mut, + seeds = [Config::SEED_PREFIX], + bump, + has_one = authority @ TbtcError::IsNotAuthority + )] + config: Account<'info, Config>, + + authority: Signer<'info>, + + #[account( + mut, + has_one = minter, + close = authority, + seeds = [MinterInfo::SEED_PREFIX, minter.key().as_ref()], + bump = minter_info.bump, + )] + minter_info: Account<'info, MinterInfo>, + + /// CHECK: Required authority to mint tokens. This pubkey lives in `MinterInfo`. + minter: AccountInfo<'info>, +} + +pub fn remove_minter(ctx: Context) -> Result<()> { + ctx.accounts.config.num_minters -= 1; + Ok(()) +} diff --git a/cross-chain/solana/programs/tbtc/src/processor/admin/take_authority.rs b/cross-chain/solana/programs/tbtc/src/processor/admin/take_authority.rs new file mode 100644 index 000000000..292d2d726 --- /dev/null +++ b/cross-chain/solana/programs/tbtc/src/processor/admin/take_authority.rs @@ -0,0 +1,24 @@ +use crate::{error::TbtcError, state::Config}; +use anchor_lang::prelude::*; + +#[derive(Accounts)] +pub struct TakeAuthority<'info> { + #[account( + mut, + seeds = [Config::SEED_PREFIX], + bump, + constraint = config.pending_authority.is_some() @ TbtcError::NoPendingAuthorityChange + )] + config: Account<'info, Config>, + + #[account( + constraint = pending_authority.key() == config.pending_authority.unwrap() @ TbtcError::IsNotPendingAuthority + )] + pending_authority: Signer<'info>, +} + +pub fn take_authority(ctx: Context) -> Result<()> { + ctx.accounts.config.authority = ctx.accounts.pending_authority.key(); + ctx.accounts.config.pending_authority = None; + Ok(()) +} \ No newline at end of file diff --git a/cross-chain/solana/programs/tbtc/src/processor/admin/unpause.rs b/cross-chain/solana/programs/tbtc/src/processor/admin/unpause.rs new file mode 100644 index 000000000..e5ce8fa25 --- /dev/null +++ b/cross-chain/solana/programs/tbtc/src/processor/admin/unpause.rs @@ -0,0 +1,29 @@ +use crate::{error::TbtcError, state::Config}; +use anchor_lang::prelude::*; + +#[derive(Accounts)] +pub struct Unpause<'info> { + #[account( + mut, + has_one = authority @ TbtcError::IsNotAuthority, + seeds = [Config::SEED_PREFIX], + bump, + )] + config: Account<'info, Config>, + + authority: Signer<'info>, +} + +impl<'info> Unpause<'info> { + fn constraints(ctx: &Context) -> Result<()> { + require!(ctx.accounts.config.paused, TbtcError::IsNotPaused); + + Ok(()) + } +} + +#[access_control(Unpause::constraints(&ctx))] +pub fn unpause(ctx: Context) -> Result<()> { + ctx.accounts.config.paused = false; + Ok(()) +} diff --git a/cross-chain/solana/programs/tbtc/src/processor/mint.rs b/cross-chain/solana/programs/tbtc/src/processor/mint.rs new file mode 100644 index 000000000..f64307754 --- /dev/null +++ b/cross-chain/solana/programs/tbtc/src/processor/mint.rs @@ -0,0 +1,69 @@ +use crate::{ + constants::SEED_PREFIX_TBTC_MINT, + error::TbtcError, + state::{Config, MinterInfo}, +}; +use anchor_lang::prelude::*; +use anchor_spl::token; + +#[derive(Accounts)] +pub struct Mint<'info> { + // Use the correct token mint for the program. + #[account( + mut, + seeds = [SEED_PREFIX_TBTC_MINT], + bump = config.mint_bump, + mint::authority = config, + )] + mint: Account<'info, token::Mint>, + + #[account( + seeds = [Config::SEED_PREFIX], + bump = config.bump, + )] + config: Account<'info, Config>, + + // Require the signing minter to match a valid minter info. + #[account( + has_one = minter, + seeds = [MinterInfo::SEED_PREFIX, minter.key().as_ref()], + bump = minter_info.bump, + )] + minter_info: Account<'info, MinterInfo>, + + minter: Signer<'info>, + + // Use the associated token account for the recipient. + #[account( + mut, + token::mint = mint, + )] + recipient_token: Account<'info, token::TokenAccount>, + + token_program: Program<'info, token::Token>, +} + +impl<'info> Mint<'info> { + fn constraints(ctx: &Context) -> Result<()> { + // Can not mint when paused. + require!(!ctx.accounts.config.paused, TbtcError::IsPaused); + + Ok(()) + } +} + +#[access_control(Mint::constraints(&ctx))] +pub fn mint(ctx: Context, amount: u64) -> Result<()> { + token::mint_to( + CpiContext::new_with_signer( + ctx.accounts.token_program.to_account_info(), + token::MintTo { + mint: ctx.accounts.mint.to_account_info(), + to: ctx.accounts.recipient_token.to_account_info(), + authority: ctx.accounts.config.to_account_info(), + }, + &[&[Config::SEED_PREFIX, &[ctx.accounts.config.bump]]], + ), + amount, + ) +} diff --git a/cross-chain/solana/programs/tbtc/src/processor/mod.rs b/cross-chain/solana/programs/tbtc/src/processor/mod.rs new file mode 100644 index 000000000..e54b71164 --- /dev/null +++ b/cross-chain/solana/programs/tbtc/src/processor/mod.rs @@ -0,0 +1,5 @@ +mod admin; +pub use admin::*; + +mod mint; +pub use mint::*; diff --git a/cross-chain/solana/programs/tbtc/src/state/config.rs b/cross-chain/solana/programs/tbtc/src/state/config.rs new file mode 100644 index 000000000..497200848 --- /dev/null +++ b/cross-chain/solana/programs/tbtc/src/state/config.rs @@ -0,0 +1,24 @@ +use anchor_lang::prelude::*; + +#[account] +#[derive(Debug, InitSpace)] +pub struct Config { + pub bump: u8, + + /// The authority over this program. + pub authority: Pubkey, + pub pending_authority: Option, + + // Mint info. + pub mint: Pubkey, + pub mint_bump: u8, + + // Admin info. + pub num_minters: u8, + pub num_guardians: u8, + pub paused: bool, +} + +impl Config { + pub const SEED_PREFIX: &'static [u8] = b"config"; +} diff --git a/cross-chain/solana/programs/tbtc/src/state/guardian_info.rs b/cross-chain/solana/programs/tbtc/src/state/guardian_info.rs new file mode 100644 index 000000000..34f1492ba --- /dev/null +++ b/cross-chain/solana/programs/tbtc/src/state/guardian_info.rs @@ -0,0 +1,12 @@ +use anchor_lang::prelude::*; + +#[account] +#[derive(Debug, InitSpace)] +pub struct GuardianInfo { + pub guardian: Pubkey, + pub bump: u8, +} + +impl GuardianInfo { + pub const SEED_PREFIX: &'static [u8] = b"guardian-info"; +} diff --git a/cross-chain/solana/programs/tbtc/src/state/minter_info.rs b/cross-chain/solana/programs/tbtc/src/state/minter_info.rs new file mode 100644 index 000000000..e8b6a6eeb --- /dev/null +++ b/cross-chain/solana/programs/tbtc/src/state/minter_info.rs @@ -0,0 +1,12 @@ +use anchor_lang::prelude::*; + +#[account] +#[derive(Debug, InitSpace)] +pub struct MinterInfo { + pub minter: Pubkey, + pub bump: u8, +} + +impl MinterInfo { + pub const SEED_PREFIX: &'static [u8] = b"minter-info"; +} diff --git a/cross-chain/solana/programs/tbtc/src/state/mod.rs b/cross-chain/solana/programs/tbtc/src/state/mod.rs new file mode 100644 index 000000000..dffd4099b --- /dev/null +++ b/cross-chain/solana/programs/tbtc/src/state/mod.rs @@ -0,0 +1,8 @@ +mod config; +pub use config::*; + +mod guardian_info; +pub use guardian_info::*; + +mod minter_info; +pub use minter_info::*; diff --git a/cross-chain/solana/programs/wormhole-gateway/Cargo.toml b/cross-chain/solana/programs/wormhole-gateway/Cargo.toml new file mode 100644 index 000000000..6df2961fc --- /dev/null +++ b/cross-chain/solana/programs/wormhole-gateway/Cargo.toml @@ -0,0 +1,26 @@ +[package] +name = "wormhole-gateway" +version = "0.1.0" +description = "Created with Anchor" +edition = "2021" + +[lib] +crate-type = ["cdylib", "lib"] +name = "wormhole_gateway" + +[features] +default = ["mainnet"] +mainnet = ["wormhole-anchor-sdk/mainnet"] +solana-devnet = ["wormhole-anchor-sdk/solana-devnet"] +no-entrypoint = [] +no-idl = [] +no-log-ix-name = [] +cpi = ["no-entrypoint"] + +[dependencies] +anchor-lang = { version = "0.28.0", features = ["init-if-needed"]} +anchor-spl = "0.28.0" + +wormhole-anchor-sdk = { git = "https://github.com/wormhole-foundation/wormhole-scaffolding", rev = "f8d5ba04bfd449ab3693b15c818fd3e85e30f758", features = ["token-bridge"], default-features = false } + +tbtc = { path = "../tbtc", features = ["cpi"] } \ No newline at end of file diff --git a/cross-chain/solana/programs/wormhole-gateway/Xargo.toml b/cross-chain/solana/programs/wormhole-gateway/Xargo.toml new file mode 100644 index 000000000..475fb71ed --- /dev/null +++ b/cross-chain/solana/programs/wormhole-gateway/Xargo.toml @@ -0,0 +1,2 @@ +[target.bpfel-unknown-unknown.dependencies.std] +features = [] diff --git a/cross-chain/solana/programs/wormhole-gateway/src/error.rs b/cross-chain/solana/programs/wormhole-gateway/src/error.rs new file mode 100644 index 000000000..09a8b136c --- /dev/null +++ b/cross-chain/solana/programs/wormhole-gateway/src/error.rs @@ -0,0 +1,22 @@ +use anchor_lang::prelude::error_code; + +#[error_code] +pub enum WormholeGatewayError { + #[msg("Cannot mint more than the minting limit.")] + MintingLimitExceeded = 0x10, + + #[msg("Only custodian authority is permitted for this action.")] + IsNotAuthority = 0x20, + + #[msg("0x0 recipient not allowed")] + ZeroRecipient = 0x30, + + #[msg("Not enough wormhole tBTC in the gateway to bridge")] + NotEnoughWrappedTbtc = 0x40, + + #[msg("Amount must not be 0")] + ZeroAmount = 0x50, + + #[msg("Amount too low to bridge")] + TruncatedZeroAmount = 0x60, +} diff --git a/cross-chain/solana/programs/wormhole-gateway/src/lib.rs b/cross-chain/solana/programs/wormhole-gateway/src/lib.rs new file mode 100644 index 000000000..b58d6d681 --- /dev/null +++ b/cross-chain/solana/programs/wormhole-gateway/src/lib.rs @@ -0,0 +1,65 @@ +#![allow(clippy::result_large_err)] + +pub mod error; + +mod processor; +pub(crate) use processor::*; + +mod state; +pub use state::*; + +use anchor_lang::prelude::*; + +declare_id!("8H9F5JGbEMyERycwaGuzLS5MQnV7dn2wm2h6egJ3Leiu"); + +#[derive(Clone)] +pub struct WormholeGateway; + +impl Id for WormholeGateway { + fn id() -> Pubkey { + ID + } +} + +#[program] +pub mod wormhole_gateway { + + use super::*; + + pub fn initialize(ctx: Context, minting_limit: u64) -> Result<()> { + processor::initialize(ctx, minting_limit) + } + + pub fn update_gateway_address( + ctx: Context, + args: UpdateGatewayAddressArgs, + ) -> Result<()> { + processor::update_gateway_address(ctx, args) + } + + pub fn update_minting_limit(ctx: Context, new_limit: u64) -> Result<()> { + processor::update_minting_limit(ctx, new_limit) + } + + // pub fn receive_tbtc(ctx: Context) -> Result<()> { + // processor::receive_tbtc(ctx) + // } + + pub fn send_tbtc_gateway( + ctx: Context, + args: SendTbtcGatewayArgs, + ) -> Result<()> { + processor::send_tbtc_gateway(ctx, args) + } + + pub fn send_tbtc_wrapped( + ctx: Context, + args: SendTbtcWrappedArgs, + ) -> Result<()> { + processor::send_tbtc_wrapped(ctx, args) + } + + pub fn deposit_wormhole_tbtc(ctx: Context, amount: u64) -> Result<()> { + processor::deposit_wormhole_tbtc(ctx, amount) + } +} diff --git a/cross-chain/solana/programs/wormhole-gateway/src/processor/deposit_wormhole_tbtc.rs b/cross-chain/solana/programs/wormhole-gateway/src/processor/deposit_wormhole_tbtc.rs new file mode 100644 index 000000000..28ccdc59a --- /dev/null +++ b/cross-chain/solana/programs/wormhole-gateway/src/processor/deposit_wormhole_tbtc.rs @@ -0,0 +1,105 @@ +use crate::{error::WormholeGatewayError, state::Custodian}; +use anchor_lang::prelude::*; +use anchor_spl::token; + +#[derive(Accounts)] +#[instruction(amount: u64)] +pub struct DepositWormholeTbtc<'info> { + /// NOTE: This account also acts as a minter for the TBTC program. + #[account( + seeds = [Custodian::SEED_PREFIX], + bump = custodian.bump, + has_one = wrapped_tbtc_token, + has_one = wrapped_tbtc_mint, + has_one = tbtc_mint, + )] + custodian: Account<'info, Custodian>, + + /// This token account is owned by this program, whose mint is the wrapped TBTC mint. This PDA + /// address is stored in the custodian account. + #[account(mut)] + wrapped_tbtc_token: Box>, + + /// This mint is owned by the Wormhole Token Bridge program. This PDA address is stored in the + /// custodian account. + wrapped_tbtc_mint: Box>, + + /// This mint is owned by the TBTC program. This PDA address is stored in the custodian account. + #[account(mut)] + tbtc_mint: Account<'info, token::Mint>, + + #[account( + mut, + token::mint = wrapped_tbtc_mint, + token::authority = recipient + )] + recipient_wrapped_token: Box>, + + // Use the associated token account for the recipient. + #[account( + mut, + token::mint = tbtc_mint, + token::authority = recipient, + )] + recipient_token: Box>, + + /// This program requires that the owner of the TBTC token account sign for TBTC being minted + /// into his account. + recipient: Signer<'info>, + + /// CHECK: TBTC program requires this account. + tbtc_config: UncheckedAccount<'info>, + + /// CHECK: TBTC program requires this account. + minter_info: UncheckedAccount<'info>, + + token_program: Program<'info, token::Token>, + tbtc_program: Program<'info, tbtc::Tbtc>, +} + +impl<'info> DepositWormholeTbtc<'info> { + fn constraints(ctx: &Context, amount: u64) -> Result<()> { + require_gt!( + ctx.accounts.custodian.minting_limit, + ctx.accounts.tbtc_mint.supply.saturating_add(amount), + WormholeGatewayError::MintingLimitExceeded + ); + + Ok(()) + } +} + +#[access_control(DepositWormholeTbtc::constraints(&ctx, amount))] +pub fn deposit_wormhole_tbtc(ctx: Context, amount: u64) -> Result<()> { + // First transfer wrapped tokens to custody account. + token::transfer( + CpiContext::new( + ctx.accounts.token_program.to_account_info(), + token::Transfer { + from: ctx.accounts.recipient_wrapped_token.to_account_info(), + to: ctx.accounts.wrapped_tbtc_token.to_account_info(), + authority: ctx.accounts.recipient.to_account_info(), + }, + ), + amount, + )?; + + let custodian = &ctx.accounts.custodian; + + // Now mint. + tbtc::cpi::mint( + CpiContext::new_with_signer( + ctx.accounts.tbtc_program.to_account_info(), + tbtc::cpi::accounts::Mint { + mint: ctx.accounts.tbtc_mint.to_account_info(), + config: ctx.accounts.tbtc_config.to_account_info(), + minter_info: ctx.accounts.minter_info.to_account_info(), + minter: custodian.to_account_info(), + recipient_token: ctx.accounts.recipient_token.to_account_info(), + token_program: ctx.accounts.token_program.to_account_info(), + }, + &[&[Custodian::SEED_PREFIX, &[custodian.bump]]], + ), + amount, + ) +} diff --git a/cross-chain/solana/programs/wormhole-gateway/src/processor/initialize.rs b/cross-chain/solana/programs/wormhole-gateway/src/processor/initialize.rs new file mode 100644 index 000000000..f73831546 --- /dev/null +++ b/cross-chain/solana/programs/wormhole-gateway/src/processor/initialize.rs @@ -0,0 +1,100 @@ +use crate::state::Custodian; +use anchor_lang::prelude::*; +use anchor_spl::token; +use wormhole_anchor_sdk::token_bridge; + +const TBTC_FOREIGN_TOKEN_CHAIN: u8 = 2; + +#[cfg(feature = "mainnet")] +const TBTC_FOREIGN_TOKEN_ADDRESS: [u8; 32] = [ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x18, 0x08, 0x4f, 0xbA, 0x66, 0x6a, + 0x33, 0xd3, 0x75, 0x92, 0xfA, 0x26, 0x33, 0xfD, 0x49, 0xa7, 0x4D, 0xD9, 0x3a, 0x88, +]; + +/// TODO: Fix this to reflect testnet contract address. +#[cfg(feature = "solana-devnet")] +const TBTC_FOREIGN_TOKEN_ADDRESS: [u8; 32] = [ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x18, 0x08, 0x4f, 0xbA, 0x66, 0x6a, + 0x33, 0xd3, 0x75, 0x92, 0xfA, 0x26, 0x33, 0xfD, 0x49, 0xa7, 0x4D, 0xD9, 0x3a, 0x88, +]; + +#[derive(Accounts)] +pub struct Initialize<'info> { + #[account(mut)] + authority: Signer<'info>, + + #[account( + init, + payer = authority, + space = 8 + Custodian::INIT_SPACE, + seeds = [Custodian::SEED_PREFIX], + bump, + )] + custodian: Account<'info, Custodian>, + + /// TBTC Program's mint PDA address bump is saved in this program's config. Ordinarily, we would + /// not have to deserialize this account. But we do in this case to make sure the TBTC program + /// has been initialized before this program. + #[account( + seeds = [tbtc::SEED_PREFIX_TBTC_MINT], + bump, + seeds::program = tbtc::ID + )] + tbtc_mint: Account<'info, token::Mint>, + + #[account( + seeds = [ + token_bridge::WrappedMint::SEED_PREFIX, + &TBTC_FOREIGN_TOKEN_CHAIN.to_be_bytes(), + TBTC_FOREIGN_TOKEN_ADDRESS.as_ref() + ], + bump + )] + wrapped_tbtc_mint: Account<'info, token::Mint>, + + #[account( + init, + payer = authority, + token::mint = wrapped_tbtc_mint, + token::authority = authority, + seeds = [b"wrapped-token"], + bump + )] + wrapped_tbtc_token: Account<'info, token::TokenAccount>, + + /// CHECK: This account is needed for the Token Bridge program. This PDA is specifically used to + /// sign for transferring via Token Bridge program with a message. + #[account( + seeds = [token_bridge::SEED_PREFIX_SENDER], + bump, + )] + token_bridge_sender: AccountInfo<'info>, + + /// CHECK: This account is needed for the Token Bridge program. This PDA is specifically used to + /// sign for transferring via Token Bridge program with a message. + #[account( + seeds = [token_bridge::SEED_PREFIX_REDEEMER], + bump, + )] + token_bridge_redeemer: AccountInfo<'info>, + + system_program: Program<'info, System>, + token_program: Program<'info, token::Token>, +} + +pub fn initialize(ctx: Context, minting_limit: u64) -> Result<()> { + ctx.accounts.custodian.set_inner(Custodian { + bump: ctx.bumps["config"], + authority: ctx.accounts.authority.key(), + tbtc_mint: ctx.accounts.tbtc_mint.key(), + wrapped_tbtc_mint: ctx.accounts.wrapped_tbtc_mint.key(), + wrapped_tbtc_token: ctx.accounts.wrapped_tbtc_token.key(), + token_bridge_sender: ctx.accounts.token_bridge_sender.key(), + token_bridge_sender_bump: ctx.bumps["token_bridge_sender"], + token_bridge_redeemer: ctx.accounts.token_bridge_sender.key(), + token_bridge_redeemer_bump: ctx.bumps["token_bridge_redeemer"], + minting_limit, + }); + + Ok(()) +} diff --git a/cross-chain/solana/programs/wormhole-gateway/src/processor/mod.rs b/cross-chain/solana/programs/wormhole-gateway/src/processor/mod.rs new file mode 100644 index 000000000..8948c9b82 --- /dev/null +++ b/cross-chain/solana/programs/wormhole-gateway/src/processor/mod.rs @@ -0,0 +1,17 @@ +mod deposit_wormhole_tbtc; +pub use deposit_wormhole_tbtc::*; + +mod initialize; +pub use initialize::*; + +// mod receive_tbtc; +// pub use receive_tbtc::*; + +mod send_tbtc; +pub use send_tbtc::*; + +mod update_gateway_address; +pub use update_gateway_address::*; + +mod update_minting_limit; +pub use update_minting_limit::*; diff --git a/cross-chain/solana/programs/wormhole-gateway/src/processor/receive_tbtc.rs b/cross-chain/solana/programs/wormhole-gateway/src/processor/receive_tbtc.rs new file mode 100644 index 000000000..b3cc68d83 --- /dev/null +++ b/cross-chain/solana/programs/wormhole-gateway/src/processor/receive_tbtc.rs @@ -0,0 +1,77 @@ +use crate::state::Custodian; +use anchor_lang::prelude::*; +use anchor_spl::token; + +#[derive(Accounts)] +pub struct ReceiveTbtc<'info> { + #[account(mut)] + payer: Signer<'info>, + + /// NOTE: This account also acts as a minter for the TBTC program. + #[account( + seeds = [Custodian::SEED_PREFIX], + bump = custodian.bump, + has_one = wrapped_tbtc_token, + has_one = wrapped_tbtc_mint, + has_one = tbtc_mint, + )] + custodian: Account<'info, Custodian>, + + // TODO: posted_vaa + #[account(mut)] + tbtc_mint: Account<'info, token::Mint>, + + /// CHECK: This account is needed fot the TBTC program. + tbtc_config: UncheckedAccount<'info>, + + /// CHECK: This account is needed fot the TBTC program. + minter_info: UncheckedAccount<'info>, + + // Use the associated token account for the recipient. + #[account( + associated_token::mint = tbtc_mint, + associated_token::authority = recipient, + )] + pub recipient_account: Account<'info, token::TokenAccount>, + + /// CHECK: the recipient doesn't need to sign the mint, + /// and it doesn't conform to any specific rules. + /// Validating the recipient is the minter's responsibility. + recipient: AccountInfo<'info>, +} + +pub fn receive_tbtc(ctx: Context) -> Result<()> { + // get balance delta + + let amount = _; + + let minted_amount = ctx.accounts.wormhole_gateway.minted_amount; + let minting_limit = ctx.accounts.wormhole_gateway.minting_limit; + + if (minted_amount + amount > minting_limit) { + // transfer bridge token + } else { + ctx.accounts.wormhole_gateway.minted_amount += amount; + + let seed_prefix = Config::SEED_PREFIX; + let key_seed = ctx.accounts.wormhole_gateway.key(); + let gateway_bump = ctx.accounts.wormhole_gateway.self_bump; + + let signer: &[&[&[u8]]] = &[&[seed_prefix, key_seed.as_ref(), &[gateway_bump]]]; + + let mint_cpi_ctx = CpiContext::new_with_signer( + ctx.accounts.tbtc.to_account_info(), + tbtc::Mint { + tbtc_mint: ctx.accounts.tbtc_mint.to_account_info(), + tbtc: ctx.accounts.tbtc.to_account_info(), + minter_info: ctx.accounts.minter_info.to_account_info(), + minter: ctx.accounts.wormhole_gateway.to_account_info(), + recipient_account: ctx.accounts.recipient_account.to_account_info(), + recipient: ctx.accounts.recipient.to_account_info(), + payer: ctx.accounts.payer.to_account_info(), + }, + signer, + ); + tbtc::mint(mint_cpi_ctx, amount) + } +} diff --git a/cross-chain/solana/programs/wormhole-gateway/src/processor/send_tbtc/gateway.rs b/cross-chain/solana/programs/wormhole-gateway/src/processor/send_tbtc/gateway.rs new file mode 100644 index 000000000..babd8a490 --- /dev/null +++ b/cross-chain/solana/programs/wormhole-gateway/src/processor/send_tbtc/gateway.rs @@ -0,0 +1,187 @@ +use crate::state::{Custodian, GatewayInfo}; +use anchor_lang::prelude::*; +use anchor_spl::token; +use wormhole_anchor_sdk::{ + token_bridge::{self, program::TokenBridge}, + wormhole::{self as core_bridge, program::Wormhole as CoreBridge}, +}; + +#[derive(Accounts)] +#[instruction(args: SendTbtcGatewayArgs)] +pub struct SendTbtcGateway<'info> { + #[account( + seeds = [Custodian::SEED_PREFIX], + bump = custodian.bump, + has_one = wrapped_tbtc_token, + has_one = wrapped_tbtc_mint, + has_one = tbtc_mint, + has_one = token_bridge_sender, + )] + custodian: Account<'info, Custodian>, + + #[account( + seeds = [GatewayInfo::SEED_PREFIX, &args.recipient_chain.to_le_bytes()], + bump = gateway_info.bump, + )] + gateway_info: Account<'info, GatewayInfo>, + + /// Custody account. + wrapped_tbtc_token: Box>, + + /// CHECK: This account is needed for the Token Bridge program. + wrapped_tbtc_mint: UncheckedAccount<'info>, + + #[account(mut)] + tbtc_mint: Box>, + + #[account( + mut, + token::mint = tbtc_mint, + token::authority = sender + )] + sender_token: Box>, + + #[account(mut)] + sender: Signer<'info>, + + /// CHECK: This account is needed for the Token Bridge program. + token_bridge_config: UncheckedAccount<'info>, + + /// CHECK: This account is needed for the Token Bridge program. + token_bridge_wrapped_asset: UncheckedAccount<'info>, + + /// CHECK: This account is needed for the Token Bridge program. + token_bridge_transfer_authority: UncheckedAccount<'info>, + + /// CHECK: This account is needed for the Token Bridge program. + #[account(mut)] + core_bridge: UncheckedAccount<'info>, + + /// CHECK: This account is needed for the Token Bridge program. + #[account( + mut, + seeds = [b"msg", &core_emitter_sequence.value().to_le_bytes()], + bump, + )] + core_message: AccountInfo<'info>, + + /// CHECK: This account is needed for the Token Bridge program. + token_bridge_core_emitter: UncheckedAccount<'info>, + + /// CHECK: This account is needed for the Token Bridge program. + #[account(mut)] + core_emitter_sequence: Account<'info, core_bridge::SequenceTracker>, + + /// CHECK: This account is needed for the Token Bridge program. + #[account(mut)] + core_fee_collector: UncheckedAccount<'info>, + + /// CHECK: This account is needed for the Token Bridge program. + clock: UncheckedAccount<'info>, + + /// CHECK: This account is needed for the Token Bridge program. This PDA is specifically used to + /// sign for transferring via Token Bridge program with a message. + token_bridge_sender: AccountInfo<'info>, + + /// CHECK: This account is needed for the Token Bridge program. + rent: UncheckedAccount<'info>, + + token_bridge_program: Program<'info, TokenBridge>, + core_bridge_program: Program<'info, CoreBridge>, + token_program: Program<'info, token::Token>, + system_program: Program<'info, System>, +} + +impl<'info> SendTbtcGateway<'info> { + fn constraints(ctx: &Context, args: &SendTbtcGatewayArgs) -> Result<()> { + super::validate_send( + &ctx.accounts.wrapped_tbtc_token, + &args.recipient, + args.amount, + ) + } +} + +#[derive(Debug, Clone, AnchorSerialize, AnchorDeserialize)] +pub struct SendTbtcGatewayArgs { + amount: u64, + recipient_chain: u16, + recipient: [u8; 32], + nonce: u32, +} + +#[access_control(SendTbtcGateway::constraints(&ctx, &args))] +pub fn send_tbtc_gateway(ctx: Context, args: SendTbtcGatewayArgs) -> Result<()> { + let SendTbtcGatewayArgs { + amount, + recipient_chain, + recipient, + nonce, + } = args; + + let sender = &ctx.accounts.sender; + let custodian = &ctx.accounts.custodian; + let wrapped_tbtc_token = &ctx.accounts.wrapped_tbtc_token; + let token_bridge_transfer_authority = &ctx.accounts.token_bridge_transfer_authority; + let token_program = &ctx.accounts.token_program; + + // Prepare for wrapped tBTC transfer (this method also truncates the amount to prevent having to + // handle dust since tBTC has >8 decimals). + let amount = super::burn_and_prepare_transfer( + super::PrepareTransfer { + custodian, + tbtc_mint: &ctx.accounts.tbtc_mint, + sender_token: &ctx.accounts.sender_token, + sender, + wrapped_tbtc_token, + token_bridge_transfer_authority, + token_program, + }, + amount, + )?; + + // Finally transfer wrapped tBTC with the recipient encoded as this transfer's message. + token_bridge::transfer_wrapped_with_payload( + CpiContext::new_with_signer( + ctx.accounts.token_bridge_program.to_account_info(), + token_bridge::TransferWrappedWithPayload { + payer: sender.to_account_info(), + config: ctx.accounts.token_bridge_config.to_account_info(), + from: wrapped_tbtc_token.to_account_info(), + from_owner: custodian.to_account_info(), + wrapped_mint: ctx.accounts.wrapped_tbtc_mint.to_account_info(), + wrapped_metadata: ctx.accounts.token_bridge_wrapped_asset.to_account_info(), + authority_signer: token_bridge_transfer_authority.to_account_info(), + wormhole_bridge: ctx.accounts.core_bridge.to_account_info(), + wormhole_message: ctx.accounts.core_message.to_account_info(), + wormhole_emitter: ctx.accounts.token_bridge_core_emitter.to_account_info(), + wormhole_sequence: ctx.accounts.core_emitter_sequence.to_account_info(), + wormhole_fee_collector: ctx.accounts.core_fee_collector.to_account_info(), + clock: ctx.accounts.clock.to_account_info(), + sender: ctx.accounts.token_bridge_sender.to_account_info(), + rent: ctx.accounts.rent.to_account_info(), + system_program: ctx.accounts.system_program.to_account_info(), + token_program: token_program.to_account_info(), + wormhole_program: ctx.accounts.core_bridge_program.to_account_info(), + }, + &[ + &[Custodian::SEED_PREFIX, &[custodian.bump]], + &[ + token_bridge::SEED_PREFIX_SENDER, + &[ctx.accounts.custodian.token_bridge_sender_bump], + ], + &[ + b"msg", + &ctx.accounts.core_emitter_sequence.value().to_le_bytes(), + &[ctx.bumps["core_message"]], + ], + ], + ), + nonce, + amount, + ctx.accounts.gateway_info.address, + recipient_chain, + recipient.to_vec(), + &crate::ID, + ) +} diff --git a/cross-chain/solana/programs/wormhole-gateway/src/processor/send_tbtc/mod.rs b/cross-chain/solana/programs/wormhole-gateway/src/processor/send_tbtc/mod.rs new file mode 100644 index 000000000..a1b89550f --- /dev/null +++ b/cross-chain/solana/programs/wormhole-gateway/src/processor/send_tbtc/mod.rs @@ -0,0 +1,82 @@ +mod gateway; +pub use gateway::*; + +mod wrapped; +pub use wrapped::*; + +use crate::error::WormholeGatewayError; +use crate::state::Custodian; +use anchor_lang::prelude::*; +use anchor_spl::token; + +pub fn validate_send( + wrapped_tbtc_token: &Account<'_, token::TokenAccount>, + recipient: &[u8; 32], + amount: u64, +) -> Result<()> { + require!(*recipient != [0; 32], WormholeGatewayError::ZeroRecipient); + require_gt!(amount, 0, WormholeGatewayError::ZeroAmount); + + // Check that the wrapped tBTC in custody is at least enough to bridge out. + require_gte!( + wrapped_tbtc_token.amount, + amount, + WormholeGatewayError::NotEnoughWrappedTbtc + ); + + Ok(()) +} + +pub struct PrepareTransfer<'ctx, 'info> { + custodian: &'ctx Account<'info, Custodian>, + tbtc_mint: &'ctx Account<'info, token::Mint>, + sender_token: &'ctx Account<'info, token::TokenAccount>, + sender: &'ctx Signer<'info>, + wrapped_tbtc_token: &'ctx Account<'info, token::TokenAccount>, + token_bridge_transfer_authority: &'ctx AccountInfo<'info>, + token_program: &'ctx Program<'info, token::Token>, +} + +pub fn burn_and_prepare_transfer(prepare_transfer: PrepareTransfer, amount: u64) -> Result { + let PrepareTransfer { + custodian, + tbtc_mint, + sender_token, + sender, + wrapped_tbtc_token, + token_bridge_transfer_authority, + token_program, + } = prepare_transfer; + + let truncated = 10 * (amount / 10); + require_gt!(truncated, 0, WormholeGatewayError::TruncatedZeroAmount); + + // Burn TBTC mint. + token::burn( + CpiContext::new( + token_program.to_account_info(), + token::Burn { + mint: tbtc_mint.to_account_info(), + from: sender_token.to_account_info(), + authority: sender.to_account_info(), + }, + ), + amount, + )?; + + // Delegate authority to Token Bridge's transfer authority. + token::approve( + CpiContext::new_with_signer( + token_program.to_account_info(), + token::Approve { + to: wrapped_tbtc_token.to_account_info(), + delegate: token_bridge_transfer_authority.to_account_info(), + authority: custodian.to_account_info(), + }, + &[&[Custodian::SEED_PREFIX, &[custodian.bump]]], + ), + truncated, + )?; + + Ok(truncated) +} diff --git a/cross-chain/solana/programs/wormhole-gateway/src/processor/send_tbtc/wrapped.rs b/cross-chain/solana/programs/wormhole-gateway/src/processor/send_tbtc/wrapped.rs new file mode 100644 index 000000000..37ba459c5 --- /dev/null +++ b/cross-chain/solana/programs/wormhole-gateway/src/processor/send_tbtc/wrapped.rs @@ -0,0 +1,179 @@ +use crate::state::Custodian; +use anchor_lang::{prelude::*, solana_program}; +use anchor_spl::token; +use wormhole_anchor_sdk::{ + token_bridge::{self, program::TokenBridge}, + wormhole::{self as core_bridge, program::Wormhole as CoreBridge}, +}; + +#[derive(Accounts)] +#[instruction(args: SendTbtcWrappedArgs)] +pub struct SendTbtcWrapped<'info> { + #[account( + seeds = [Custodian::SEED_PREFIX], + bump = custodian.bump, + has_one = wrapped_tbtc_token, + has_one = wrapped_tbtc_mint, + has_one = tbtc_mint, + )] + custodian: Account<'info, Custodian>, + + /// Custody account. + wrapped_tbtc_token: Box>, + + /// CHECK: This account is needed for the Token Bridge program. + wrapped_tbtc_mint: UncheckedAccount<'info>, + + #[account(mut)] + tbtc_mint: Box>, + + #[account( + mut, + token::mint = tbtc_mint, + token::authority = sender + )] + sender_token: Box>, + + #[account(mut)] + sender: Signer<'info>, + + /// CHECK: This account is needed for the Token Bridge program. + token_bridge_config: UncheckedAccount<'info>, + + /// CHECK: This account is needed for the Token Bridge program. + token_bridge_wrapped_asset: UncheckedAccount<'info>, + + /// CHECK: This account is needed for the Token Bridge program. + token_bridge_transfer_authority: UncheckedAccount<'info>, + + /// CHECK: This account is needed for the Token Bridge program. + #[account(mut)] + core_bridge: UncheckedAccount<'info>, + + /// CHECK: This account is needed for the Token Bridge program. + #[account( + mut, + seeds = [b"msg", &core_emitter_sequence.value().to_le_bytes()], + bump, + )] + core_message: AccountInfo<'info>, + + /// CHECK: This account is needed for the Token Bridge program. + token_bridge_core_emitter: UncheckedAccount<'info>, + + /// CHECK: This account is needed for the Token Bridge program. + #[account(mut)] + core_emitter_sequence: Account<'info, core_bridge::SequenceTracker>, + + /// CHECK: This account is needed for the Token Bridge program. + #[account(mut)] + core_fee_collector: UncheckedAccount<'info>, + + /// CHECK: This account is needed for the Token Bridge program. + clock: UncheckedAccount<'info>, + + /// CHECK: This account is needed for the Token Bridge program. + rent: UncheckedAccount<'info>, + + token_bridge_program: Program<'info, TokenBridge>, + core_bridge_program: Program<'info, CoreBridge>, + token_program: Program<'info, token::Token>, + system_program: Program<'info, System>, +} + +impl<'info> SendTbtcWrapped<'info> { + fn constraints(ctx: &Context, args: &SendTbtcWrappedArgs) -> Result<()> { + super::validate_send( + &ctx.accounts.wrapped_tbtc_token, + &args.recipient, + args.amount, + ) + } +} + +#[derive(Debug, Clone, AnchorSerialize, AnchorDeserialize)] +pub struct SendTbtcWrappedArgs { + amount: u64, + recipient_chain: u16, + recipient: [u8; 32], + arbiter_fee: u64, + nonce: u32, +} + +#[access_control(SendTbtcWrapped::constraints(&ctx, &args))] +pub fn send_tbtc_wrapped(ctx: Context, args: SendTbtcWrappedArgs) -> Result<()> { + let SendTbtcWrappedArgs { + amount, + recipient_chain, + recipient, + arbiter_fee, + nonce, + } = args; + + let sender = &ctx.accounts.sender; + let custodian = &ctx.accounts.custodian; + let wrapped_tbtc_token = &ctx.accounts.wrapped_tbtc_token; + let token_bridge_transfer_authority = &ctx.accounts.token_bridge_transfer_authority; + let token_program = &ctx.accounts.token_program; + + // Prepare for wrapped tBTC transfer. + let amount = super::burn_and_prepare_transfer( + super::PrepareTransfer { + custodian, + tbtc_mint: &ctx.accounts.tbtc_mint, + sender_token: &ctx.accounts.sender_token, + sender, + wrapped_tbtc_token, + token_bridge_transfer_authority, + token_program, + }, + amount, + )?; + + // Because the wormhole-anchor-sdk does not support relayable transfers (i.e. payload ID == 1), + // we need to construct the instruction from scratch and invoke it. + let ix = solana_program::instruction::Instruction { + program_id: ctx.accounts.token_bridge_program.key(), + accounts: vec![ + AccountMeta::new(sender.key(), true), + AccountMeta::new_readonly(ctx.accounts.token_bridge_config.key(), false), + AccountMeta::new(wrapped_tbtc_token.key(), false), + AccountMeta::new_readonly(custodian.key(), false), + AccountMeta::new(ctx.accounts.wrapped_tbtc_mint.key(), false), + AccountMeta::new_readonly(ctx.accounts.token_bridge_wrapped_asset.key(), false), + AccountMeta::new_readonly(token_bridge_transfer_authority.key(), false), + AccountMeta::new(ctx.accounts.core_bridge.key(), false), + AccountMeta::new(ctx.accounts.core_message.key(), true), + AccountMeta::new_readonly(ctx.accounts.token_bridge_core_emitter.key(), false), + AccountMeta::new(ctx.accounts.core_emitter_sequence.key(), false), + AccountMeta::new(ctx.accounts.core_fee_collector.key(), false), + AccountMeta::new_readonly(ctx.accounts.clock.key(), false), + AccountMeta::new_readonly(ctx.accounts.rent.key(), false), + AccountMeta::new_readonly(ctx.accounts.system_program.key(), false), + AccountMeta::new_readonly(ctx.accounts.core_bridge_program.key(), false), + AccountMeta::new_readonly(token_program.key(), false), + ], + data: token_bridge::Instruction::TransferWrapped { + batch_id: nonce, + amount, + fee: arbiter_fee, + recipient_address: recipient, + recipient_chain, + } + .try_to_vec()?, + }; + + solana_program::program::invoke_signed( + &ix, + &ctx.accounts.to_account_infos(), + &[ + &[Custodian::SEED_PREFIX, &[custodian.bump]], + &[ + b"msg", + &ctx.accounts.core_emitter_sequence.value().to_le_bytes(), + &[ctx.bumps["core_message"]], + ], + ], + ) + .map_err(Into::into) +} diff --git a/cross-chain/solana/programs/wormhole-gateway/src/processor/update_gateway_address.rs b/cross-chain/solana/programs/wormhole-gateway/src/processor/update_gateway_address.rs new file mode 100644 index 000000000..6fcfbfed2 --- /dev/null +++ b/cross-chain/solana/programs/wormhole-gateway/src/processor/update_gateway_address.rs @@ -0,0 +1,50 @@ +use crate::{ + error::WormholeGatewayError, + state::{Custodian, GatewayInfo}, +}; +use anchor_lang::prelude::*; + +#[derive(Accounts)] +#[instruction(args: UpdateGatewayAddressArgs)] +pub struct UpdateGatewayAddress<'info> { + #[account( + seeds = [Custodian::SEED_PREFIX], + bump = custodian.bump, + has_one = authority @ WormholeGatewayError::IsNotAuthority, + )] + custodian: Account<'info, Custodian>, + + #[account( + init_if_needed, + payer = authority, + space = 8 + GatewayInfo::INIT_SPACE, + seeds = [GatewayInfo::SEED_PREFIX, &args.chain.to_le_bytes()], + bump, + )] + gateway_info: Account<'info, GatewayInfo>, + + #[account(mut)] + authority: Signer<'info>, + + system_program: Program<'info, System>, +} + +#[derive(Debug, Clone, AnchorSerialize, AnchorDeserialize)] +pub struct UpdateGatewayAddressArgs { + chain: u16, + address: [u8; 32], +} + +pub fn update_gateway_address( + ctx: Context, + args: UpdateGatewayAddressArgs, +) -> Result<()> { + let UpdateGatewayAddressArgs { address, .. } = args; + + ctx.accounts.gateway_info.set_inner(GatewayInfo { + bump: ctx.bumps["gateway_info"], + address, + }); + + Ok(()) +} diff --git a/cross-chain/solana/programs/wormhole-gateway/src/processor/update_minting_limit.rs b/cross-chain/solana/programs/wormhole-gateway/src/processor/update_minting_limit.rs new file mode 100644 index 000000000..b52b72df4 --- /dev/null +++ b/cross-chain/solana/programs/wormhole-gateway/src/processor/update_minting_limit.rs @@ -0,0 +1,20 @@ +use crate::{error::WormholeGatewayError, state::Custodian}; +use anchor_lang::prelude::*; + +#[derive(Accounts)] +pub struct UpdateMintingLimit<'info> { + #[account( + mut, + seeds = [Custodian::SEED_PREFIX], + bump = custodian.bump, + has_one = authority @ WormholeGatewayError::IsNotAuthority, + )] + custodian: Account<'info, Custodian>, + + authority: Signer<'info>, +} + +pub fn update_minting_limit(ctx: Context, new_limit: u64) -> Result<()> { + ctx.accounts.custodian.minting_limit = new_limit; + Ok(()) +} diff --git a/cross-chain/solana/programs/wormhole-gateway/src/state/custodian.rs b/cross-chain/solana/programs/wormhole-gateway/src/state/custodian.rs new file mode 100644 index 000000000..72882128d --- /dev/null +++ b/cross-chain/solana/programs/wormhole-gateway/src/state/custodian.rs @@ -0,0 +1,22 @@ +use anchor_lang::prelude::*; + +#[account] +#[derive(Debug, InitSpace)] +pub struct Custodian { + pub bump: u8, + pub authority: Pubkey, + + pub tbtc_mint: Pubkey, + pub wrapped_tbtc_mint: Pubkey, + pub wrapped_tbtc_token: Pubkey, + pub token_bridge_sender: Pubkey, + pub token_bridge_sender_bump: u8, + pub token_bridge_redeemer: Pubkey, + pub token_bridge_redeemer_bump: u8, + + pub minting_limit: u64, +} + +impl Custodian { + pub const SEED_PREFIX: &'static [u8] = b"custodian"; +} diff --git a/cross-chain/solana/programs/wormhole-gateway/src/state/gateway_info.rs b/cross-chain/solana/programs/wormhole-gateway/src/state/gateway_info.rs new file mode 100644 index 000000000..3d1171d3b --- /dev/null +++ b/cross-chain/solana/programs/wormhole-gateway/src/state/gateway_info.rs @@ -0,0 +1,12 @@ +use anchor_lang::prelude::*; + +#[account] +#[derive(Debug, InitSpace)] +pub struct GatewayInfo { + pub bump: u8, + pub address: [u8; 32], +} + +impl GatewayInfo { + pub const SEED_PREFIX: &'static [u8] = b"gateway-info"; +} diff --git a/cross-chain/solana/programs/wormhole-gateway/src/state/mod.rs b/cross-chain/solana/programs/wormhole-gateway/src/state/mod.rs new file mode 100644 index 000000000..8b8779a6a --- /dev/null +++ b/cross-chain/solana/programs/wormhole-gateway/src/state/mod.rs @@ -0,0 +1,5 @@ +mod custodian; +pub use custodian::*; + +mod gateway_info; +pub use gateway_info::*; diff --git a/cross-chain/solana/tests/01__tbtc.ts b/cross-chain/solana/tests/01__tbtc.ts new file mode 100644 index 000000000..0a70e3d93 --- /dev/null +++ b/cross-chain/solana/tests/01__tbtc.ts @@ -0,0 +1,712 @@ +import * as anchor from "@coral-xyz/anchor"; +import { Program, AnchorError } from "@coral-xyz/anchor"; +import * as spl from "@solana/spl-token"; +import * as web3 from '@solana/web3.js'; +import { Tbtc } from "../target/types/tbtc"; +import { expect } from 'chai'; +import { ASSOCIATED_PROGRAM_ID } from "@coral-xyz/anchor/dist/cjs/utils/token"; +import { transferLamports } from "./helpers/utils"; + +function maybeAuthorityAnd( + signer, + signers +) { + return signers.concat(signer instanceof (anchor.Wallet as any) ? [] : [signer]); +} + +async function setup( + program: Program, + authority +) { + const [config,] = getConfigPDA(program); + const [tbtcMintPDA, _] = getTokenPDA(program); + + await program.methods + .initialize() + .accounts({ + mint: tbtcMintPDA, + config, + authority: authority.publicKey + }) + .rpc(); +} + +async function checkState( + program: Program, + expectedAuthority, + expectedMinters, + expectedGuardians, + expectedTokensSupply +) { + const [config,] = getConfigPDA(program); + let configState = await program.account.config.fetch(config); + + expect(configState.authority).to.eql(expectedAuthority.publicKey); + expect(configState.numMinters).to.equal(expectedMinters); + expect(configState.numGuardians).to.equal(expectedGuardians); + + let tbtcMint = configState.mint; + + let mintState = await spl.getMint(program.provider.connection, tbtcMint); + + expect(mintState.supply).to.equal(BigInt(expectedTokensSupply)); +} + +async function changeAuthority( + program: Program, + authority, + newAuthority, +) { + const [config,] = getConfigPDA(program); + await program.methods + .changeAuthority() + .accounts({ + config, + authority: authority.publicKey, + newAuthority: newAuthority.publicKey, + }) + .signers(maybeAuthorityAnd(authority, [])) + .rpc(); +} + +async function takeAuthority( + program: Program, + newAuthority, +) { + const [config,] = getConfigPDA(program); + await program.methods + .takeAuthority() + .accounts({ + config, + pendingAuthority: newAuthority.publicKey, + }) + .signers(maybeAuthorityAnd(newAuthority, [])) + .rpc(); +} + +async function cancelAuthorityChange( + program: Program, + authority, +) { + const [config,] = getConfigPDA(program); + await program.methods + .cancelAuthorityChange() + .accounts({ + config, + authority: authority.publicKey, + }) + .signers(maybeAuthorityAnd(authority, [])) + .rpc(); +} + +async function checkPendingAuthority( + program: Program, + pendingAuthority, +) { + const [config,] = getConfigPDA(program); + let configState = await program.account.config.fetch(config); + expect(configState.pendingAuthority).to.eql(pendingAuthority.publicKey); +} + +async function checkNoPendingAuthority( + program: Program, +) { + const [config,] = getConfigPDA(program); + let configState = await program.account.config.fetch(config); + expect(configState.pendingAuthority).to.equal(null); +} + +async function checkPaused( + program: Program, + paused: boolean +) { + const [config,] = getConfigPDA(program); + let configState = await program.account.config.fetch(config); + expect(configState.paused).to.equal(paused); +} + + +function getConfigPDA( + program: Program, +): [anchor.web3.PublicKey, number] { + return web3.PublicKey.findProgramAddressSync( + [ + Buffer.from('config'), + ], + program.programId + ); +} + +function getTokenPDA( + program: Program, +): [anchor.web3.PublicKey, number] { + return web3.PublicKey.findProgramAddressSync( + [ + Buffer.from('tbtc-mint'), + ], + program.programId + ); +} + +function getMinterPDA( + program: Program, + minter +): [anchor.web3.PublicKey, number] { + return web3.PublicKey.findProgramAddressSync( + [ + Buffer.from('minter-info'), + minter.publicKey.toBuffer(), + ], + program.programId + ); +} + +async function addMinter( + program: Program, + authority, + minter, + payer +): Promise { + const [config,] = getConfigPDA(program); + const [minterInfoPDA, _] = getMinterPDA(program, minter); + await program.methods + .addMinter() + .accounts({ + config, + authority: authority.publicKey, + minter: minter.publicKey, + minterInfo: minterInfoPDA, + }) + .signers(maybeAuthorityAnd(authority, [])) + .rpc(); + return minterInfoPDA; +} + +async function checkMinter( + program: Program, + minter +) { + const [minterInfoPDA, bump] = getMinterPDA(program, minter); + let minterInfo = await program.account.minterInfo.fetch(minterInfoPDA); + + expect(minterInfo.minter).to.eql(minter.publicKey); + expect(minterInfo.bump).to.equal(bump); +} + +async function removeMinter( + program: Program, + authority, + minter, + minterInfo +) { + const [config,] = getConfigPDA(program); + await program.methods + .removeMinter() + .accounts({ + config, + authority: authority.publicKey, + minterInfo: minterInfo, + minter: minter.publicKey + }) + .signers(maybeAuthorityAnd(authority, [])) + .rpc(); +} + +function getGuardianPDA( + program: Program, + guardian +): [anchor.web3.PublicKey, number] { + return web3.PublicKey.findProgramAddressSync( + [ + Buffer.from('guardian-info'), + guardian.publicKey.toBuffer(), + ], + program.programId + ); +} + +async function addGuardian( + program: Program, + authority, + guardian, + payer +): Promise { + const [config,] = getConfigPDA(program); + const [guardianInfoPDA, _] = getGuardianPDA(program, guardian); + await program.methods + .addGuardian() + .accounts({ + config, + authority: authority.publicKey, + guardianInfo: guardianInfoPDA, + guardian: guardian.publicKey, + }) + .signers(maybeAuthorityAnd(authority, [])) + .rpc(); + return guardianInfoPDA; +} + +async function checkGuardian( + program: Program, + guardian +) { + const [guardianInfoPDA, bump] = getGuardianPDA(program, guardian); + let guardianInfo = await program.account.guardianInfo.fetch(guardianInfoPDA); + + expect(guardianInfo.guardian).to.eql(guardian.publicKey); + expect(guardianInfo.bump).to.equal(bump); +} + +async function removeGuardian( + program: Program, + authority, + guardian, + guardianInfo +) { + const [config,] = getConfigPDA(program); + await program.methods + .removeGuardian() + .accounts({ + config, + authority: authority.publicKey, + guardianInfo: guardianInfo, + guardian: guardian.publicKey + }) + .signers(maybeAuthorityAnd(authority, [])) + .rpc(); +} + +async function pause( + program: Program, + guardian +) { + const [config,] = getConfigPDA(program); + const [guardianInfoPDA, _] = getGuardianPDA(program, guardian); + await program.methods + .pause() + .accounts({ + config, + guardianInfo: guardianInfoPDA, + guardian: guardian.publicKey + }) + .signers([guardian]) + .rpc(); +} + +async function unpause( + program: Program, + authority +) { + const [config,] = getConfigPDA(program); + await program.methods + .unpause() + .accounts({ + config, + authority: authority.publicKey + }) + .signers(maybeAuthorityAnd(authority, [])) + .rpc(); +} + +async function mint( + program: Program, + minter, + minterInfoPDA, + recipient, + amount, + payer, +) { + const connection = program.provider.connection; + + const [config,] = getConfigPDA(program); + const [tbtcMintPDA, _] = getTokenPDA(program); + const recipientToken = spl.getAssociatedTokenAddressSync(tbtcMintPDA, recipient.publicKey); + + const tokenData = await spl.getAccount(connection, recipientToken).catch((err) => { + if (err instanceof spl.TokenAccountNotFoundError) { + return null; + } else { + throw err; + }; + }); + + if (tokenData === null) { + const tx = await web3.sendAndConfirmTransaction( + connection, + new web3.Transaction().add( + spl.createAssociatedTokenAccountIdempotentInstruction( + payer.publicKey, + recipientToken, + recipient.publicKey, + tbtcMintPDA, + ) + ), + [payer.payer] + ); + } + + + await program.methods + .mint(new anchor.BN(amount)) + .accounts({ + mint: tbtcMintPDA, + config, + minterInfo: minterInfoPDA, + minter: minter.publicKey, + recipientToken, + }) + .signers(maybeAuthorityAnd(payer, [minter])) + .rpc(); +} + +describe("tbtc", () => { + // Configure the client to use the local cluster. + anchor.setProvider(anchor.AnchorProvider.env()); + + const program = anchor.workspace.Tbtc as Program; + + const authority = (program.provider as anchor.AnchorProvider).wallet as anchor.Wallet; + const newAuthority = anchor.web3.Keypair.generate(); + const minterKeys = anchor.web3.Keypair.generate(); + const minter2Keys = anchor.web3.Keypair.generate(); + const impostorKeys = anchor.web3.Keypair.generate(); + const guardianKeys = anchor.web3.Keypair.generate(); + const guardian2Keys = anchor.web3.Keypair.generate(); + + const recipientKeys = anchor.web3.Keypair.generate(); + + it('setup', async () => { + await setup(program, authority); + await checkState(program, authority, 0, 0, 0); + }); + + it('change authority', async () => { + await checkState(program, authority, 0, 0, 0); + await checkNoPendingAuthority(program); + try { + await cancelAuthorityChange(program, authority); + chai.assert(false, "should've failed but didn't"); + } catch (_err) { + expect(_err).to.be.instanceOf(AnchorError); + const err: AnchorError = _err; + expect(err.error.errorCode.code).to.equal('NoPendingAuthorityChange'); + expect(err.program.equals(program.programId)).is.true; + } + try { + await takeAuthority(program, newAuthority); + chai.assert(false, "should've failed but didn't"); + } catch (_err) { + expect(_err).to.be.instanceOf(AnchorError); + const err: AnchorError = _err; + expect(err.error.errorCode.code).to.equal('NoPendingAuthorityChange'); + expect(err.program.equals(program.programId)).is.true; + } + + await changeAuthority(program, authority, newAuthority); + await checkPendingAuthority(program, newAuthority); + await takeAuthority(program, newAuthority); + await checkNoPendingAuthority(program); + await checkState(program, newAuthority, 0, 0, 0); + await changeAuthority(program, newAuthority, authority.payer); + try { + await takeAuthority(program, impostorKeys); + chai.assert(false, "should've failed but didn't"); + } catch (_err) { + expect(_err).to.be.instanceOf(AnchorError); + const err: AnchorError = _err; + expect(err.error.errorCode.code).to.equal('IsNotPendingAuthority'); + expect(err.program.equals(program.programId)).is.true; + } + try { + await takeAuthority(program, newAuthority); + chai.assert(false, "should've failed but didn't"); + } catch (_err) { + expect(_err).to.be.instanceOf(AnchorError); + const err: AnchorError = _err; + expect(err.error.errorCode.code).to.equal('IsNotPendingAuthority'); + expect(err.program.equals(program.programId)).is.true; + } + try { + await cancelAuthorityChange(program, authority); + chai.assert(false, "should've failed but didn't"); + } catch (_err) { + expect(_err).to.be.instanceOf(AnchorError); + const err: AnchorError = _err; + expect(err.error.errorCode.code).to.equal('IsNotAuthority'); + expect(err.program.equals(program.programId)).is.true; + } + await takeAuthority(program, authority); + + await checkState(program, authority, 0, 0, 0); + }) + + it('add minter', async () => { + await checkState(program, authority, 0, 0, 0); + await addMinter(program, authority, minterKeys, authority); + await checkMinter(program, minterKeys); + await checkState(program, authority, 1, 0, 0); + + // Transfer lamports to imposter. + await transferLamports(program.provider.connection, authority.payer, impostorKeys.publicKey, 1000000000); + // await web3.sendAndConfirmTransaction( + // program.provider.connection, + // new web3.Transaction().add( + // web3.SystemProgram.transfer({ + // fromPubkey: authority.publicKey, + // toPubkey: impostorKeys.publicKey, + // lamports: 1000000000, + // }) + // ), + // [authority.payer] + // ); + + try { + await addMinter(program, impostorKeys, minter2Keys, authority); + chai.assert(false, "should've failed but didn't"); + } catch (_err) { + expect(_err).to.be.instanceOf(AnchorError); + const err: AnchorError = _err; + expect(err.error.errorCode.code).to.equal('IsNotAuthority'); + expect(err.program.equals(program.programId)).is.true; + } + }); + + it('mint', async () => { + await checkState(program, authority, 1, 0, 0); + const [minterInfoPDA, _] = getMinterPDA(program, minterKeys); + await checkMinter(program, minterKeys); + + // await setupMint(program, authority, recipientKeys); + await mint(program, minterKeys, minterInfoPDA, recipientKeys, 1000, authority); + + await checkState(program, authority, 1, 0, 1000); + + // // Burn for next test. + // const ix = spl.createBurnCheckedInstruction( + // account, // PublicKey of Owner's Associated Token Account + // new PublicKey(MINT_ADDRESS), // Public Key of the Token Mint Address + // WALLET.publicKey, // Public Key of Owner's Wallet + // BURN_QUANTITY * (10**MINT_DECIMALS), // Number of tokens to burn + // MINT_DECIMALS // Number of Decimals of the Token Mint + // ) + + }); + + it('won\'t mint', async () => { + await checkState(program, authority, 1, 0, 1000); + const [minterInfoPDA, _] = getMinterPDA(program, minterKeys); + await checkMinter(program, minterKeys); + + // await setupMint(program, authority, recipientKeys); + + try { + await mint(program, impostorKeys, minterInfoPDA, recipientKeys, 1000, authority); + chai.assert(false, "should've failed but didn't"); + } catch (_err) { + expect(_err).to.be.instanceOf(AnchorError); + const err: AnchorError = _err; + expect(err.error.errorCode.code).to.equal('ConstraintSeeds'); + expect(err.program.equals(program.programId)).is.true; + } + }); + + it('use two minters', async () => { + await checkState(program, authority, 1, 0, 1000); + const [minterInfoPDA, _] = getMinterPDA(program, minterKeys); + await checkMinter(program, minterKeys); + const minter2InfoPDA = await addMinter(program, authority, minter2Keys, authority); + await checkMinter(program, minter2Keys); + await checkState(program, authority, 2, 0, 1000); + // await setupMint(program, authority, recipientKeys); + + // cannot mint with wrong keys + try { + await mint(program, minter2Keys, minterInfoPDA, recipientKeys, 1000, authority); + chai.assert(false, "should've failed but didn't"); + } catch (_err) { + expect(_err).to.be.instanceOf(AnchorError); + const err: AnchorError = _err; + expect(err.error.errorCode.code).to.equal('ConstraintSeeds'); + expect(err.program.equals(program.programId)).is.true; + } + + // cannot remove minter with wrong keys + try { + await removeMinter(program, authority, minter2Keys, minterInfoPDA); + chai.assert(false, "should've failed but didn't"); + } catch (_err) { + expect(_err).to.be.instanceOf(AnchorError); + const err: AnchorError = _err; + expect(err.error.errorCode.code).to.equal('ConstraintSeeds'); + expect(err.program.equals(program.programId)).is.true; + } + + await mint(program, minterKeys, minterInfoPDA, recipientKeys, 500, authority); + await checkState(program, authority, 2, 0, 1500); + }); + + it('remove minter', async () => { + await checkState(program, authority, 2, 0, 1500); + const [minter2InfoPDA, _] = getMinterPDA(program, minter2Keys); + await checkMinter(program, minter2Keys); + await removeMinter(program, authority, minter2Keys, minter2InfoPDA); + await checkState(program, authority, 1, 0, 1500); + }); + + it('won\'t remove minter', async () => { + await checkState(program, authority, 1, 0, 1500); + const [minterInfoPDA, _] = getMinterPDA(program, minterKeys); + await checkMinter(program, minterKeys); + + try { + await removeMinter(program, impostorKeys, minterKeys, minterInfoPDA); + chai.assert(false, "should've failed but didn't"); + } catch (_err) { + expect(_err).to.be.instanceOf(AnchorError); + const err: AnchorError = _err; + expect(err.error.errorCode.code).to.equal('IsNotAuthority'); + expect(err.program.equals(program.programId)).is.true; + } + + await removeMinter(program, authority, minterKeys, minterInfoPDA); + await checkState(program, authority, 0, 0, 1500); + + try { + await removeMinter(program, authority, minterKeys, minterInfoPDA); + chai.assert(false, "should've failed but didn't"); + } catch (_err) { + expect(_err).to.be.instanceOf(AnchorError); + const err: AnchorError = _err; + expect(err.error.errorCode.code).to.equal('AccountNotInitialized'); + expect(err.program.equals(program.programId)).is.true; + } + }); + + it('add guardian', async () => { + await checkState(program, authority, 0, 0, 1500); + await addGuardian(program, authority, guardianKeys, authority); + await checkGuardian(program, guardianKeys); + await checkState(program, authority, 0, 1, 1500); + + try { + await addGuardian(program, impostorKeys, guardian2Keys, authority); + chai.assert(false, "should've failed but didn't"); + } catch (_err) { + expect(_err).to.be.instanceOf(AnchorError); + const err: AnchorError = _err; + expect(err.error.errorCode.code).to.equal('IsNotAuthority'); + expect(err.program.equals(program.programId)).is.true; + } + }); + + it('remove guardian', async () => { + await checkState(program, authority, 0, 1, 1500); + const [guardianInfoPDA, _] = getGuardianPDA(program, guardianKeys); + await checkGuardian(program, guardianKeys); + + try { + await removeGuardian(program, impostorKeys, guardianKeys, guardianInfoPDA); + chai.assert(false, "should've failed but didn't"); + } catch (_err) { + expect(_err).to.be.instanceOf(AnchorError); + const err: AnchorError = _err; + expect(err.error.errorCode.code).to.equal('IsNotAuthority'); + expect(err.program.equals(program.programId)).is.true; + } + + await removeGuardian(program, authority, guardianKeys, guardianInfoPDA); + await checkState(program, authority, 0, 0, 1500); + + try { + await removeGuardian(program, authority, guardianKeys, guardianInfoPDA); + chai.assert(false, "should've failed but didn't"); + } catch (_err) { + expect(_err).to.be.instanceOf(AnchorError); + const err: AnchorError = _err; + expect(err.error.errorCode.code).to.equal('AccountNotInitialized'); + expect(err.program.equals(program.programId)).is.true; + } + }); + + it('pause', async () => { + await checkState(program, authority, 0, 0, 1500); + await addGuardian(program, authority, guardianKeys, authority); + await checkPaused(program, false); + await pause(program, guardianKeys); + await checkPaused(program, true); + }); + + it('unpause', async () => { + await checkState(program, authority, 0, 1, 1500); + await checkPaused(program, true); + await unpause(program, authority); + await checkPaused(program, false); + + try { + await unpause(program, authority); + + chai.assert(false, "should've failed but didn't"); + } catch (_err) { + expect(_err).to.be.instanceOf(AnchorError); + const err: AnchorError = _err; + expect(err.error.errorCode.code).to.equal('IsNotPaused'); + expect(err.program.equals(program.programId)).is.true; + } + }); + + it('won\'t mint when paused', async () => { + await checkState(program, authority, 0, 1, 1500); + const minterInfoPDA = await addMinter(program, authority, minterKeys, authority); + await pause(program, guardianKeys); + // await setupMint(program, authority, recipientKeys); + + try { + await mint(program, minterKeys, minterInfoPDA, recipientKeys, 1000, authority); + chai.assert(false, "should've failed but didn't"); + } catch (_err) { + expect(_err).to.be.instanceOf(AnchorError); + const err: AnchorError = _err; + expect(err.error.errorCode.code).to.equal('IsPaused'); + expect(err.program.equals(program.programId)).is.true; + } + + await unpause(program, authority); + await checkPaused(program, false); + }) + + it('use two guardians', async () => { + await checkState(program, authority, 1, 1, 1500); + const [guardianInfoPDA, _] = getGuardianPDA(program, guardianKeys); + await checkGuardian(program, guardianKeys); + await addGuardian(program, authority, guardian2Keys, authority); + await checkGuardian(program, guardian2Keys); + + await pause(program, guardianKeys); + + try { + await pause(program, guardian2Keys); + chai.assert(false, "should've failed but didn't"); + } catch (_err) { + expect(_err).to.be.instanceOf(AnchorError); + const err: AnchorError = _err; + expect(err.error.errorCode.code).to.equal('IsPaused'); + expect(err.program.equals(program.programId)).is.true; + } + + await unpause(program, authority); + await pause(program, guardian2Keys); + await checkPaused(program, true); + await unpause(program, authority); + + // cannot remove guardian with wrong keys + try { + await removeGuardian(program, authority, guardian2Keys, guardianInfoPDA); + chai.assert(false, "should've failed but didn't"); + } catch (_err) { + expect(_err).to.be.instanceOf(AnchorError); + const err: AnchorError = _err; + expect(err.error.errorCode.code).to.equal('ConstraintSeeds'); + expect(err.program.equals(program.programId)).is.true; + } + }); +}); diff --git a/cross-chain/solana/tests/02__wormholeGateway.ts b/cross-chain/solana/tests/02__wormholeGateway.ts new file mode 100644 index 000000000..69eb14fe3 --- /dev/null +++ b/cross-chain/solana/tests/02__wormholeGateway.ts @@ -0,0 +1,116 @@ +import * as mock from "@certusone/wormhole-sdk/lib/cjs/mock"; +import * as tokenBridge from "@certusone/wormhole-sdk/lib/cjs/solana/tokenBridge"; +import * as coreBridge from "@certusone/wormhole-sdk/lib/cjs/solana/wormhole"; +import { NodeWallet } from "@certusone/wormhole-sdk/lib/cjs/solana"; +import { parseTokenTransferVaa, postVaaSolana, redeemOnSolana, tryNativeToHexString } from "@certusone/wormhole-sdk"; +import * as anchor from "@coral-xyz/anchor"; +import { Program } from "@coral-xyz/anchor"; +import * as spl from "@solana/spl-token"; +import { expect } from 'chai'; +import { WormholeGateway } from "../target/types/wormhole_gateway"; +import { generatePayer, getOrCreateTokenAccount } from "./helpers/utils"; +import { web3 } from "@coral-xyz/anchor"; + +const SOLANA_CORE_BRIDGE_ADDRESS = "worm2ZoG2kUd4vFXhvjh93UUH596ayRfgQ2MgjNMTth"; +const SOLANA_TOKEN_BRIDGE_ADDRESS = "wormDTUJ6AWPNvk59vGQbDvGJmqbDTdgWgAqcLBCgUb"; +const ETHEREUM_TOKEN_BRIDGE_ADDRESS = "0x3ee18B2214AFF97000D974cf647E7C347E8fa585"; +const ETHEREUM_TBTC_ADDRESS = "0x18084fbA666a33d37592fA2633fD49a74DD93a88"; + +const GUARDIAN_SET_INDEX = 3; + +function getCustodianPDA( + program: Program, +): [anchor.web3.PublicKey, number] { + return web3.PublicKey.findProgramAddressSync( + [ + Buffer.from('custodian'), + ], + program.programId + ); +} + + +describe("wormhole-gateway", () => { + // Configure the client to use the local cluster. + anchor.setProvider(anchor.AnchorProvider.env()); + + const program = anchor.workspace.WormholeGateway as Program; + const connection = program.provider.connection; + + const authority = (program.provider as anchor.AnchorProvider).wallet as anchor.Wallet; + const newAuthority = anchor.web3.Keypair.generate(); + const minterKeys = anchor.web3.Keypair.generate(); + const minter2Keys = anchor.web3.Keypair.generate(); + const impostorKeys = anchor.web3.Keypair.generate(); + const guardianKeys = anchor.web3.Keypair.generate(); + const guardian2Keys = anchor.web3.Keypair.generate(); + + const recipientKeys = anchor.web3.Keypair.generate(); + + const ethereumTokenBridge = new mock.MockEthereumTokenBridge(ETHEREUM_TOKEN_BRIDGE_ADDRESS); + + it('check core bridge and token bridge', async () => { + // Check core bridge guardian set. + const guardianSetData = await coreBridge.getGuardianSet(connection, SOLANA_CORE_BRIDGE_ADDRESS, GUARDIAN_SET_INDEX); + expect(guardianSetData.keys).has.length(1); + + // Set up new wallet + const payer = await generatePayer(connection, authority.payer); + + // Check wrapped tBTC mint. + const wrappedTbtcMint = tokenBridge.deriveWrappedMintKey(SOLANA_TOKEN_BRIDGE_ADDRESS, 2, ETHEREUM_TBTC_ADDRESS); + const mintData = await spl.getMint(connection, wrappedTbtcMint); + expect(mintData.decimals).to.equal(8); + expect(mintData.supply).to.equal(BigInt(90)); + + const wrappedTbtcToken = await getOrCreateTokenAccount(connection, payer, wrappedTbtcMint, payer.publicKey); + + // Bridge tbtc to token account. + const published = ethereumTokenBridge.publishTransferTokens( + tryNativeToHexString(ETHEREUM_TBTC_ADDRESS, "ethereum"), + 2, + BigInt("100000000000"), + 1, + wrappedTbtcToken.address.toBuffer().toString("hex"), + BigInt(0), + 0, + 0 + ); + + const signedVaa = await mockSignAndPostVaa(connection, payer, published); + + const tx = await redeemOnSolana( + connection, + SOLANA_CORE_BRIDGE_ADDRESS, + SOLANA_TOKEN_BRIDGE_ADDRESS, + payer.publicKey, + signedVaa, + ); + await web3.sendAndConfirmTransaction(connection, tx, [payer]); + }); + + it('setup', async () => { + // await setup(program, authority); + // await checkState(program, authority, 0, 0, 0); + }); +}); + +async function mockSignAndPostVaa(connection: web3.Connection, payer: web3.Keypair, published: Buffer) { + const guardians = new mock.MockGuardians( + GUARDIAN_SET_INDEX, + ["cfb12303a19cde580bb4dd771639b0d26bc68353645571a8cff516ab2ee113a0"] + ); + + // Add guardian signature. + const signedVaa = guardians.addSignatures(published, [0]); + + // Verify and post VAA. + await postVaaSolana(connection, + new NodeWallet(payer).signTransaction, + SOLANA_CORE_BRIDGE_ADDRESS, + payer.publicKey, + signedVaa + ); + + return signedVaa; +} diff --git a/cross-chain/solana/tests/accounts/core_bridge.json b/cross-chain/solana/tests/accounts/core_bridge.json new file mode 100644 index 000000000..5c14d521c --- /dev/null +++ b/cross-chain/solana/tests/accounts/core_bridge.json @@ -0,0 +1,13 @@ +{ + "pubkey": "2yVjuQwpsvdsrywzsJJVs9Ueh4zayyo5DYJbBNc3DDpn", + "account": { + "lamports": 1057920, + "data": [ + "AwAAAPhmKAUAAAAAgFEBAGQAAAAAAAAA", + "base64" + ], + "owner": "worm2ZoG2kUd4vFXhvjh93UUH596ayRfgQ2MgjNMTth", + "executable": false, + "rentEpoch": 361 + } +} \ No newline at end of file diff --git a/cross-chain/solana/tests/accounts/core_emitter_sequence.json b/cross-chain/solana/tests/accounts/core_emitter_sequence.json new file mode 100644 index 000000000..966d215e5 --- /dev/null +++ b/cross-chain/solana/tests/accounts/core_emitter_sequence.json @@ -0,0 +1,13 @@ +{ + "pubkey": "GF2ghkjwsR9CHkGk1RvuZrApPZGBZynxMm817VNi51Nf", + "account": { + "lamports": 946560, + "data": [ + "4KMEAAAAAAA=", + "base64" + ], + "owner": "worm2ZoG2kUd4vFXhvjh93UUH596ayRfgQ2MgjNMTth", + "executable": false, + "rentEpoch": 361 + } +} \ No newline at end of file diff --git a/cross-chain/solana/tests/accounts/core_fee_collector.json b/cross-chain/solana/tests/accounts/core_fee_collector.json new file mode 100644 index 000000000..6f355d442 --- /dev/null +++ b/cross-chain/solana/tests/accounts/core_fee_collector.json @@ -0,0 +1,13 @@ +{ + "pubkey": "9bFNrXNb2WTx8fMHXCheaZqkLZ3YCCaiqTftHxeintHy", + "account": { + "lamports": 86533780, + "data": [ + "", + "base64" + ], + "owner": "11111111111111111111111111111111", + "executable": false, + "rentEpoch": 361 + } +} \ No newline at end of file diff --git a/cross-chain/solana/tests/accounts/core_guardian_set.json b/cross-chain/solana/tests/accounts/core_guardian_set.json new file mode 100644 index 000000000..d503f9049 --- /dev/null +++ b/cross-chain/solana/tests/accounts/core_guardian_set.json @@ -0,0 +1,13 @@ +{ + "pubkey": "6d3w8mGjJauf6gCAg7WfLezbaPmUHYGuoNutnfYF1RYM", + "account": { + "lamports": 3647040, + "data": [ + "AwAAAAEAAAC++kKdV80Yt/ik2RotqatK8F0PvgAAAAAAAAAA", + "base64" + ], + "owner": "worm2ZoG2kUd4vFXhvjh93UUH596ayRfgQ2MgjNMTth", + "executable": false, + "rentEpoch": 0 + } +} \ No newline at end of file diff --git a/cross-chain/solana/tests/accounts/ethereum_token_bridge.json b/cross-chain/solana/tests/accounts/ethereum_token_bridge.json new file mode 100644 index 000000000..e5c5ef3ad --- /dev/null +++ b/cross-chain/solana/tests/accounts/ethereum_token_bridge.json @@ -0,0 +1,13 @@ +{ + "pubkey": "DujfLgMKW71CT2W8pxknf42FT86VbcK5PjQ6LsutjWKC", + "account": { + "lamports": 1127520, + "data": [ + "AgAAAAAAAAAAAAAAAAA+4YsiFK/5cADZdM9kfnw0fo+lhQ==", + "base64" + ], + "owner": "wormDTUJ6AWPNvk59vGQbDvGJmqbDTdgWgAqcLBCgUb", + "executable": false, + "rentEpoch": 361 + } +} \ No newline at end of file diff --git a/cross-chain/solana/tests/accounts/token_bridge_config.json b/cross-chain/solana/tests/accounts/token_bridge_config.json new file mode 100644 index 000000000..c4f8fb6c3 --- /dev/null +++ b/cross-chain/solana/tests/accounts/token_bridge_config.json @@ -0,0 +1,13 @@ +{ + "pubkey": "DapiQYH3BGonhN8cngWcXQ6SrqSm3cwysoznoHr6Sbsx", + "account": { + "lamports": 1113600, + "data": [ + "DgpYmkGlX71mxSpHXy2SptPcm0dHEUy5r4JamLVF084=", + "base64" + ], + "owner": "wormDTUJ6AWPNvk59vGQbDvGJmqbDTdgWgAqcLBCgUb", + "executable": false, + "rentEpoch": 361 + } +} \ No newline at end of file diff --git a/cross-chain/solana/tests/accounts/wrapped_tbtc_asset.json b/cross-chain/solana/tests/accounts/wrapped_tbtc_asset.json new file mode 100644 index 000000000..423cf3610 --- /dev/null +++ b/cross-chain/solana/tests/accounts/wrapped_tbtc_asset.json @@ -0,0 +1,13 @@ +{ + "pubkey": "5LEUZpBxUQmoxoNGqmYmFEGAPDuhWbAY5CGt519UixLo", + "account": { + "lamports": 1134480, + "data": [ + "AgAAAAAAAAAAAAAAAAAYCE+6Zmoz03WS+iYz/UmnTdk6iBI=", + "base64" + ], + "owner": "wormDTUJ6AWPNvk59vGQbDvGJmqbDTdgWgAqcLBCgUb", + "executable": false, + "rentEpoch": 0 + } +} \ No newline at end of file diff --git a/cross-chain/solana/tests/accounts/wrapped_tbtc_mint.json b/cross-chain/solana/tests/accounts/wrapped_tbtc_mint.json new file mode 100644 index 000000000..0dd211691 --- /dev/null +++ b/cross-chain/solana/tests/accounts/wrapped_tbtc_mint.json @@ -0,0 +1,13 @@ +{ + "pubkey": "25rXTx9zDZcHyTav5sRqM6YBvTGu9pPH9yv83uAEqbgG", + "account": { + "lamports": 1461600, + "data": [ + "AQAAAJdz8e+O65iVdMpxBFsTrA0MEUaiThB5GX5TF1UZTdCWWgAAAAAAAAAIAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==", + "base64" + ], + "owner": "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA", + "executable": false, + "rentEpoch": 0 + } +} \ No newline at end of file diff --git a/cross-chain/solana/tests/helpers/utils.ts b/cross-chain/solana/tests/helpers/utils.ts new file mode 100644 index 000000000..b87a0a948 --- /dev/null +++ b/cross-chain/solana/tests/helpers/utils.ts @@ -0,0 +1,53 @@ +import { web3 } from "@coral-xyz/anchor"; +import { Account, TokenAccountNotFoundError, createAssociatedTokenAccountIdempotentInstruction, getAccount, getAssociatedTokenAddressSync } from "@solana/spl-token"; +import { Connection, Keypair, PublicKey, SystemProgram, Transaction, sendAndConfirmTransaction } from "@solana/web3.js"; + +export async function transferLamports(connection: web3.Connection, fromSigner: web3.Keypair, toPubkey: web3.PublicKey, lamports: number) { + return sendAndConfirmTransaction( + connection, + new Transaction().add( + SystemProgram.transfer({ + fromPubkey: fromSigner.publicKey, + toPubkey, + lamports, + }) + ), + [fromSigner] + ); +} + +export async function generatePayer(connection: web3.Connection, payer: Keypair, lamports?: number) { + const newPayer = Keypair.generate(); + await transferLamports(connection, payer, newPayer.publicKey, lamports === undefined ? 1000000000 : lamports); + return newPayer; +} + +export async function getOrCreateTokenAccount(connection: Connection, payer: Keypair, mint: PublicKey, owner: PublicKey) { + const token = getAssociatedTokenAddressSync(mint, owner); + const tokenData: Account = await getAccount(connection, token).catch((err) => { + if (err instanceof TokenAccountNotFoundError) { + return null; + } else { + throw err; + }; + }); + + if (tokenData === null) { + await web3.sendAndConfirmTransaction( + connection, + new web3.Transaction().add( + createAssociatedTokenAccountIdempotentInstruction( + payer.publicKey, + token, + owner, + mint, + ) + ), + [payer] + ); + + return getAccount(connection, token); + } else { + return tokenData; + } +} \ No newline at end of file diff --git a/cross-chain/solana/tsconfig.json b/cross-chain/solana/tsconfig.json new file mode 100644 index 000000000..558b83e5e --- /dev/null +++ b/cross-chain/solana/tsconfig.json @@ -0,0 +1,11 @@ +{ + "compilerOptions": { + "types": ["mocha", "chai"], + "typeRoots": ["./node_modules/@types"], + "lib": ["es2015"], + "module": "commonjs", + "target": "es6", + "esModuleInterop": true + } + } + \ No newline at end of file