Skip to content

Commit

Permalink
Fix decodeAccount in SDK (#14)
Browse files Browse the repository at this point in the history
  • Loading branch information
dguenther authored Apr 16, 2024
1 parent 2cbbac8 commit 5586d6d
Show file tree
Hide file tree
Showing 6 changed files with 181 additions and 20 deletions.
60 changes: 60 additions & 0 deletions Cargo.lock

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

13 changes: 11 additions & 2 deletions packages/ironfish-native-module/ios/IronfishNativeModule.swift
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ public class IronfishNativeModule: Module {
// The module will be accessible from `requireNativeModule('IronfishNativeModule')` in JavaScript.
Name("IronfishNativeModule")

AsyncFunction("generateKey") { () -> ExpoKey in
Function("generateKey") { () -> ExpoKey in
let k = generateKey()

return ExpoKey(
Expand All @@ -43,7 +43,12 @@ public class IronfishNativeModule: Module {
)
}

AsyncFunction("generateKeyFromPrivateKey") { (privateKey: String) throws -> ExpoKey in
Function("wordsToSpendingKey") { (words: String, languageCode: Int32) throws -> String in
let k = try wordsToSpendingKey(words: words, languageCode: languageCode)
return k
}

Function("generateKeyFromPrivateKey") { (privateKey: String) throws -> ExpoKey in
let k = try generateKeyFromPrivateKey(privateKey: privateKey)

return ExpoKey(
Expand All @@ -55,5 +60,9 @@ public class IronfishNativeModule: Module {
proofAuthorizingKey: Field(wrappedValue: k.proofAuthorizingKey)
)
}

Function("isValidPublicAddress") { (hexAddress: String) -> Bool in
return isValidPublicAddress(hexAddress: hexAddress)
}
}
}
5 changes: 4 additions & 1 deletion packages/ironfish-native-module/rust_lib/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,11 @@ edition = "2021"

[dependencies]
ironfish = { path = "../ironfish/ironfish-rust" }
num = "0.4.1"
num-derive = "0.4.2"
num-traits = "0.2.18"
thiserror = "1.0"
uniffi = "0.26.1"

[lib]
crate-type = ["staticlib", "cdylib"]
crate-type = ["staticlib", "cdylib"]
51 changes: 50 additions & 1 deletion packages/ironfish-native-module/rust_lib/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,9 @@
use ironfish::{serializing::bytes_to_hex, SaplingKey};
extern crate num;
#[macro_use]
extern crate num_derive;

use crate::num::FromPrimitive;
use ironfish::{keys::Language, serializing::bytes_to_hex, PublicAddress, SaplingKey};

uniffi::setup_scaffolding!();

Expand All @@ -8,6 +13,33 @@ pub enum EnumError {
Error { msg: String },
}

#[derive(FromPrimitive)]
pub enum LanguageCode {
English,
ChineseSimplified,
ChineseTraditional,
French,
Italian,
Japanese,
Korean,
Spanish,
}

impl From<LanguageCode> for Language {
fn from(item: LanguageCode) -> Self {
match item {
LanguageCode::English => Language::English,
LanguageCode::ChineseSimplified => Language::ChineseSimplified,
LanguageCode::ChineseTraditional => Language::ChineseTraditional,
LanguageCode::French => Language::French,
LanguageCode::Italian => Language::Italian,
LanguageCode::Japanese => Language::Japanese,
LanguageCode::Korean => Language::Korean,
LanguageCode::Spanish => Language::Spanish,
}
}
}

#[derive(uniffi::Record)]
pub struct Key {
pub spending_key: String,
Expand All @@ -34,6 +66,18 @@ fn generate_key() -> Key {
}
}

#[uniffi::export]
pub fn words_to_spending_key(
words: String,
language_code: i32,
) -> Result<String, EnumError> {
let language_code_enum = LanguageCode::from_i32(language_code).ok_or_else(|| EnumError::Error { msg: "Invalid language code".to_string() })?;
let language = Language::from(language_code_enum);

let key = SaplingKey::from_words(words, language).map_err(|e| EnumError::Error { msg: e.to_string() })?;
Ok(key.hex_spending_key())
}

#[uniffi::export]
fn generate_key_from_private_key(private_key: String) -> Result<Key, EnumError> {
let sapling_key =
Expand All @@ -50,3 +94,8 @@ fn generate_key_from_private_key(private_key: String) -> Result<Key, EnumError>
),
})
}

#[uniffi::export]
pub fn is_valid_public_address(hex_address: String) -> bool {
PublicAddress::from_hex(&hex_address).is_ok()
}
21 changes: 15 additions & 6 deletions packages/ironfish-native-module/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,21 @@ export interface Key {
proofAuthorizingKey: string;
}

export async function generateKey(): Promise<Key> {
return await IronfishNativeModule.generateKey();
export function generateKey(): Key {
return IronfishNativeModule.generateKey();
}

export async function generateKeyFromPrivateKey(
privateKey: string,
): Promise<Key> {
return await IronfishNativeModule.generateKeyFromPrivateKey(privateKey);
export function wordsToSpendingKey(
words: string,
languageCode: number,
): string {
return IronfishNativeModule.wordsToSpendingKey(words, languageCode);
}

export function generateKeyFromPrivateKey(privateKey: string): Key {
return IronfishNativeModule.generateKeyFromPrivateKey(privateKey);
}

export function isValidPublicAddress(hexAddress: string): boolean {
return IronfishNativeModule.isValidPublicAddress(hexAddress);
}
51 changes: 41 additions & 10 deletions packages/mobile-app/shims/ironfish-rust-nodejs.js
Original file line number Diff line number Diff line change
@@ -1,16 +1,8 @@
/* eslint-env node */

export const ENCRYPTED_NOTE_PLAINTEXT_LENGTH = 136 + 16;
import * as IronfishNativeModule from "ironfish-native-module";

export const NOTE_ENCRYPTION_KEY_LENGTH = 80;

export const PUBLIC_ADDRESS_LENGTH = 32;
export const ASSET_ID_LENGTH = 32;
export const RANDOMNESS_LENGTH = 32;
export const MEMO_LENGTH = 32;
export const DECRYPTED_NOTE_LENGTH = 168;

export class Asset {
class Asset {
// https://github.com/iron-fish/ironfish/blob/8ee25c612383d4bd6e1e46ff709ed42604abc5f3/ironfish/src/utils/asset.ts#L10
static nativeId() {
return Buffer.from([
Expand All @@ -19,3 +11,42 @@ export class Asset {
]);
}
}

const mockIronfishRustNodejs = {
"$$typeof": undefined,
KEY_LENGTH: 32,
ASSET_NAME_LENGTH: 32,
ASSET_METADATA_LENGTH: 96,
ENCRYPTED_NOTE_PLAINTEXT_LENGTH: 136 + 16,
NOTE_ENCRYPTION_KEY_LENGTH: 80,
PUBLIC_ADDRESS_LENGTH: 32,
ASSET_ID_LENGTH: 32,
RANDOMNESS_LENGTH: 32,
MEMO_LENGTH: 32,
Asset: new Proxy(Asset, {
get: (obj, property) => {
if (obj.hasOwnProperty(property)) {
return obj[property];
}
const message = `ERROR: Please implement ${property} in shims/ironfish-rust-nodejs/Asset`
console.error(message);
throw new Error(message);
}
}),
wordsToSpendingKey: IronfishNativeModule.wordsToSpendingKey,
generateKeyFromPrivateKey: IronfishNativeModule.generateKeyFromPrivateKey,
isValidPublicAddress: IronfishNativeModule.isValidPublicAddress,
}

const proxy = new Proxy(mockIronfishRustNodejs, {
get: (obj, property) => {
if (obj.hasOwnProperty(property)) {
return obj[property];
}
const message = `ERROR: Please implement ${property} in shims/ironfish-rust-nodejs`
console.error(message);
throw new Error(message);
}
});

module.exports = proxy;

0 comments on commit 5586d6d

Please sign in to comment.