diff --git a/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/CoinAddressDerivationTests.kt b/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/CoinAddressDerivationTests.kt
index 05d20a89744..0d0e8f18103 100644
--- a/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/CoinAddressDerivationTests.kt
+++ b/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/CoinAddressDerivationTests.kt
@@ -153,5 +153,6 @@ class CoinAddressDerivationTests {
INTERNETCOMPUTER -> assertEquals("b9a13d974ee9db036d5abc5b66ace23e513cb5676f3996626c7717c339a3ee87", address)
TIA -> assertEquals("celestia142j9u5eaduzd7faumygud6ruhdwme98qpwmfv7", address)
NATIVEZETACHAIN -> assertEquals("zeta13u6g7vqgw074mgmf2ze2cadzvkz9snlwywj304", address)
+ DYDX -> assertEquals("dydx142j9u5eaduzd7faumygud6ruhdwme98qeayaky", address)
}
}
diff --git a/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/dydx/TestDydxAddress.kt b/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/dydx/TestDydxAddress.kt
new file mode 100644
index 00000000000..408f8fb4ae3
--- /dev/null
+++ b/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/dydx/TestDydxAddress.kt
@@ -0,0 +1,27 @@
+// SPDX-License-Identifier: Apache-2.0
+//
+// Copyright © 2017 Trust Wallet.
+
+package com.trustwallet.core.app.blockchains.dydx
+
+import com.trustwallet.core.app.utils.toHexByteArray
+import org.junit.Assert.assertEquals
+import org.junit.Test
+import wallet.core.jni.*
+
+class TestDydxAddress {
+
+ init {
+ System.loadLibrary("TrustWalletCore")
+ }
+
+ @Test
+ fun testAddress() {
+ val key = PrivateKey("a498a9ee41af9bab5ef2a8be63d5c970135c3c109e70efc8c56c534e6636b433".toHexByteArray())
+ val pubKey = key.getPublicKeySecp256k1(true)
+ val address = AnyAddress(pubKey, CoinType.DYDX)
+ val expected = AnyAddress("dydx1mry47pkga5tdswtluy0m8teslpalkdq0hc72uz", CoinType.DYDX)
+
+ assertEquals(address.description(), expected.description())
+ }
+}
diff --git a/docs/registry.md b/docs/registry.md
index 4fd54a26c0c..a2023da41f1 100644
--- a/docs/registry.md
+++ b/docs/registry.md
@@ -144,6 +144,7 @@ This list is generated from [./registry.json](../registry.json)
| 20007000 | Zeta EVM | ZETA | | |
| 20009001 | Native Evmos | EVMOS | | |
| 21000118 | Celestia | TIA | | |
+| 22000118 | dYdX | DYDX | | |
| 30000118 | Juno | JUNO | | |
| 30000714 | TBNB | BNB | | |
| 40000118 | Stride | STRD | | |
diff --git a/include/TrustWalletCore/TWCoinType.h b/include/TrustWalletCore/TWCoinType.h
index 289ff480a82..e65dc4878e7 100644
--- a/include/TrustWalletCore/TWCoinType.h
+++ b/include/TrustWalletCore/TWCoinType.h
@@ -180,6 +180,7 @@ enum TWCoinType {
TWCoinTypeMantaPacific = 169,
TWCoinTypeNativeZetaChain = 10007000,
TWCoinTypeZetaEVM = 20007000,
+ TWCoinTypeDydx = 22000118,
// end_of_tw_coin_type_marker_do_not_modify
};
diff --git a/kotlin/wallet-core-kotlin/src/commonTest/kotlin/com/trustwallet/core/test/CoinAddressDerivationTests.kt b/kotlin/wallet-core-kotlin/src/commonTest/kotlin/com/trustwallet/core/test/CoinAddressDerivationTests.kt
index 444e9ea9767..a586146c54d 100644
--- a/kotlin/wallet-core-kotlin/src/commonTest/kotlin/com/trustwallet/core/test/CoinAddressDerivationTests.kt
+++ b/kotlin/wallet-core-kotlin/src/commonTest/kotlin/com/trustwallet/core/test/CoinAddressDerivationTests.kt
@@ -146,5 +146,6 @@ class CoinAddressDerivationTests {
InternetComputer -> "b9a13d974ee9db036d5abc5b66ace23e513cb5676f3996626c7717c339a3ee87"
Tia -> "celestia142j9u5eaduzd7faumygud6ruhdwme98qpwmfv7"
NativeZetaChain -> "zeta13u6g7vqgw074mgmf2ze2cadzvkz9snlwywj304"
+ Dydx -> "dydx142j9u5eaduzd7faumygud6ruhdwme98qeayaky"
}
}
diff --git a/registry.json b/registry.json
index e034c34bede..ca3f9cf2660 100644
--- a/registry.json
+++ b/registry.json
@@ -4361,6 +4361,38 @@
"documentation": "https://docs.agoric.com"
}
},
+ {
+ "id": "dydx",
+ "name": "Dydx",
+ "displayName": "dYdX",
+ "coinId": 22000118,
+ "symbol": "DYDX",
+ "decimals": 18,
+ "blockchain": "Cosmos",
+ "derivation": [
+ {
+ "path": "m/44'/118'/0'/0/0"
+ }
+ ],
+ "curve": "secp256k1",
+ "publicKeyType": "secp256k1",
+ "hrp": "dydx",
+ "chainId": "dydx-mainnet-1",
+ "addressHasher": "sha256ripemd",
+ "explorer": {
+ "url": "https://www.mintscan.io/dydx",
+ "txPath": "/tx/",
+ "accountPath": "/address/",
+ "sampleTx": "F236222E4F7C92FA84711FD6451ED22DD56CBDFA319BFDAFB99A21E4E9B9EC2F",
+ "sampleAccount": "dydx1adl7usw7z2dnysyn7wvrghu0u0q6gr7jqs4gtt"
+ },
+ "info": {
+ "url": "https://dydx.exchange",
+ "source": "https://github.com/dydxprotocol",
+ "rpc": "https://dydx-dao-api.polkachu.com",
+ "documentation": "https://docs.dydx.exchange"
+ }
+ },
{
"id": "nativeinjective",
"name": "NativeInjective",
diff --git a/rust/tw_any_coin/tests/chains/cosmos/cosmos_address.rs b/rust/tw_any_coin/tests/chains/cosmos/cosmos_address.rs
index 51bf414bec3..a9acab72f63 100644
--- a/rust/tw_any_coin/tests/chains/cosmos/cosmos_address.rs
+++ b/rust/tw_any_coin/tests/chains/cosmos/cosmos_address.rs
@@ -73,9 +73,9 @@ fn test_any_address_is_valid_bech32() {
fn test_any_address_create_bech32_with_public_key() {
test_address_create_bech32_with_public_key(AddressCreateBech32WithPublicKey {
coin: CoinType::Cosmos,
- private_key: "afeefca74d9a325cf1d6b6911d61a65c32afa8e02bd5e78e2e4ac2910bab45f5",
+ private_key: "a498a9ee41af9bab5ef2a8be63d5c970135c3c109e70efc8c56c534e6636b433",
public_key_type: PublicKeyType::Secp256k1,
- hrp: "juno",
- expected: "juno1ten42eesehw0ktddcp0fws7d3ycsqez3fksy86",
+ hrp: "dydx",
+ expected: "dydx1mry47pkga5tdswtluy0m8teslpalkdq0hc72uz",
});
}
diff --git a/rust/tw_any_coin/tests/chains/dydx/dydx_address.rs b/rust/tw_any_coin/tests/chains/dydx/dydx_address.rs
new file mode 100644
index 00000000000..8ba214f3e41
--- /dev/null
+++ b/rust/tw_any_coin/tests/chains/dydx/dydx_address.rs
@@ -0,0 +1,83 @@
+// SPDX-License-Identifier: Apache-2.0
+//
+// Copyright © 2017 Trust Wallet.
+
+use tw_any_coin::test_utils::address_utils::{
+ test_address_bech32_is_valid, test_address_create_bech32_with_public_key,
+ test_address_get_data, test_address_invalid, test_address_normalization, test_address_valid,
+ AddressBech32IsValid, AddressCreateBech32WithPublicKey,
+};
+use tw_coin_registry::coin_type::CoinType;
+use tw_keypair::tw::PublicKeyType;
+
+#[test]
+fn test_dydx_address_normalization() {
+ test_address_normalization(
+ CoinType::Dydx,
+ "dydx1adl7usw7z2dnysyn7wvrghu0u0q6gr7jqs4gtt",
+ "dydx1adl7usw7z2dnysyn7wvrghu0u0q6gr7jqs4gtt",
+ );
+}
+
+#[test]
+fn test_dydx_address_is_valid() {
+ test_address_valid(
+ CoinType::Dydx,
+ "dydxvaloper1gf9yvztyvnc3aqrkjd8hfnaf8pk56sl7mzfage",
+ );
+}
+
+#[test]
+fn test_dydx_address_invalid() {
+ test_address_invalid(
+ CoinType::Dydx,
+ "dydxvaloper1gf9yvztyvnc3aqrkjd8hfnaf8pk56sl7mz",
+ );
+ // Cosmos has a different `hrp`.
+ test_address_invalid(
+ CoinType::Cosmos,
+ "dydx1adl7usw7z2dnysyn7wvrghu0u0q6gr7jqs4gtt",
+ );
+}
+
+#[test]
+fn test_dydx_address_get_data() {
+ test_address_get_data(
+ CoinType::Dydx,
+ "dydxvaloper1gf9yvztyvnc3aqrkjd8hfnaf8pk56sl7mzfage",
+ "424a46096464f11e8076934f74cfa9386d4d43fe",
+ );
+}
+
+#[test]
+fn test_dydx_is_valid_bech32() {
+ // Dydx address must be valid if its Base32 prefix passed.
+ test_address_bech32_is_valid(AddressBech32IsValid {
+ coin: CoinType::Dydx,
+ address: "dydx1adl7usw7z2dnysyn7wvrghu0u0q6gr7jqs4gtt",
+ hrp: "dydx",
+ });
+ // Dydx address must be valid for the standard Cosmos hub if its Base32 prefix passed.
+ test_address_bech32_is_valid(AddressBech32IsValid {
+ coin: CoinType::Cosmos,
+ address: "dydx1adl7usw7z2dnysyn7wvrghu0u0q6gr7jqs4gtt",
+ hrp: "dydx",
+ });
+ // Cosmos address must be valid with "cosmos" hrp.
+ test_address_bech32_is_valid(AddressBech32IsValid {
+ coin: CoinType::Dydx,
+ address: "cosmos1hsk6jryyqjfhp5dhc55tc9jtckygx0eph6dd02",
+ hrp: "cosmos",
+ });
+}
+
+#[test]
+fn test_any_address_create_bech32_with_public_key() {
+ test_address_create_bech32_with_public_key(AddressCreateBech32WithPublicKey {
+ coin: CoinType::Cosmos,
+ private_key: "a498a9ee41af9bab5ef2a8be63d5c970135c3c109e70efc8c56c534e6636b433",
+ public_key_type: PublicKeyType::Secp256k1,
+ hrp: "dydx",
+ expected: "dydx1mry47pkga5tdswtluy0m8teslpalkdq0hc72uz",
+ });
+}
diff --git a/rust/tw_any_coin/tests/chains/dydx/mod.rs b/rust/tw_any_coin/tests/chains/dydx/mod.rs
new file mode 100644
index 00000000000..d559c269a8b
--- /dev/null
+++ b/rust/tw_any_coin/tests/chains/dydx/mod.rs
@@ -0,0 +1,5 @@
+// SPDX-License-Identifier: Apache-2.0
+//
+// Copyright © 2017 Trust Wallet.
+
+mod dydx_address;
diff --git a/rust/tw_any_coin/tests/chains/mod.rs b/rust/tw_any_coin/tests/chains/mod.rs
index 7a9f7285560..cefb0e37ae4 100644
--- a/rust/tw_any_coin/tests/chains/mod.rs
+++ b/rust/tw_any_coin/tests/chains/mod.rs
@@ -6,6 +6,7 @@ mod aptos;
mod binance;
mod bitcoin;
mod cosmos;
+mod dydx;
mod ethereum;
mod greenfield;
mod internet_computer;
diff --git a/rust/tw_any_coin/tests/coin_address_derivation_test.rs b/rust/tw_any_coin/tests/coin_address_derivation_test.rs
index 12ce7f772fc..9cf10ad244a 100644
--- a/rust/tw_any_coin/tests/coin_address_derivation_test.rs
+++ b/rust/tw_any_coin/tests/coin_address_derivation_test.rs
@@ -147,6 +147,7 @@ fn test_coin_address_derivation() {
CoinType::Binance => "bnb1ten42eesehw0ktddcp0fws7d3ycsqez3aqvnpg",
CoinType::TBinance => "tbnb1ten42eesehw0ktddcp0fws7d3ycsqez3n49hpe",
CoinType::NativeZetaChain => "zeta14s0vgnj0pjnazu4hsqlksdk7slah9vcfcwctsr",
+ CoinType::Dydx => "dydx1ten42eesehw0ktddcp0fws7d3ycsqez3kaamq3",
// end_of_coin_address_derivation_tests_marker_do_not_modify
_ => panic!("{:?} must be covered", coin),
};
diff --git a/swift/Tests/Blockchains/DydxTests.swift b/swift/Tests/Blockchains/DydxTests.swift
new file mode 100644
index 00000000000..a464c834c8a
--- /dev/null
+++ b/swift/Tests/Blockchains/DydxTests.swift
@@ -0,0 +1,17 @@
+// SPDX-License-Identifier: Apache-2.0
+//
+// Copyright © 2017 Trust Wallet.
+
+import WalletCore
+import XCTest
+
+class DydxTests: XCTestCase {
+ func testAddress() {
+ let key = PrivateKey(data: Data(hexString: "a498a9ee41af9bab5ef2a8be63d5c970135c3c109e70efc8c56c534e6636b433")!)!
+ let pubkey = key.getPublicKeySecp256k1(compressed: true)
+ let address = AnyAddress(publicKey: pubkey, coin: .dydx)
+ let addressFromString = AnyAddress(string: "dydx1mry47pkga5tdswtluy0m8teslpalkdq0hc72uz", coin: .dydx)!
+
+ XCTAssertEqual(address.description, addressFromString.description)
+ }
+}
diff --git a/swift/Tests/CoinAddressDerivationTests.swift b/swift/Tests/CoinAddressDerivationTests.swift
index 4d18de7ae96..339b2ccde19 100644
--- a/swift/Tests/CoinAddressDerivationTests.swift
+++ b/swift/Tests/CoinAddressDerivationTests.swift
@@ -392,6 +392,9 @@ class CoinAddressDerivationTests: XCTestCase {
case .nativeZetaChain:
let expectedResult = "zeta13u6g7vqgw074mgmf2ze2cadzvkz9snlwywj304"
assertCoinDerivation(coin, expectedResult, derivedAddress, address)
+ case .dydx:
+ let expectedResult = "dydx142j9u5eaduzd7faumygud6ruhdwme98qeayaky"
+ assertCoinDerivation(coin, expectedResult, derivedAddress, address)
@unknown default:
fatalError()
}
diff --git a/tests/chains/Dydx/TWCoinTypeTests.cpp b/tests/chains/Dydx/TWCoinTypeTests.cpp
new file mode 100644
index 00000000000..1dd49ee8eb4
--- /dev/null
+++ b/tests/chains/Dydx/TWCoinTypeTests.cpp
@@ -0,0 +1,29 @@
+// SPDX-License-Identifier: Apache-2.0
+//
+// Copyright © 2017 Trust Wallet.
+
+#include "TestUtilities.h"
+#include
+#include
+
+TEST(TWDydxCoinType, TWCoinType) {
+ const auto coin = TWCoinTypeDydx;
+ const auto symbol = WRAPS(TWCoinTypeConfigurationGetSymbol(coin));
+ const auto id = WRAPS(TWCoinTypeConfigurationGetID(coin));
+ const auto name = WRAPS(TWCoinTypeConfigurationGetName(coin));
+ const auto txId = WRAPS(TWStringCreateWithUTF8Bytes("F236222E4F7C92FA84711FD6451ED22DD56CBDFA319BFDAFB99A21E4E9B9EC2F"));
+ const auto txUrl = WRAPS(TWCoinTypeConfigurationGetTransactionURL(coin, txId.get()));
+ const auto accId = WRAPS(TWStringCreateWithUTF8Bytes("dydx1adl7usw7z2dnysyn7wvrghu0u0q6gr7jqs4gtt"));
+ const auto accUrl = WRAPS(TWCoinTypeConfigurationGetAccountURL(coin, accId.get()));
+
+ assertStringsEqual(id, "dydx");
+ assertStringsEqual(name, "dYdX");
+ assertStringsEqual(symbol, "DYDX");
+ ASSERT_EQ(TWCoinTypeConfigurationGetDecimals(coin), 18);
+ ASSERT_EQ(TWCoinTypeBlockchain(coin), TWBlockchainCosmos);
+ ASSERT_EQ(TWCoinTypeP2pkhPrefix(coin), 0);
+ ASSERT_EQ(TWCoinTypeP2shPrefix(coin), 0);
+ ASSERT_EQ(TWCoinTypeStaticPrefix(coin), 0);
+ assertStringsEqual(txUrl, "https://www.mintscan.io/dydx/tx/F236222E4F7C92FA84711FD6451ED22DD56CBDFA319BFDAFB99A21E4E9B9EC2F");
+ assertStringsEqual(accUrl, "https://www.mintscan.io/dydx/address/dydx1adl7usw7z2dnysyn7wvrghu0u0q6gr7jqs4gtt");
+}
diff --git a/tests/common/CoinAddressDerivationTests.cpp b/tests/common/CoinAddressDerivationTests.cpp
index f052b41322b..93411f2e8cf 100644
--- a/tests/common/CoinAddressDerivationTests.cpp
+++ b/tests/common/CoinAddressDerivationTests.cpp
@@ -388,6 +388,9 @@ TEST(Coin, DeriveAddress) {
case TWCoinTypeNativeZetaChain:
EXPECT_EQ(address, "zeta1nk9x9ajk4rgkzhqjjn7hr6w0k0jg2kj027x9uy");
break;
+ case TWCoinTypeDydx:
+ EXPECT_EQ(address, "dydx1hkfq3zahaqkkzx5mjnamwjsfpq2jk7z0sz38vk");
+ break;
// end_of_coin_address_derivation_tests_marker_do_not_modify
// no default branch here, intentionally, to better notice any missing coins
}