Skip to content

Commit

Permalink
Split Polymesh chain from Polkadot impl. (trustwallet#4229)
Browse files Browse the repository at this point in the history
* Add SCALE support for String

* Add SCALE support for BTreeSet/Map.

* Split Polymesh chain from Polkadot impl.

* Some cleanup of the Polymesh call encoder.

* Use Polymesh protobuf instead of Polkadot.

* Add permissions support.

* Refactor.  Move types into different module.

* Add support for leave identity as key.

* Fix custom call indices for staking batch calls.

* Refactor batched call support.

* Remove dead code.

* Allow enum variants to re-use the same index for backwards compatibility.

* Remove `multi_address` flag.  Only support MultiAddress.

* Fix batch call index.

* Add some batch tests.

* Code cleanup.

* Add mobile tests.

* Cleanup error conversion code.

* Fix RewardDestination.

* Add missing check_metadata field.

* Move Polymesh signing tests over from Polkadot tests.

* cargo clippy.

* Fix Kotlin test.

* Try fixing iOS test.

* Fix test_address_derive call.

* Fix Clang-tidy error.

* Fix swift tests.

* Fix json format.

* Remove extra to_string calls.

* Use common types from Polkadot.proto.

* Add test for Staking.rebond

* Update Android and swift tests to use Era from Polkadot.

* Improve code coverage and remove dead code.

* Some more code coverage.

* Removed more dead code and improved code coverage.
  • Loading branch information
Neopallium authored Mar 4, 2025
1 parent 33b5548 commit 9ede115
Show file tree
Hide file tree
Showing 44 changed files with 3,378 additions and 595 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,7 @@ class CoinAddressDerivationTests {
ACALA -> assertEquals("25GGezx3LWFQj6HZpYzoWoVzLsHojGtybef3vthC9nd19ms3", address)
KUSAMA -> assertEquals("G9xV2EatmrjRC1FLPexc3ddqNRRzCsAdURU8RFiAAJX6ppY", address)
POLKADOT -> assertEquals("13nN6BGAoJwd7Nw1XxeBCx5YcBXuYnL94Mh7i3xBprqVSsFk", address)
POLYMESH -> assertEquals("2DHK8VhBpacs9quk78AVP9TmmcG5iXi2oKtZqneSNsVXxCKw", address)
PIVX -> assertEquals("D81AqC8zKma3Cht4TbVuh4jyVVyLkZULCm", address)
KAVA -> assertEquals("kava1drpa0x9ptz0fql3frv562rcrhj2nstuz3pas87", address)
CARDANO -> assertEquals("addr1qyr8jjfnypp95eq74aqzn7ss687ehxclgj7mu6gratmg3mul2040vt35dypp042awzsjk5xm3zr3zm5qh7454uwdv08s84ray2", address)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
// SPDX-License-Identifier: Apache-2.0
//
// Copyright © 2017 Trust Wallet.

package com.trustwallet.core.app.blockchains.polymesh

import com.trustwallet.core.app.utils.toHex
import com.trustwallet.core.app.utils.toHexByteArray
import org.junit.Assert.assertEquals
import org.junit.Test
import wallet.core.jni.*

class TestPolymeshAddress {

init {
System.loadLibrary("TrustWalletCore")
}

@Test
fun testAddress() {

val key = PrivateKey("0x790a0a01ec2e7c7db4abcaffc92ce70a960ef9ad3021dbe3bf327c1c6343aee4".toHexByteArray())
val pubkey = key.publicKeyEd25519
val address = AnyAddress(pubkey, CoinType.POLYMESH)
val expected = AnyAddress("2EANwBfNsFu9KV8JsW5sbhF6ft8bzvw5EW1LCrgHhrqtK6Ys", CoinType.POLYMESH)

assertEquals(pubkey.data().toHex(), "0x4bdb9ef424035e1621e228bd11c5917d7d1dac5965d244c4c72fc91170244f0c")
assertEquals(address.description(), expected.description())
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
// SPDX-License-Identifier: Apache-2.0
//
// Copyright © 2017 Trust Wallet.

package com.trustwallet.core.app.blockchains.polymesh

import com.trustwallet.core.app.utils.Numeric
import com.trustwallet.core.app.utils.toHexBytesInByteString
import org.junit.Assert.assertEquals
import org.junit.Test
import wallet.core.java.AnySigner
import wallet.core.jni.CoinType.POLYMESH
import wallet.core.jni.proto.Polkadot
import wallet.core.jni.proto.Polymesh
import wallet.core.jni.proto.Polymesh.SigningOutput

class TestPolymeshSigner {

init {
System.loadLibrary("TrustWalletCore")
}

val genesisHashStr = "0x6fbd74e5e1d0a61d52ccfe9d4adaed16dd3a7caa37c6bc4d0c2fa12e8b2f4063".toHexBytesInByteString()
// Private key for testing. DO NOT USE, since this is public.
val TestKey1 = "0x790a0a01ec2e7c7db4abcaffc92ce70a960ef9ad3021dbe3bf327c1c6343aee4".toHexBytesInByteString()

@Test
fun PolymeshTransactionSigning() {
// https://polymesh.subscan.io/extrinsic/0x98cb5e33d8ff3dd5838c384e2ef9e291314ed8db13f5d4f42cdd70bad54a5e04

// Step 1: Prepare input.
val blockHashStr = "77d32517dcc7b74501096afdcff3af72008a2c489e17083f56629d195e5c6a1d".toHexBytesInByteString()

var call = Polymesh.Balance.Transfer.newBuilder().apply {
toAddress = "2CpqFh8VnwJAjenw4xSUWCaaJ2QwGdhnCikoSEczMhjgqyj7"
value = "0x0F4240".toHexBytesInByteString()
}

val input = Polymesh.SigningInput.newBuilder().apply {
genesisHash = genesisHashStr
blockHash = blockHashStr
era = Polkadot.Era.newBuilder().apply {
blockNumber = 16_102_106
period = 64
}.build()
network = POLYMESH.ss58Prefix()
nonce = 1
specVersion = 7000005
transactionVersion = 7
privateKey = TestKey1
runtimeCall = Polymesh.RuntimeCall.newBuilder().apply {
balanceCall = Polymesh.Balance.newBuilder().apply {
transfer = call.build()
}.build()
}.build()
}

val output = AnySigner.sign(input.build(), POLYMESH, SigningOutput.parser())
val encoded = Numeric.toHexString(output.encoded.toByteArray())

val expected = "0x390284004bdb9ef424035e1621e228bd11c5917d7d1dac5965d244c4c72fc91170244f0c00e9b4742a2b66931e0cf29f6811e4d44545b4f278a667b9eb1217c4b2de8763c8037e4501dd4a21179b737beb33415f458788f2d1093b527cae8bee8b2d55210ba501040005000010b713ceeb165c1ac7c450f5b138a6da0eba50bb18849f5b8e83985daa45a87e02093d00"
assertEquals(encoded, expected)
}
}
1 change: 1 addition & 0 deletions docs/registry.md
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ This list is generated from [./registry.json](../registry.json)
| 508 | MultiversX | eGLD | <img src="https://raw.githubusercontent.com/trustwallet/assets/master/blockchains/elrond/info/logo.png" width="32" /> | <https://multiversx.com/> |
| 529 | Secret | SCRT | <img src="https://raw.githubusercontent.com/trustwallet/assets/master/blockchains/secret/info/logo.png" width="32" /> | <https://scrt.network/> |
| 564 | Agoric | BLD | <img src="https://raw.githubusercontent.com/trustwallet/assets/master/blockchains/agoric/info/logo.png" width="32" /> | <https://agoric.com> |
| 595 | Polymesh | POLYX | <img src="https://raw.githubusercontent.com/trustwallet/assets/master/blockchains/polymesh/info/logo.png" width="32" /> | <https://polymesh.network> |
| 607 | TON | TON | <img src="https://raw.githubusercontent.com/trustwallet/assets/master/blockchains/ton/info/logo.png" width="32" /> | <https://ton.org> |
| 637 | Aptos | APT | <img src="https://raw.githubusercontent.com/trustwallet/assets/master/blockchains/aptos/info/logo.png" width="32" /> | <https://aptoslabs.com/> |
| 714 | BNB Beacon Chain | BNB | <img src="https://raw.githubusercontent.com/trustwallet/assets/master/blockchains/binance/info/logo.png" width="32" /> | <https://www.bnbchain.org> |
Expand Down
1 change: 1 addition & 0 deletions include/TrustWalletCore/TWBlockchain.h
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ enum TWBlockchain {
TWBlockchainBitcoinCash = 55,
TWBlockchainPactus = 56,
TWBlockchainKomodo = 57,
TWBlockchainPolymesh = 58, // Substrate
};

TW_EXTERN_C_END
1 change: 1 addition & 0 deletions include/TrustWalletCore/TWCoinType.h
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,7 @@ enum TWCoinType {
TWCoinTypeZkLinkNova = 810180,
TWCoinTypePactus = 21888,
TWCoinTypeSonic = 10000146,
TWCoinTypePolymesh = 595,
// end_of_tw_coin_type_marker_do_not_modify
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@ class CoinAddressDerivationTests {
Acala -> "25GGezx3LWFQj6HZpYzoWoVzLsHojGtybef3vthC9nd19ms3"
Kusama -> "G9xV2EatmrjRC1FLPexc3ddqNRRzCsAdURU8RFiAAJX6ppY"
Polkadot -> "13nN6BGAoJwd7Nw1XxeBCx5YcBXuYnL94Mh7i3xBprqVSsFk"
Polymesh -> "2DHK8VhBpacs9quk78AVP9TmmcG5iXi2oKtZqneSNsVXxCKw"
Pivx -> "D81AqC8zKma3Cht4TbVuh4jyVVyLkZULCm"
Kava -> "kava1drpa0x9ptz0fql3frv562rcrhj2nstuz3pas87"
Cardano -> "addr1qyr8jjfnypp95eq74aqzn7ss687ehxclgj7mu6gratmg3mul2040vt35dypp042awzsjk5xm3zr3zm5qh7454uwdv08s84ray2"
Expand Down
30 changes: 30 additions & 0 deletions registry.json
Original file line number Diff line number Diff line change
Expand Up @@ -4844,5 +4844,35 @@
"rpc": "https://docs.pactus.org/api/http",
"documentation": "https://docs.pactus.org"
}
},
{
"id": "polymesh",
"name": "Polymesh",
"coinId": 595,
"symbol": "POLYX",
"decimals": 6,
"blockchain": "Polymesh",
"derivation": [
{
"path": "m/44'/595'/0'/0'/0'"
}
],
"curve": "ed25519",
"publicKeyType": "ed25519",
"addressHasher": "keccak256",
"ss58Prefix": 12,
"explorer": {
"url": "https://polymesh.subscan.io",
"txPath": "/extrinsic/",
"accountPath": "/account/",
"sampleTx": "0x98cb5e33d8ff3dd5838c384e2ef9e291314ed8db13f5d4f42cdd70bad54a5e04",
"sampleAccount": "2E5u4xA1TqswQ3jMJH96zekxwr2itvKu79fDC1mmnVZRh6Uv"
},
"info": {
"url": "https://polymesh.network",
"source": "https://github.com/PolymeshAssociation/Polymesh",
"rpc": "wss://rpc.polymesh.network/",
"documentation": "https://developers.polymesh.network/"
}
}
]
17 changes: 17 additions & 0 deletions rust/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions rust/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ members = [
"chains/tw_native_injective",
"chains/tw_pactus",
"chains/tw_polkadot",
"chains/tw_polymesh",
"chains/tw_ripple",
"chains/tw_ronin",
"chains/tw_solana",
Expand Down
6 changes: 1 addition & 5 deletions rust/chains/tw_polkadot/src/call_encoder/mod.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use crate::{ctx_from_tw, KUSAMA, POLKADOT, POLYMESH};
use crate::{ctx_from_tw, KUSAMA, POLKADOT};
use tw_proto::Polkadot::Proto::{
self,
mod_Balance::{BatchAssetTransfer, BatchTransfer, OneOfmessage_oneof as BalanceVariant},
Expand All @@ -19,9 +19,6 @@ use generic::*;
pub mod polkadot;
use polkadot::*;

pub mod polymesh;
use polymesh::*;

pub fn validate_call_index(call_index: &Option<CallIndices>) -> EncodeResult<CallIndex> {
let index = match call_index {
Some(CallIndices {
Expand Down Expand Up @@ -56,7 +53,6 @@ impl CallEncoder {
let encoder = match ctx.network {
POLKADOT => PolkadotCallEncoder::new_boxed(ctx),
KUSAMA => KusamaCallEncoder::new_boxed(ctx),
POLYMESH => PolymeshCallEncoder::new_boxed(ctx),
_ => PolkadotCallEncoder::new_boxed(ctx),
};
Ok(Self { encoder })
Expand Down
Loading

0 comments on commit 9ede115

Please sign in to comment.