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 65f59720ca4..94b2f723f45 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
@@ -45,7 +45,7 @@ class CoinAddressDerivationTests {
ETHEREUM, SMARTCHAIN, POLYGON, OPTIMISM, ZKSYNC, ARBITRUM, ECOCHAIN, AVALANCHECCHAIN, XDAI,
FANTOM, CELO, CRONOSCHAIN, SMARTBITCOINCASH, KUCOINCOMMUNITYCHAIN, BOBA, METIS,
AURORA, EVMOS, MOONRIVER, MOONBEAM, KAVAEVM, KLAYTN, METER, OKXCHAIN, POLYGONZKEVM, SCROLL,
- CONFLUXESPACE, ACALAEVM, OPBNBTESTNET -> assertEquals("0x8f348F300873Fd5DA36950B2aC75a26584584feE", address)
+ CONFLUXESPACE, ACALAEVM, OPBNBTESTNET, NEON, BASE -> assertEquals("0x8f348F300873Fd5DA36950B2aC75a26584584feE", address)
RONIN -> assertEquals("ronin:8f348F300873Fd5DA36950B2aC75a26584584feE", address)
ETHEREUMCLASSIC -> assertEquals("0x078bA3228F3E6C08bEEac9A005de0b7e7089aD1c", address)
GOCHAIN -> assertEquals("0x5940ce4A14210d4Ccd0ac206CE92F21828016aC2", address)
diff --git a/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/ethereum/TestBarz.kt b/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/ethereum/TestBarz.kt
index cb9d745f96e..235cd442b73 100644
--- a/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/ethereum/TestBarz.kt
+++ b/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/ethereum/TestBarz.kt
@@ -34,10 +34,21 @@ class TestBarz {
val publicKeyData = Numeric.hexStringToByteArray("04e6f4e0351e2f556fd7284a9a033832bae046ac31fd529ad02ab6220870624b79eb760e718fdaed7a037dd1d77a561759cee9f2706eb55a729dc953e0d5719b02")
val publicKey = PublicKey(publicKeyData, PublicKeyType.NIST256P1EXTENDED)
val verificationFacet = "0x6BF22ff186CC97D88ECfbA47d1473a234CEBEFDf"
- val result = WCBarz.getInitCode(factoryAddress, publicKey, verificationFacet)
+ val result = WCBarz.getInitCode(factoryAddress, publicKey, verificationFacet, 0)
assertEquals(Numeric.toHexString(result), "0x3fc708630d85a3b5ec217e53100ec2b735d4f800296601cd0000000000000000000000006bf22ff186cc97d88ecfba47d1473a234cebefdf00000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004104e6f4e0351e2f556fd7284a9a033832bae046ac31fd529ad02ab6220870624b79eb760e718fdaed7a037dd1d77a561759cee9f2706eb55a729dc953e0d5719b0200000000000000000000000000000000000000000000000000000000000000")
}
+ @Test
+ fun testInitCodeNonZeroSalt() {
+ val factoryAddress = "0x3fC708630d85A3B5ec217E53100eC2b735d4f800"
+ val publicKeyData = Numeric.hexStringToByteArray("04e6f4e0351e2f556fd7284a9a033832bae046ac31fd529ad02ab6220870624b79eb760e718fdaed7a037dd1d77a561759cee9f2706eb55a729dc953e0d5719b02")
+ val publicKey = PublicKey(publicKeyData, PublicKeyType.NIST256P1EXTENDED)
+ val verificationFacet = "0x6BF22ff186CC97D88ECfbA47d1473a234CEBEFDf"
+ val salt = 1
+ val result = WCBarz.getInitCode(factoryAddress, publicKey, verificationFacet, salt)
+ assertEquals(Numeric.toHexString(result), "0x3fc708630d85a3b5ec217e53100ec2b735d4f800296601cd0000000000000000000000006bf22ff186cc97d88ecfba47d1473a234cebefdf00000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000004104e6f4e0351e2f556fd7284a9a033832bae046ac31fd529ad02ab6220870624b79eb760e718fdaed7a037dd1d77a561759cee9f2706eb55a729dc953e0d5719b0200000000000000000000000000000000000000000000000000000000000000")
+ }
+
@Test
fun testCounterfactualAddress() {
val input = Barz.ContractAddressInput.newBuilder()
@@ -55,6 +66,24 @@ class TestBarz {
assertEquals(result, "0x77F62bb3E43190253D4E198199356CD2b25063cA")
}
+ @Test
+ fun testCounterfactualAddressNonZeroSalt() {
+ val input = Barz.ContractAddressInput.newBuilder()
+ input.apply {
+ factory = "0x96C489979E39F877BDb8637b75A25C1a5B2DE14C"
+ accountFacet = "0xF6F5e5fC74905e65e3FF53c6BacEba8535dd14d1"
+ verificationFacet = "0xaB84813cbf26Fd951CB3d7E33Dccb8995027e490"
+ entryPoint = "0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789"
+ facetRegistry = "0x9a95d201BB8F559771784D12c01F8084278c65E5"
+ defaultFallback = "0x522cDc7558b5f798dF5D61AB09B6D95Ebd342EF9"
+ bytecode = "0x60806040526040516104c83803806104c883398101604081905261002291610163565b6000858585858560405160240161003d959493929190610264565b60408051601f198184030181529181526020820180516001600160e01b0316634a93641760e01b1790525190915060009081906001600160a01b038a16906100869085906102c3565b600060405180830381855af49150503d80600081146100c1576040519150601f19603f3d011682016040523d82523d6000602084013e6100c6565b606091505b50915091508115806100e157506100dc816102df565b600114155b156100ff57604051636ff35f8960e01b815260040160405180910390fd5b505050505050505050610306565b80516001600160a01b038116811461012457600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b60005b8381101561015a578181015183820152602001610142565b50506000910152565b60008060008060008060c0878903121561017c57600080fd5b6101858761010d565b95506101936020880161010d565b94506101a16040880161010d565b93506101af6060880161010d565b92506101bd6080880161010d565b60a08801519092506001600160401b03808211156101da57600080fd5b818901915089601f8301126101ee57600080fd5b81518181111561020057610200610129565b604051601f8201601f19908116603f0116810190838211818310171561022857610228610129565b816040528281528c602084870101111561024157600080fd5b61025283602083016020880161013f565b80955050505050509295509295509295565b600060018060a01b0380881683528087166020840152808616604084015280851660608401525060a0608083015282518060a08401526102ab8160c085016020870161013f565b601f01601f19169190910160c0019695505050505050565b600082516102d581846020870161013f565b9190910192915050565b80516020808301519190811015610300576000198160200360031b1b821691505b50919050565b6101b3806103156000396000f3fe60806040523661000b57005b600080356001600160e01b03191681527f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f6020819052604090912054819060601c806100cf576004838101546040516366ffd66360e11b81526000356001600160e01b031916928101929092526001600160a01b03169063cdffacc690602401602060405180830381865afa1580156100a8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906100cc919061014d565b90505b6001600160a01b0381166101295760405162461bcd60e51b815260206004820152601d60248201527f4261727a3a2046756e6374696f6e20646f6573206e6f74206578697374000000604482015260640160405180910390fd5b3660008037600080366000845af43d6000803e808015610148573d6000f35b3d6000fd5b60006020828403121561015f57600080fd5b81516001600160a01b038116811461017657600080fd5b939250505056fea2646970667358221220d35db061bb6ecdb7688c3674af669ce44d527cae4ded59214d06722d73da62be64736f6c63430008120033"
+ publicKey = "0xB5547FBdC56DCE45e1B8ef75569916D438e09c46"
+ salt = 123456
+ }
+ val result = WCBarz.getCounterfactualAddress(input.build().toByteArray())
+ assertEquals(result, "0xB91aaa96B138A1B1D94c9df4628187132c5F2bf1")
+ }
+
@Test
fun testGetFormattedSignature() {
val signature = Numeric.hexStringToByteArray("0x3044022012d89e3b41e253dc9e90bd34dc1750d059b76d0b1d16af2059aa26e90b8960bf0220256d8a05572c654906ce422464693e280e243e6d9dbc5f96a681dba846bca276")
@@ -126,7 +155,7 @@ class TestBarz {
sender = "0x1392Ae041BfBdBAA0cFF9234a0C8F64df97B7218"
preVerificationGas = ByteString.copyFrom("0xb708".toHexByteArray())
verificationGasLimit = ByteString.copyFrom("0x2DC6C0".toHexByteArray())
- initCode = ByteString.copyFrom(WCBarz.getInitCode(factoryAddress, publicKey, verificationFacet))
+ initCode = ByteString.copyFrom(WCBarz.getInitCode(factoryAddress, publicKey, verificationFacet, 0))
}.build()
transaction = Ethereum.Transaction.newBuilder().apply {
diff --git a/docs/registry.md b/docs/registry.md
index 40d4db58107..df5c8145a01 100644
--- a/docs/registry.md
+++ b/docs/registry.md
@@ -86,6 +86,7 @@ This list is generated from [./registry.json](../registry.json)
| 3030 | Hedera | HBAR | | |
| 5611 | OpBNB testnet | tBNB | | |
| 6060 | GoChain | GO | | |
+| 8453 | Base | ETH | | |
| 8964 | NULS | NULS | | |
| 14001 | WAX | WAXP | | |
| 18000 | Meter | MTR | | |
diff --git a/include/TrustWalletCore/TWBarz.h b/include/TrustWalletCore/TWBarz.h
index e68a6527c0e..3bc08ed31b4 100644
--- a/include/TrustWalletCore/TWBarz.h
+++ b/include/TrustWalletCore/TWBarz.h
@@ -30,7 +30,7 @@ TWString *_Nonnull TWBarzGetCounterfactualAddress(TWData *_Nonnull input);
/// \param verificationFacet Verification facet address
/// \return The address.
TW_EXPORT_STATIC_METHOD
-TWData *_Nonnull TWBarzGetInitCode(TWString* _Nonnull factory, struct TWPublicKey* _Nonnull publicKey, TWString* _Nonnull verificationFacet);
+TWData *_Nonnull TWBarzGetInitCode(TWString* _Nonnull factory, struct TWPublicKey* _Nonnull publicKey, TWString* _Nonnull verificationFacet, uint32_t salt);
/// Converts the original ASN-encoded signature from webauthn to the format accepted by Barz
///
diff --git a/include/TrustWalletCore/TWCoinType.h b/include/TrustWalletCore/TWCoinType.h
index c6de3d4e5dd..beef6628af1 100644
--- a/include/TrustWalletCore/TWCoinType.h
+++ b/include/TrustWalletCore/TWCoinType.h
@@ -169,6 +169,8 @@ enum TWCoinType {
TWCoinTypeAcala = 787,
TWCoinTypeAcalaEVM = 10000787,
TWCoinTypeOpBNBtestnet = 5611,
+ TWCoinTypeNeon = 245022934,
+ TWCoinTypeBase = 8453,
};
/// Returns the blockchain for a coin type.
diff --git a/registry.json b/registry.json
index 2cfd4282050..f1fd12c7ec5 100644
--- a/registry.json
+++ b/registry.json
@@ -350,6 +350,36 @@
"documentation": "https://docs.syscoin.org"
}
},
+ {
+ "id": "base",
+ "name": "Base",
+ "coinId": 8453,
+ "symbol": "ETH",
+ "decimals": 18,
+ "blockchain": "Ethereum",
+ "derivation": [
+ {
+ "path": "m/44'/60'/0'/0/0"
+ }
+ ],
+ "curve": "secp256k1",
+ "publicKeyType": "secp256k1Extended",
+ "chainId": "8453",
+ "addressHasher": "keccak256",
+ "explorer": {
+ "url": "https://basescan.org",
+ "txPath": "/tx/",
+ "accountPath": "/address/",
+ "sampleTx": "0x4acb15506b7696a2dfac4258f3f86392b4b2b717a3f316a8aa78509b2c3b6ab4",
+ "sampleAccount": "0xb8ff877ed78ba520ece21b1de7843a8a57ca47cb"
+ },
+ "info": {
+ "url": "https://base.mirror.xyz/",
+ "source": "https://github.com/base-org",
+ "rpc": "https://mainnet.base.org",
+ "documentation": "https://docs.base.org/"
+ }
+ },
{
"id": "ethereum",
"name": "Ethereum",
diff --git a/src/Ethereum/ABI/Array.cpp b/src/Ethereum/ABI/Array.cpp
index b47fc8b034c..a75c92f9b15 100644
--- a/src/Ethereum/ABI/Array.cpp
+++ b/src/Ethereum/ABI/Array.cpp
@@ -141,6 +141,13 @@ std::shared_ptr ParamArray::clone() const {
return newArray;
}
+std::shared_ptr ParamArray::clone() const {
+ auto newArray = std::make_shared();
+ newArray->_params = _params.clone();
+ newArray->_proto = _proto->clone();
+ return newArray;
+}
+
void ParamArrayFix::encode(Data& data) const {
this->_params.encode(data);
}
diff --git a/src/Ethereum/ABI/Array.h b/src/Ethereum/ABI/Array.h
index 4638c38f171..9a2e38bbd08 100644
--- a/src/Ethereum/ABI/Array.h
+++ b/src/Ethereum/ABI/Array.h
@@ -45,7 +45,7 @@ class ParamArray final : public ParamCollection {
bool decode(const Data& encoded, size_t& offset_inout) override;
bool setValueJson(const std::string& value) override;
Data hashStruct() const override;
- void fillExtraTypesMap(ExtraTypesMap& extraTypes) const override;
+ std::string getExtraTypes(std::vector& ignoreList) const override;
std::shared_ptr clone() const override;
};
diff --git a/src/Ethereum/ABI/ParamBase.h b/src/Ethereum/ABI/ParamBase.h
index 882a9571e0f..11039de5a75 100644
--- a/src/Ethereum/ABI/ParamBase.h
+++ b/src/Ethereum/ABI/ParamBase.h
@@ -8,16 +8,11 @@
#include "Data.h"
-#include