Skip to content

Commit

Permalink
feat(dYdX): Add support for dYdX Cosmos chain (#3671)
Browse files Browse the repository at this point in the history
* feat(dYdX): Add support for dYdX Cosmos chain

* feat(dYdX): Fix Kotlin tests
  • Loading branch information
satoshiotomakan authored Jan 25, 2024
1 parent 24f24c1 commit d42429b
Show file tree
Hide file tree
Showing 15 changed files with 208 additions and 3 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -153,5 +153,6 @@ class CoinAddressDerivationTests {
INTERNETCOMPUTER -> assertEquals("b9a13d974ee9db036d5abc5b66ace23e513cb5676f3996626c7717c339a3ee87", address)
TIA -> assertEquals("celestia142j9u5eaduzd7faumygud6ruhdwme98qpwmfv7", address)
NATIVEZETACHAIN -> assertEquals("zeta13u6g7vqgw074mgmf2ze2cadzvkz9snlwywj304", address)
DYDX -> assertEquals("dydx142j9u5eaduzd7faumygud6ruhdwme98qeayaky", address)
}
}
Original file line number Diff line number Diff line change
@@ -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())
}
}
1 change: 1 addition & 0 deletions docs/registry.md
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,7 @@ This list is generated from [./registry.json](../registry.json)
| 20007000 | Zeta EVM | ZETA | <img src="https://raw.githubusercontent.com/trustwallet/assets/master/blockchains/zetaevm/info/logo.png" width="32" /> | <https://www.zetachain.com/> |
| 20009001 | Native Evmos | EVMOS | <img src="https://raw.githubusercontent.com/trustwallet/assets/master/blockchains/nativeevmos/info/logo.png" width="32" /> | <https://evmos.org/> |
| 21000118 | Celestia | TIA | <img src="https://raw.githubusercontent.com/trustwallet/assets/master/blockchains/tia/info/logo.png" width="32" /> | <https://celestia.org/> |
| 22000118 | dYdX | DYDX | <img src="https://raw.githubusercontent.com/trustwallet/assets/master/blockchains/dydx/info/logo.png" width="32" /> | <https://dydx.exchange> |
| 30000118 | Juno | JUNO | <img src="https://raw.githubusercontent.com/trustwallet/assets/master/blockchains/juno/info/logo.png" width="32" /> | <https://www.junonetwork.io/> |
| 30000714 | TBNB | BNB | <img src="https://raw.githubusercontent.com/trustwallet/assets/master/blockchains/tbinance/info/logo.png" width="32" /> | <https://www.bnbchain.org> |
| 40000118 | Stride | STRD | <img src="https://raw.githubusercontent.com/trustwallet/assets/master/blockchains/stride/info/logo.png" width="32" /> | <https://stride.zone/> |
Expand Down
1 change: 1 addition & 0 deletions include/TrustWalletCore/TWCoinType.h
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,7 @@ enum TWCoinType {
TWCoinTypeMantaPacific = 169,
TWCoinTypeNativeZetaChain = 10007000,
TWCoinTypeZetaEVM = 20007000,
TWCoinTypeDydx = 22000118,
// end_of_tw_coin_type_marker_do_not_modify
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -146,5 +146,6 @@ class CoinAddressDerivationTests {
InternetComputer -> "b9a13d974ee9db036d5abc5b66ace23e513cb5676f3996626c7717c339a3ee87"
Tia -> "celestia142j9u5eaduzd7faumygud6ruhdwme98qpwmfv7"
NativeZetaChain -> "zeta13u6g7vqgw074mgmf2ze2cadzvkz9snlwywj304"
Dydx -> "dydx142j9u5eaduzd7faumygud6ruhdwme98qeayaky"
}
}
32 changes: 32 additions & 0 deletions registry.json
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
6 changes: 3 additions & 3 deletions rust/tw_any_coin/tests/chains/cosmos/cosmos_address.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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",
});
}
83 changes: 83 additions & 0 deletions rust/tw_any_coin/tests/chains/dydx/dydx_address.rs
Original file line number Diff line number Diff line change
@@ -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",
});
}
5 changes: 5 additions & 0 deletions rust/tw_any_coin/tests/chains/dydx/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
// SPDX-License-Identifier: Apache-2.0
//
// Copyright © 2017 Trust Wallet.

mod dydx_address;
1 change: 1 addition & 0 deletions rust/tw_any_coin/tests/chains/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ mod aptos;
mod binance;
mod bitcoin;
mod cosmos;
mod dydx;
mod ethereum;
mod greenfield;
mod internet_computer;
Expand Down
1 change: 1 addition & 0 deletions rust/tw_any_coin/tests/coin_address_derivation_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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),
};
Expand Down
17 changes: 17 additions & 0 deletions swift/Tests/Blockchains/DydxTests.swift
Original file line number Diff line number Diff line change
@@ -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)
}
}
3 changes: 3 additions & 0 deletions swift/Tests/CoinAddressDerivationTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -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()
}
Expand Down
29 changes: 29 additions & 0 deletions tests/chains/Dydx/TWCoinTypeTests.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
// SPDX-License-Identifier: Apache-2.0
//
// Copyright © 2017 Trust Wallet.

#include "TestUtilities.h"
#include <TrustWalletCore/TWCoinTypeConfiguration.h>
#include <gtest/gtest.h>

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");
}
3 changes: 3 additions & 0 deletions tests/common/CoinAddressDerivationTests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
Expand Down

0 comments on commit d42429b

Please sign in to comment.