-
Notifications
You must be signed in to change notification settings - Fork 20
Add ADR-36 signatures support #195
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
8e205e5
96f5a53
313685d
6364a8f
b8619d5
f5723db
6d52ab7
80646fa
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,17 @@ | ||
| [package] | ||
| name = "defuse-adr36" | ||
| edition.workspace = true | ||
| version.workspace = true | ||
| rust-version.workspace = true | ||
| repository.workspace = true | ||
|
|
||
| [dependencies] | ||
| defuse-crypto = { workspace = true, features = ["serde"] } | ||
| near-sdk.workspace = true | ||
|
|
||
| [dev-dependencies] | ||
| near-sdk = { workspace = true, features = ["unit-testing"] } | ||
| hex-literal.workspace = true | ||
|
|
||
| [lints] | ||
| workspace = true |
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,189 @@ | ||||||||||||||||||||||||||||||||||||||||||||||||||
| use defuse_crypto::serde::AsCurve; | ||||||||||||||||||||||||||||||||||||||||||||||||||
| use defuse_crypto::{Curve, Payload, Secp256k1, SignedPayload}; | ||||||||||||||||||||||||||||||||||||||||||||||||||
| use near_sdk::base64::engine::{Engine, general_purpose::STANDARD}; | ||||||||||||||||||||||||||||||||||||||||||||||||||
| use near_sdk::serde_json::json; | ||||||||||||||||||||||||||||||||||||||||||||||||||
| use near_sdk::{CryptoHash, env, near}; | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||
| /// The signing algorithm to use. It determines the hash function to be used before signing. | ||||||||||||||||||||||||||||||||||||||||||||||||||
| /// If the chain you are using is Ethermint-like, usually your wallet sdk goes with the "ethsecp256k1", | ||||||||||||||||||||||||||||||||||||||||||||||||||
| /// otherwise "secp256k1". | ||||||||||||||||||||||||||||||||||||||||||||||||||
| /// [reference](https://github.com/chainapsis/keplr-wallet/blob/71552ca8443a3d40263cdfa1df4a7390e9c58692/packages/background/src/keyring-cosmos/service.ts#L1151) | ||||||||||||||||||||||||||||||||||||||||||||||||||
| #[near(serializers = [json])] | ||||||||||||||||||||||||||||||||||||||||||||||||||
| #[serde(rename_all = "snake_case")] | ||||||||||||||||||||||||||||||||||||||||||||||||||
| #[derive(Debug, Clone)] | ||||||||||||||||||||||||||||||||||||||||||||||||||
| pub enum Algorithm { | ||||||||||||||||||||||||||||||||||||||||||||||||||
| Secp256k1, | ||||||||||||||||||||||||||||||||||||||||||||||||||
| Ethsecp256k1, | ||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||
| impl Algorithm { | ||||||||||||||||||||||||||||||||||||||||||||||||||
| pub fn hash(&self, data: &[u8]) -> CryptoHash { | ||||||||||||||||||||||||||||||||||||||||||||||||||
| match self { | ||||||||||||||||||||||||||||||||||||||||||||||||||
| Self::Secp256k1 => env::sha256_array(data), | ||||||||||||||||||||||||||||||||||||||||||||||||||
| Self::Ethsecp256k1 => env::keccak256_array(data), | ||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||
| impl Default for Algorithm { | ||||||||||||||||||||||||||||||||||||||||||||||||||
| fn default() -> Self { | ||||||||||||||||||||||||||||||||||||||||||||||||||
| Self::Secp256k1 | ||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||
| /// [ADR-36 Standard reference](https://github.com/cosmos/cosmos-sdk/blob/main/docs/architecture/adr-036-arbitrary-signature.md) | ||||||||||||||||||||||||||||||||||||||||||||||||||
| /// [Usage docs](https://docs.keplr.app/api/guide/sign-arbitrary#adr-36-signing-with-signamino) | ||||||||||||||||||||||||||||||||||||||||||||||||||
| #[near(serializers = [json])] | ||||||||||||||||||||||||||||||||||||||||||||||||||
| #[serde(rename_all = "snake_case")] | ||||||||||||||||||||||||||||||||||||||||||||||||||
| #[derive(Debug, Clone)] | ||||||||||||||||||||||||||||||||||||||||||||||||||
| pub struct Adr36Payload { | ||||||||||||||||||||||||||||||||||||||||||||||||||
| pub message: String, | ||||||||||||||||||||||||||||||||||||||||||||||||||
| /// The Bech32 address of the account that will sign the message. | ||||||||||||||||||||||||||||||||||||||||||||||||||
| /// Example: `cosmos1skjwj5whet0lpe65qaq4rpq03hjxlwd5c9m9s6`, where: | ||||||||||||||||||||||||||||||||||||||||||||||||||
| /// * `cosmos`: network prefix | ||||||||||||||||||||||||||||||||||||||||||||||||||
| /// * `1`: separator | ||||||||||||||||||||||||||||||||||||||||||||||||||
| /// * remainder: data + checksum | ||||||||||||||||||||||||||||||||||||||||||||||||||
| pub signer: String, | ||||||||||||||||||||||||||||||||||||||||||||||||||
| #[serde(default)] | ||||||||||||||||||||||||||||||||||||||||||||||||||
| pub algo: Algorithm, | ||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||
| impl Adr36Payload { | ||||||||||||||||||||||||||||||||||||||||||||||||||
| #[inline] | ||||||||||||||||||||||||||||||||||||||||||||||||||
| pub const fn new(message: String, signer: String, algo: Algorithm) -> Self { | ||||||||||||||||||||||||||||||||||||||||||||||||||
| Self { | ||||||||||||||||||||||||||||||||||||||||||||||||||
| message, | ||||||||||||||||||||||||||||||||||||||||||||||||||
| signer, | ||||||||||||||||||||||||||||||||||||||||||||||||||
| algo, | ||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||
| /// [Implementation reference](https://github.com/chainapsis/keplr-wallet/blob/59b2e18122dc2ec3b12d3005fec709e4bcc885f8/packages/cosmos/src/adr-36/amino.ts#L88) | ||||||||||||||||||||||||||||||||||||||||||||||||||
| #[inline] | ||||||||||||||||||||||||||||||||||||||||||||||||||
| pub fn prehash(&self) -> Vec<u8> { | ||||||||||||||||||||||||||||||||||||||||||||||||||
| let json = json!({ | ||||||||||||||||||||||||||||||||||||||||||||||||||
| "account_number": "0", | ||||||||||||||||||||||||||||||||||||||||||||||||||
| "chain_id": "", | ||||||||||||||||||||||||||||||||||||||||||||||||||
| "fee": { | ||||||||||||||||||||||||||||||||||||||||||||||||||
| "amount": [], | ||||||||||||||||||||||||||||||||||||||||||||||||||
| "gas": "0", | ||||||||||||||||||||||||||||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||||||||||||||||||||||||||||
| "memo": "", | ||||||||||||||||||||||||||||||||||||||||||||||||||
| "msgs": [ | ||||||||||||||||||||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||||||||||||||||||||
| "type": "sign/MsgSignData", | ||||||||||||||||||||||||||||||||||||||||||||||||||
| "value": { | ||||||||||||||||||||||||||||||||||||||||||||||||||
| "data": STANDARD.encode(self.message.as_bytes()), | ||||||||||||||||||||||||||||||||||||||||||||||||||
| "signer": self.signer, | ||||||||||||||||||||||||||||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||||||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||||||||||||||||||||||||||||
| ], | ||||||||||||||||||||||||||||||||||||||||||||||||||
| "sequence": "0", | ||||||||||||||||||||||||||||||||||||||||||||||||||
| }); | ||||||||||||||||||||||||||||||||||||||||||||||||||
| json.to_string().into_bytes() | ||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||
| impl Payload for Adr36Payload { | ||||||||||||||||||||||||||||||||||||||||||||||||||
| #[inline] | ||||||||||||||||||||||||||||||||||||||||||||||||||
| fn hash(&self) -> CryptoHash { | ||||||||||||||||||||||||||||||||||||||||||||||||||
| self.algo.hash(&self.prehash()) | ||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||
| #[near(serializers = [json])] | ||||||||||||||||||||||||||||||||||||||||||||||||||
| #[derive(Debug, Clone)] | ||||||||||||||||||||||||||||||||||||||||||||||||||
| pub struct SignedAdr36Payload { | ||||||||||||||||||||||||||||||||||||||||||||||||||
| pub payload: Adr36Payload, | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||
| #[serde_as(as = "AsCurve<Secp256k1>")] | ||||||||||||||||||||||||||||||||||||||||||||||||||
| pub signature: <Secp256k1 as Curve>::Signature, | ||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||
| impl Payload for SignedAdr36Payload { | ||||||||||||||||||||||||||||||||||||||||||||||||||
| #[inline] | ||||||||||||||||||||||||||||||||||||||||||||||||||
| fn hash(&self) -> CryptoHash { | ||||||||||||||||||||||||||||||||||||||||||||||||||
| self.payload.hash() | ||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||
| impl SignedPayload for SignedAdr36Payload { | ||||||||||||||||||||||||||||||||||||||||||||||||||
| type PublicKey = <Secp256k1 as Curve>::PublicKey; | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||
| #[inline] | ||||||||||||||||||||||||||||||||||||||||||||||||||
| fn verify(&self) -> Option<Self::PublicKey> { | ||||||||||||||||||||||||||||||||||||||||||||||||||
| Secp256k1::verify(&self.signature, &self.payload.hash(), &()) | ||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+110
to
+116
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🧩 Analysis chain🏁 Script executed: # First, find the adr36 directory and examine the file
find . -type f -name "lib.rs" | grep -E "adr36|Adr36"Repository: near/intents Length of output: 74 🏁 Script executed: # Read the file to see the context around lines 110-116 and 126-132
cat -n adr36/src/lib.rs | sed -n '100,145p'Repository: near/intents Length of output: 2104 🏁 Script executed: # Check the entire file to understand the structure
wc -l adr36/src/lib.rsRepository: near/intents Length of output: 76 🏁 Script executed: # Check where fix_v_in_signature is used
grep -n "fix_v_in_signature" adr36/src/lib.rsRepository: near/intents Length of output: 268 🏁 Script executed: # See more of the test code to understand how it's used
cat -n adr36/src/lib.rs | sed -n '145,189p'Repository: near/intents Length of output: 1786 🏁 Script executed: # Check if there are other files that might handle v normalization
rg "fix_v_in_signature|normalize.*v" --type rustRepository: near/intents Length of output: 1005 Normalize Ethereum-style recovery Tests normalize 🛠️ Proposed fix+fn normalize_v(mut sig: <Secp256k1 as Curve>::Signature) -> <Secp256k1 as Curve>::Signature {
+ // Ethereum-style signatures use v=27/28; normalize to 0/1
+ if sig[64] >= 27 {
+ sig[64] -= 27;
+ }
+ sig
+}
+
impl SignedPayload for SignedAdr36Payload {
type PublicKey = <Secp256k1 as Curve>::PublicKey;
#[inline]
fn verify(&self) -> Option<Self::PublicKey> {
- Secp256k1::verify(&self.signature, &self.payload.hash(), &())
+ let sig = normalize_v(self.signature);
+ Secp256k1::verify(&sig, &self.payload.hash(), &())
}
}📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||
| #[cfg(test)] | ||||||||||||||||||||||||||||||||||||||||||||||||||
| mod tests { | ||||||||||||||||||||||||||||||||||||||||||||||||||
| use crate::{Adr36Payload, Algorithm, SignedAdr36Payload}; | ||||||||||||||||||||||||||||||||||||||||||||||||||
| use defuse_crypto::{Payload, SignedPayload}; | ||||||||||||||||||||||||||||||||||||||||||||||||||
| use hex_literal::hex; | ||||||||||||||||||||||||||||||||||||||||||||||||||
| use near_sdk::CryptoHash; | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||
| const fn fix_v_in_signature(mut sig: [u8; 65]) -> [u8; 65] { | ||||||||||||||||||||||||||||||||||||||||||||||||||
| if *sig.last().unwrap() >= 27 { | ||||||||||||||||||||||||||||||||||||||||||||||||||
| // Ethereum only uses uncompressed keys, with corresponding value v=27/28 | ||||||||||||||||||||||||||||||||||||||||||||||||||
| // https://bitcoin.stackexchange.com/a/38909/58790 | ||||||||||||||||||||||||||||||||||||||||||||||||||
| *sig.last_mut().unwrap() -= 27; | ||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||
| sig | ||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||
| /// golang cosmos-sdk [repro](https://gist.github.com/kuksag/eeb8ef3a77e6751d53db006b206925ab) | ||||||||||||||||||||||||||||||||||||||||||||||||||
| const REFERENCE_MESSAGE: &str = "Hello, ADR-036!"; | ||||||||||||||||||||||||||||||||||||||||||||||||||
| const REFERENCE_SECP256K1_SIGNER: &str = "cosmos1mnyn7x24xj6vraxeeq56dfkxa009tvhgknhm04"; | ||||||||||||||||||||||||||||||||||||||||||||||||||
| const REFERENCE_SHA256_HASH_MESSAGE_HEX: CryptoHash = | ||||||||||||||||||||||||||||||||||||||||||||||||||
| hex!("5ac8daed449a016684fd64bade7510b75ccd7c6eefa31b60a10eb577b37575e3"); | ||||||||||||||||||||||||||||||||||||||||||||||||||
| const REFERENCE_SIGNATURE: [u8; 65] = hex!( | ||||||||||||||||||||||||||||||||||||||||||||||||||
| "043485aac9cd7de64da9548b72635c061e07b20063488c0d3affc3c843b33c0458f799ac6592b6260c5ce326be4996d95ee8cfbea4ae76b820f2a7a01ad3a5cc1b" | ||||||||||||||||||||||||||||||||||||||||||||||||||
| ); | ||||||||||||||||||||||||||||||||||||||||||||||||||
| const WRONG_REFERENCE_SIGNATURE: [u8; 65] = hex!( | ||||||||||||||||||||||||||||||||||||||||||||||||||
| "c6ada709bab5a03bdbeb7e53e54ff77afbfec9e4f7b3d1b588e24f09d6f5dc305fa7cdb36c78d9f0c31859879eb930d28c890bcf9e27944e7e8808b1a53c09661c" | ||||||||||||||||||||||||||||||||||||||||||||||||||
| ); | ||||||||||||||||||||||||||||||||||||||||||||||||||
| const REFERENCE_PUBKEY: [u8; 64] = hex!( | ||||||||||||||||||||||||||||||||||||||||||||||||||
| "4646ae5047316b4230d0086c8acec687f00b1cd9d1dc634f6cb358ac0a9a8ffffe77b4dd0a4bfb95851f3b7355c781dd60f8418fc8a65d14907aff47c903a559" | ||||||||||||||||||||||||||||||||||||||||||||||||||
| ); | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||
| #[test] | ||||||||||||||||||||||||||||||||||||||||||||||||||
| fn test_expected_sha256_hash() { | ||||||||||||||||||||||||||||||||||||||||||||||||||
| let payload = Adr36Payload::new( | ||||||||||||||||||||||||||||||||||||||||||||||||||
| REFERENCE_MESSAGE.to_string(), | ||||||||||||||||||||||||||||||||||||||||||||||||||
| REFERENCE_SECP256K1_SIGNER.to_string(), | ||||||||||||||||||||||||||||||||||||||||||||||||||
| Algorithm::Secp256k1, | ||||||||||||||||||||||||||||||||||||||||||||||||||
| ); | ||||||||||||||||||||||||||||||||||||||||||||||||||
| assert_eq!(payload.hash(), REFERENCE_SHA256_HASH_MESSAGE_HEX); | ||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||
| #[test] | ||||||||||||||||||||||||||||||||||||||||||||||||||
| fn test_reference_signature_verification_works() { | ||||||||||||||||||||||||||||||||||||||||||||||||||
| let payload = Adr36Payload::new( | ||||||||||||||||||||||||||||||||||||||||||||||||||
| REFERENCE_MESSAGE.to_string(), | ||||||||||||||||||||||||||||||||||||||||||||||||||
| REFERENCE_SECP256K1_SIGNER.to_string(), | ||||||||||||||||||||||||||||||||||||||||||||||||||
| Algorithm::Secp256k1, | ||||||||||||||||||||||||||||||||||||||||||||||||||
| ); | ||||||||||||||||||||||||||||||||||||||||||||||||||
| let signature = fix_v_in_signature(REFERENCE_SIGNATURE); | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||
| assert_eq!( | ||||||||||||||||||||||||||||||||||||||||||||||||||
| SignedAdr36Payload { payload, signature }.verify(), | ||||||||||||||||||||||||||||||||||||||||||||||||||
| Some(REFERENCE_PUBKEY) | ||||||||||||||||||||||||||||||||||||||||||||||||||
| ); | ||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||
| #[test] | ||||||||||||||||||||||||||||||||||||||||||||||||||
| fn test_reference_signature_verification_fails() { | ||||||||||||||||||||||||||||||||||||||||||||||||||
| let payload = Adr36Payload::new( | ||||||||||||||||||||||||||||||||||||||||||||||||||
| REFERENCE_MESSAGE.to_string(), | ||||||||||||||||||||||||||||||||||||||||||||||||||
| REFERENCE_SECP256K1_SIGNER.to_string(), | ||||||||||||||||||||||||||||||||||||||||||||||||||
| Algorithm::Secp256k1, | ||||||||||||||||||||||||||||||||||||||||||||||||||
| ); | ||||||||||||||||||||||||||||||||||||||||||||||||||
| let signature = fix_v_in_signature(WRONG_REFERENCE_SIGNATURE); | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||
| assert_ne!( | ||||||||||||||||||||||||||||||||||||||||||||||||||
| SignedAdr36Payload { payload, signature }.verify(), | ||||||||||||||||||||||||||||||||||||||||||||||||||
| Some(REFERENCE_PUBKEY) | ||||||||||||||||||||||||||||||||||||||||||||||||||
| ); | ||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,26 @@ | ||
| use crate::payload::{DefusePayload, ExtractDefusePayload}; | ||
| use defuse_adr36::{Adr36Payload, SignedAdr36Payload}; | ||
| use near_sdk::{serde::de::DeserializeOwned, serde_json}; | ||
|
|
||
| impl<T> ExtractDefusePayload<T> for SignedAdr36Payload | ||
| where | ||
| T: DeserializeOwned, | ||
| { | ||
| type Error = serde_json::Error; | ||
|
|
||
| #[inline] | ||
| fn extract_defuse_payload(self) -> Result<DefusePayload<T>, Self::Error> { | ||
| self.payload.extract_defuse_payload() | ||
| } | ||
| } | ||
|
|
||
| impl<T> ExtractDefusePayload<T> for Adr36Payload | ||
| where | ||
| T: DeserializeOwned, | ||
| { | ||
| type Error = serde_json::Error; | ||
|
|
||
| fn extract_defuse_payload(self) -> Result<DefusePayload<T>, Self::Error> { | ||
| serde_json::from_str(&self.message) | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,3 +1,4 @@ | ||
| pub mod adr36; | ||
| pub mod erc191; | ||
| pub mod multi; | ||
| pub mod nep413; | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
According to docs:
Since we already represent
self.messageasString, does it make sense to avoid base64 encoding here and embedmessageas-is?Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good catch. I'm gonna say I've overlooked that, because I was referencing implementations of the most used wallets on Cosmos SDK, and they wrap a message into base64:
https://github.com/chainapsis/keplr-wallet/blob/59b2e18122dc2ec3b12d3005fec709e4bcc885f8/packages/cosmos/src/adr-36/amino.ts#L78
https://github.com/leapwallet/cosmos-extension/blob/d6747ff73851d8e958dfec9ef1da4809100d694a/packages/wallet-provider/src/provider/core.ts#L295
To comply with the standard and to have something working in practise, we can verify the signature against both
b64(message)(as of right now) and plaindata.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah, ok, if that's a convention across ecosystem - I'm ok with leaving it in current state, i.e. always encode as base64