Skip to content
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

Feat: stellar integration #1057

Merged
merged 46 commits into from
Jul 4, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
46 commits
Select commit Hold shift + click to select a range
27c5428
chore: add stellar rust app
Charon-Fan May 17, 2024
7ce828b
fix: update stellar address and private key generation
Charon-Fan May 17, 2024
256729f
fix: Update stellar address and private key generation
Charon-Fan May 22, 2024
5bdb46d
refactor: Update sign function to use hash instead of message
Charon-Fan May 22, 2024
0242020
style: stellar app fmt
Charon-Fan May 22, 2024
e4e08ec
feat: Add enum for Stellar network types
Charon-Fan May 22, 2024
e095702
feat: Add support for Stellar network types
Charon-Fan May 24, 2024
742cb5c
Merge branch 'master' into feat/stellar-integration
Charon-Fan May 24, 2024
23f821f
style: stellar app fmt
Charon-Fan May 24, 2024
d20f9bc
feat: Add function to generate Stellar addresses from public keys
Charon-Fan May 24, 2024
a9696cd
feat: Add support for Stellar Rust C integration
Charon-Fan May 27, 2024
fd3cbc3
Merge branch 'master' into feat/stellar-integration
Charon-Fan May 27, 2024
2845197
chore: receive xlm
Charon-Fan May 27, 2024
16d639f
feat: Add xbull wallet support
Charon-Fan May 27, 2024
97b25bd
feat: Update stellar i18n
Charon-Fan May 27, 2024
67f27ab
feat: Add Stellar Rust C integration and support for Stellar addresse…
Charon-Fan May 28, 2024
f848f57
feat: Update Stellar integration
Charon-Fan May 31, 2024
d1a6b43
Merge branch 'master' into feat/stellar-integration
Charon-Fan May 31, 2024
c202a10
feat: Add xBull wallet integration
Charon-Fan May 31, 2024
c950649
style: wallet fmt
Charon-Fan May 31, 2024
a156739
chore: Update error messages in Stellar module and add tests for erro…
Charon-Fan May 31, 2024
afdebbb
chore: Add unit tests for generate_sync_ur function in solana.rs and …
Charon-Fan May 31, 2024
2a9701e
feat: Add support for getting the length of Stellar raw message
Charon-Fan May 31, 2024
fd99451
feat: Update Stellar integration
Charon-Fan May 31, 2024
364162a
chore: Update ur-registry and ur-parse-lib dependencies
Charon-Fan May 31, 2024
4c7af26
chore: Add requestId to signature response
Charon-Fan Jun 3, 2024
5127358
feat: Add support for Stellar hash notice in GUI
Charon-Fan Jun 4, 2024
013ea6c
chore: Update GUI for Stellar hash notice and length retrieval
Charon-Fan Jun 4, 2024
edc0d4e
Merge branch 'master' into feat/stellar-integration
Charon-Fan Jun 5, 2024
6dd1a05
chore: Update version to 1.4.9
Charon-Fan Jun 5, 2024
cb182e9
Merge branch 'master' into feat/stellar-integration
Charon-Fan Jun 11, 2024
d36ed87
Merge branch 'master' into feat/stellar-integration
Charon-Fan Jun 26, 2024
2cad665
chore: Update image hash and fix code formatting in font files
Charon-Fan Jun 26, 2024
6ad5335
Merge branch 'master' into feat/stellar-integration
Charon-Fan Jun 27, 2024
3cb1345
feat: Add Stellar sign QR code generation for ViewType StellarTx and …
Charon-Fan Jun 27, 2024
389a739
chore: Refactor rendering of switch buttons
Charon-Fan Jun 27, 2024
5c3942f
Merge branch 'master' into feat/stellar-integration
Charon-Fan Jul 3, 2024
4e1d7c9
chore: update image hash
Charon-Fan Jul 3, 2024
54c1d98
feat: update scan QR code signing notice and description
Charon-Fan Jul 3, 2024
456726e
feat: update scan QR code signing notice and description
Charon-Fan Jul 3, 2024
19d3bb8
style: rust_c fmt
Charon-Fan Jul 4, 2024
0d34ba8
style: wallet fmt
Charon-Fan Jul 4, 2024
8dfdc82
chore: fix formatting in aptos.rs file
Charon-Fan Jul 4, 2024
c4de487
Merge branch 'master' into feat/stellar-integration
Charon-Fan Jul 4, 2024
e7c994a
style: app utils fmt
Charon-Fan Jul 4, 2024
57193ea
feat: add alloc::string::ToString to test module
Charon-Fan Jul 4, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .github/workflows/rust-fmt-checks.yml
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@ jobs:
run: cd rust/apps/sui && cargo +nightly-2023-06-26 fmt --check
- name: Run rust/apps/arweave
run: cd rust/apps/arweave && cargo +nightly-2023-06-26 fmt --check
- name: Run rust/apps/stellar
run: cd rust/apps/stellar && cargo +nightly-2023-06-26 fmt --check
- name: Run rust/apps/utils
run: cd rust/apps/utils && cargo +nightly-2023-06-26 fmt --check
- name: Run rust/apps/wallets
Expand Down
27 changes: 27 additions & 0 deletions .github/workflows/rust-stellar-checks.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
on:
pull_request:
paths:
- rust/apps/stellar/**

name: Stellar Checks

jobs:
UnitTest:
name: Unit Test And Code coverage
runs-on: ubuntu-latest
steps:
- name: Checkout sources
uses: actions/checkout@v2

- uses: actions-rs/toolchain@v1
with:
toolchain: nightly-2023-06-26
override: true
components: rustfmt
target: x86_64-apple-darwin

- name: Install cargo-llvm-cov
uses: taiki-e/install-action@cargo-llvm-cov

- name: Run rust/apps/stellar
run: cd rust/apps/stellar && cargo +nightly-2023-06-26 llvm-cov --fail-under-functions 50 --fail-under-lines 50 --fail-under-regions 50
Binary file added images/coin/coinXlm.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added images/img/imgNotice.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added images/wallet/walletXBull.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added images/walletList/walletListXBull.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
10 changes: 10 additions & 0 deletions rust/apps/stellar/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
[package]
name = "app_stellar"
version = "0.1.0"
edition = "2021"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
third_party = { path = "../../third_party" }
keystore = { path = "../../keystore", default-features = false }
1 change: 1 addition & 0 deletions rust/apps/stellar/rust-toolchain
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
nightly
78 changes: 78 additions & 0 deletions rust/apps/stellar/src/address.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
use crate::errors::{Result, StellarError};
use crate::strkeys::{calculate_crc16_checksum, encode_base32, StrKeyType};
use alloc::string::String;
use alloc::vec::Vec;
use core::str::FromStr;
use keystore::algorithms::ed25519::slip10_ed25519::get_public_key_by_seed;
use third_party::hex;

pub fn get_address(pub_key: &String) -> Result<String> {
match hex::decode(pub_key) {
Ok(pub_key) => {
let key_type = StrKeyType::STRKEY_PUBKEY;
let key = [key_type as u8]
.iter()
.chain(pub_key.iter())
.cloned()
.collect::<Vec<u8>>();
let checksum = calculate_crc16_checksum(&key);
let data = key
.iter()
.chain(checksum.iter())
.cloned()
.collect::<Vec<u8>>();
Ok(encode_base32(&data))
}
Err(e) => Err(StellarError::AddressError(format!(
"hex decode error {}",
e
))),
}
}

pub fn generate_stellar_address(seed: &[u8], path: &String) -> Result<String> {
let public_key = get_public_key_by_seed(seed, path)?;
get_address(&hex::encode(public_key))
}

#[cfg(test)]
mod tests {
use super::*;
use alloc::string::ToString;
use third_party::hex;

#[test]
fn test_stellar_address() {
let seed = hex::decode("96063c45132c840f7e1665a3b97814d8eb2586f34bd945f06fa15b9327eebe355f654e81c6233a52149d7a95ea7486eb8d699166f5677e507529482599624cdc").unwrap();
let path = "m/44'/148'/0'".to_string();
let address = generate_stellar_address(&seed, &path).unwrap();
assert_eq!(
"GDKLQMRO2LFHLJ5I67VVOBLUOGYXXV6V72SPTKFCSNRWWTLFH7HT33AU",
address
);
}

#[test]
fn test_stellar_xpub_address() {
let xpub = "5f5a723f0f3ef785387b016a8b61eb2713b02f429edadfacd96082d7da029594";
let address_from_xpub = get_address(&xpub.to_string()).unwrap();
assert_eq!(
"GBPVU4R7B47PPBJYPMAWVC3B5MTRHMBPIKPNVX5M3FQIFV62AKKZIPNL",
address_from_xpub
);
}

#[test]
fn test_stellar_xpub_address_error() {
let address_error = StellarError::AddressError(
"hex decode error Invalid character 'g' at position 63".to_string(),
);
let error: StellarError = address_error.into();
let xpub = "5f5a723f0f3ef785387b016a8b61eb2713b02f429edadfacd96082d7da02959g";
let address_from_xpub = get_address(&xpub.to_string());
assert_eq!(
error.to_string(),
address_from_xpub.unwrap_err().to_string()
);
}
}
70 changes: 70 additions & 0 deletions rust/apps/stellar/src/errors.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
use alloc::format;
use alloc::string::{String, ToString};
use keystore::errors::KeystoreError;
use third_party::hex;
use third_party::serde_json;
use third_party::serde_json::Error;
use third_party::thiserror;
use thiserror::Error;

#[derive(Error, Debug)]
pub enum StellarError {
#[error("meet error when encoding address: {0}")]
AddressError(String),
#[error("keystore operation failed, reason: {0}")]
KeystoreError(String),
#[error("Meet invalid data when reading `{0}`")]
InvalidData(String),
#[error("Could not parse transaction, reason: `{0}`")]
ParseTxError(String),
}

pub type Result<T> = core::result::Result<T, StellarError>;

impl From<KeystoreError> for StellarError {
fn from(value: KeystoreError) -> Self {
Self::KeystoreError(value.to_string())
}
}

impl From<hex::FromHexError> for StellarError {
fn from(value: hex::FromHexError) -> Self {
Self::InvalidData(format!("hex operation failed {}", value))
}
}

impl From<serde_json::Error> for StellarError {
fn from(value: Error) -> Self {
Self::ParseTxError(format!(
"serde json operation failed {:?}",
value.to_string()
))
}
}

#[cfg(test)]
mod tests {
use super::*;

#[test]
fn test_stellar_error() {
let err = StellarError::AddressError("test".to_string());
assert_eq!(err.to_string(), "meet error when encoding address: test");
let err = StellarError::KeystoreError("test".to_string());
assert_eq!(err.to_string(), "keystore operation failed, reason: test");
let err = StellarError::InvalidData("test".to_string());
assert_eq!(err.to_string(), "Meet invalid data when reading `test`");
let err = StellarError::ParseTxError("test".to_string());
assert_eq!(
err.to_string(),
"Could not parse transaction, reason: `test`"
);
}

#[test]
fn test_stellar_error_from() {
let err = hex::FromHexError::InvalidHexCharacter { c: 'a', index: 0 };
let err = StellarError::from(err);
assert_eq!(err.to_string(), "Meet invalid data when reading `hex operation failed Invalid character 'a' at position 0`");
}
}
79 changes: 79 additions & 0 deletions rust/apps/stellar/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
#![no_std]
#![feature(error_in_core)]

pub mod address;
pub mod errors;
pub mod strkeys;
pub mod structs;

#[macro_use]
extern crate alloc;

use crate::structs::Network;
use alloc::string::String;
use alloc::vec::Vec;
use third_party::base64;
use third_party::hex;

pub fn get_network_from_base(base: &[u8]) -> Network {
let network_id = &base[0..32];
Network::from_hash(network_id)
}

fn strip_network_prefix(base: &[u8]) -> Vec<u8> {
base[32..].to_vec()
}

pub fn base_to_xdr(base: &[u8]) -> String {
let stripped_base = strip_network_prefix(base);
base64::encode(&stripped_base)
}

#[cfg(test)]
mod tests {
use super::*;

#[test]
fn test_network() {
let public = Network::Public;
assert_eq!(
"Public Global Stellar Network ; September 2015",
public.get()
);
}

#[test]
fn test_network_hash() {
let public = Network::Public;
assert_eq!(
"7ac33997544e3175d266bd022439b22cdb16508c01163f26e5cb2a3e1045a979",
public.hash()
);
}

#[test]
fn test_hash_from() {
let signature_base = "7ac33997544e3175d266bd022439b22cdb16508c01163f26e5cb2a3e1045a979000000020000000096e8c54780e871fabf106cb5b047149e72b04aa5e069a158b2d0e7a68ab50d4f00002710031494870000000a00000001000000000000000000000000664ed303000000000000000100000000000000060000000155534443000000003b9911380efe988ba0a8900eb1cfe44f366f7dbe946bed077240f7f624df15c57fffffffffffffff00000000";
let network = get_network_from_base(&hex::decode(signature_base).unwrap());
assert_eq!(
network.get(),
"Public Global Stellar Network ; September 2015"
);
}

#[test]
fn test_strip_network_prefix() {
let signature_base = "7ac33997544e3175d266bd022439b22cdb16508c01163f26e5cb2a3e1045a979000000020000000096e8c54780e871fabf106cb5b047149e72b04aa5e069a158b2d0e7a68ab50d4f00002710031494870000000a00000001000000000000000000000000664ed303000000000000000100000000000000060000000155534443000000003b9911380efe988ba0a8900eb1cfe44f366f7dbe946bed077240f7f624df15c57fffffffffffffff00000000";
let data = strip_network_prefix(&hex::decode(signature_base).unwrap());
assert_eq!(data.len(), 144);
assert_eq!(hex::encode(data), "000000020000000096e8c54780e871fabf106cb5b047149e72b04aa5e069a158b2d0e7a68ab50d4f00002710031494870000000a00000001000000000000000000000000664ed303000000000000000100000000000000060000000155534443000000003b9911380efe988ba0a8900eb1cfe44f366f7dbe946bed077240f7f624df15c57fffffffffffffff00000000");
}

// #[test]
// fn test_base_to_xdr() {
// let signature_base = "7ac33997544e3175d266bd022439b22cdb16508c01163f26e5cb2a3e1045a979000000020000000096e8c54780e871fabf106cb5b047149e72b04aa5e069a158b2d0e7a68ab50d4f00002710031494870000000a00000001000000000000000000000000664ed303000000000000000100000000000000060000000155534443000000003b9911380efe988ba0a8900eb1cfe44f366f7dbe946bed077240f7f624df15c57fffffffffffffff00000000";
// let target_xdr = "AAAAAgAAAACW6MVHgOhx+r8QbLWwRxSecrBKpeBpoViy0OemirUNTwAAJxADFJSHAAAACgAAAAEAAAAAAAAAAAAAAABmTtMDAAAAAAAAAAEAAAAAAAAABgAAAAFVU0RDAAAAADuZETgO/piLoKiQDrHP5E82b32+lGvtB3JA9/Yk3xXFf/////////8AAAAAAAAAAA==";
// let xdr = base_to_xdr(&hex::decode(signature_base).unwrap());
// assert_eq!(target_xdr, xdr);
// }
}
Loading
Loading