Skip to content

Commit

Permalink
fix: abi methods
Browse files Browse the repository at this point in the history
  • Loading branch information
Alex-A4 committed Nov 17, 2023
1 parent d0f2d6d commit 5734b8e
Show file tree
Hide file tree
Showing 9 changed files with 130 additions and 76 deletions.
5 changes: 3 additions & 2 deletions packages/flutter_nekoton_bridge/ios/Classes/frb.h
Original file line number Diff line number Diff line change
Expand Up @@ -292,8 +292,9 @@ intptr_t init_frb_dart_api_dl(void *obj);

void wire_verify_signature(int64_t port_,
struct wire_uint_8_list *public_key,
struct wire_uint_8_list *data_hash,
struct wire_uint_8_list *signature);
struct wire_uint_8_list *data,
struct wire_uint_8_list *signature,
int32_t *signature_id);

void wire_nt_generate_key(int64_t port_, struct wire_MnemonicType *account_type);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,14 @@ export 'password_cache/password_cache_lib.dart';
/// Check signature by publicKey and data hash
Future<bool> verifySignature({
required PublicKey publicKey,
required String dataHash,
required String data,
required String signature,
required int? signatureId,
}) {
return createLib().verifySignature(
publicKey: publicKey.publicKey,
dataHash: dataHash,
data: data,
signature: signature,
signatureId: signatureId,
);
}
4 changes: 2 additions & 2 deletions packages/flutter_nekoton_bridge/lib/nekoton/helpers/abi.dart
Original file line number Diff line number Diff line change
Expand Up @@ -206,7 +206,7 @@ Future<String> getBocHash(String boc) {
Future<(String, String)> packIntoCell({
required List<AbiParam> params,
required TokensObject tokens,
String? abiVersion,
required String? abiVersion,
}) async {
final data = await createLib().packIntoCell(
params: jsonEncode(params),
Expand All @@ -222,7 +222,7 @@ Future<TokensObject> unpackFromCell({
required List<AbiParam> params,
required String boc,
required bool allowPartial,
String? abiVersion,
required String? abiVersion,
}) async {
return jsonDecode(await createLib().unpackFromCell(
params: jsonEncode(params),
Expand Down
19 changes: 11 additions & 8 deletions packages/nekoton_bridge/lib/src/bridge_generated.dart
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,12 @@ abstract class NekotonBridge {
///----------------------------
/// CONTENT OF src/nekoton_wrapper/crypto/crypto_api.rs
///----------------------------
/// Check signature by publicKey and data hash
/// Check signature by publicKey and data
Future<bool> verifySignature(
{required String publicKey,
required String dataHash,
required String data,
required String signature,
int? signatureId,
dynamic hint});

FlutterRustBridgeTaskConstMeta get kVerifySignatureConstMeta;
Expand Down Expand Up @@ -82,7 +83,7 @@ abstract class NekotonBridge {
FlutterRustBridgeTaskConstMeta get kRunLocalConstMeta;

/// Get address of tvc and contract_abi.
/// Returns list of [address, state_init, hash] or throws error
/// Returns list of [address, boc of state_init, hash] or throws error
Future<List<String>> getExpectedAddress(
{required String tvc,
required String contractAbi,
Expand Down Expand Up @@ -3685,26 +3686,28 @@ class NekotonBridgeImpl implements NekotonBridge {
NekotonBridgeImpl.raw(this._platform);
Future<bool> verifySignature(
{required String publicKey,
required String dataHash,
required String data,
required String signature,
int? signatureId,
dynamic hint}) {
var arg0 = _platform.api2wire_String(publicKey);
var arg1 = _platform.api2wire_String(dataHash);
var arg1 = _platform.api2wire_String(data);
var arg2 = _platform.api2wire_String(signature);
var arg3 = _platform.api2wire_opt_box_autoadd_i32(signatureId);
return _platform.executeNormal(FlutterRustBridgeTask(
callFfi: (port_) =>
_platform.inner.wire_verify_signature(port_, arg0, arg1, arg2),
_platform.inner.wire_verify_signature(port_, arg0, arg1, arg2, arg3),
parseSuccessData: _wire2api_bool,
constMeta: kVerifySignatureConstMeta,
argValues: [publicKey, dataHash, signature],
argValues: [publicKey, data, signature, signatureId],
hint: hint,
));
}

FlutterRustBridgeTaskConstMeta get kVerifySignatureConstMeta =>
const FlutterRustBridgeTaskConstMeta(
debugName: "verify_signature",
argNames: ["publicKey", "dataHash", "signature"],
argNames: ["publicKey", "data", "signature", "signatureId"],
);

Future<GeneratedKeyG> ntGenerateKey(
Expand Down
17 changes: 12 additions & 5 deletions packages/nekoton_bridge/lib/src/bridge_generated.io.dart
Original file line number Diff line number Diff line change
Expand Up @@ -984,14 +984,16 @@ class NekotonBridgeWire implements FlutterRustBridgeWireBase {
void wire_verify_signature(
int port_,
ffi.Pointer<wire_uint_8_list> public_key,
ffi.Pointer<wire_uint_8_list> data_hash,
ffi.Pointer<wire_uint_8_list> data,
ffi.Pointer<wire_uint_8_list> signature,
ffi.Pointer<ffi.Int32> signature_id,
) {
return _wire_verify_signature(
port_,
public_key,
data_hash,
data,
signature,
signature_id,
);
}

Expand All @@ -1001,10 +1003,15 @@ class NekotonBridgeWire implements FlutterRustBridgeWireBase {
ffi.Int64,
ffi.Pointer<wire_uint_8_list>,
ffi.Pointer<wire_uint_8_list>,
ffi.Pointer<wire_uint_8_list>)>>('wire_verify_signature');
ffi.Pointer<wire_uint_8_list>,
ffi.Pointer<ffi.Int32>)>>('wire_verify_signature');
late final _wire_verify_signature = _wire_verify_signaturePtr.asFunction<
void Function(int, ffi.Pointer<wire_uint_8_list>,
ffi.Pointer<wire_uint_8_list>, ffi.Pointer<wire_uint_8_list>)>();
void Function(
int,
ffi.Pointer<wire_uint_8_list>,
ffi.Pointer<wire_uint_8_list>,
ffi.Pointer<wire_uint_8_list>,
ffi.Pointer<ffi.Int32>)>();

void wire_nt_generate_key(
int port_,
Expand Down
7 changes: 4 additions & 3 deletions packages/nekoton_bridge/lib/src/bridge_generated.web.dart
Original file line number Diff line number Diff line change
Expand Up @@ -533,7 +533,7 @@ class NekotonBridgeWasmModule implements WasmModule {
external Object /* Promise */ call([String? moduleName]);
external NekotonBridgeWasmModule bind(dynamic thisArg, String moduleName);
external dynamic /* void */ wire_verify_signature(NativePortType port_,
String public_key, String data_hash, String signature);
String public_key, String data, String signature, int? signature_id);

external dynamic /* void */ wire_nt_generate_key(
NativePortType port_, List<dynamic> account_type);
Expand Down Expand Up @@ -1386,8 +1386,9 @@ class NekotonBridgeWire
: super(WasmModule.cast<NekotonBridgeWasmModule>(module));

void wire_verify_signature(NativePortType port_, String public_key,
String data_hash, String signature) =>
wasmModule.wire_verify_signature(port_, public_key, data_hash, signature);
String data, String signature, int? signature_id) =>
wasmModule.wire_verify_signature(
port_, public_key, data, signature, signature_id);

void wire_nt_generate_key(NativePortType port_, List<dynamic> account_type) =>
wasmModule.wire_nt_generate_key(port_, account_type);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,47 +1,30 @@
#![allow(unused_variables, dead_code)]

pub use crate::nekoton_wrapper::crypto::models::UnsignedMessageBoxTrait;
use crate::nekoton_wrapper::{parse_public_key, HandleError};
use crate::nekoton_wrapper::{
helpers::{parse_hex_or_base64_bytes, parse_signature},
parse_public_key, HandleError,
};
use ed25519_dalek::Verifier;
pub use flutter_rust_bridge::RustOpaque;
pub use nekoton::crypto::UnsignedMessage;
use std::convert::TryFrom;
use std::sync::Arc;

/// Check signature by publicKey and data hash
/// Check signature by publicKey and data
pub fn verify_signature(
public_key: String,
data_hash: String,
data: String,
signature: String,
signature_id: Option<i32>,
) -> anyhow::Result<bool> {
let public_key = parse_public_key(public_key).handle_error()?;
let public_key = parse_public_key(public_key)?;

let data_hash = match hex::decode(&data_hash) {
Ok(data_hash) => data_hash,
Err(e) => match base64::decode(&data_hash) {
Ok(data_hash) => data_hash,
Err(e) => return Err(anyhow::Error::msg(e)),
},
};
let data = parse_hex_or_base64_bytes(data).handle_error()?;
let signature = parse_signature(signature)?;

if data_hash.len() != 32 {
return Err(anyhow::Error::msg("Invalid data hash. Expected 32 bytes"));
}

let signature = match base64::decode(&signature) {
Ok(signature) => signature,
Err(e) => match hex::decode(&signature) {
Ok(signature) => signature,
Err(_) => return Err(anyhow::Error::msg(e)),
},
};

let signature = match ed25519_dalek::Signature::try_from(signature.as_slice()) {
Ok(signature) => signature,
Err(_) => return Err(anyhow::Error::msg("Invalid signature. Expected 64 bytes")),
};
let data = nekoton::crypto::extend_with_signature_id(&data, signature_id);

Ok(public_key.verify(&data_hash, &signature).is_ok())
Ok(public_key.verify(data.as_ref(), &signature).is_ok())
}

/// This struct creates only in rust side and describes UnsignedMessage
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,9 @@ use crate::nekoton_wrapper::helpers::models::{
DecodedEvent, DecodedInput, DecodedOutput, DecodedTransaction, ExecutionOutput,
};
use crate::nekoton_wrapper::helpers::{
make_boc, make_full_contract_state, parse_account_stuff, parse_cell, parse_contract_abi,
parse_method_name, parse_params_list, parse_slice, serialize_into_boc,
serialize_into_boc_with_hash, serialize_state_init_data_key,parse_optional_abi_version,
make_boc, make_boc_with_hash, make_full_contract_state, parse_account_stuff, parse_cell,
parse_contract_abi, parse_method_name, parse_optional_abi_version, parse_params_list,
parse_slice, serialize_into_boc, serialize_into_boc_with_hash, serialize_state_init_data_key,
};
use crate::nekoton_wrapper::{parse_address, parse_public_key, HandleError};
use nekoton::core::models::{Expiration, ExpireAt, Transaction};
Expand All @@ -27,7 +27,6 @@ use ton_block::{Deserializable, GetRepresentationHash, Serializable};
use ton_executor::TransactionExecutor;
use ton_types::SliceData;


/// Check if public key is correct.
/// If no - throws error, if ok - return true
pub fn check_public_key(public_key: String) -> anyhow::Result<bool> {
Expand Down Expand Up @@ -77,7 +76,7 @@ pub fn run_local(
}

/// Get address of tvc and contract_abi.
/// Returns list of [address, state_init, hash] or throws error
/// Returns list of [address, boc of state_init, hash] or throws error
pub fn get_expected_address(
tvc: String,
contract_abi: String,
Expand Down Expand Up @@ -121,9 +120,11 @@ pub fn get_expected_address(
let cell = state_init.serialize().handle_error()?;
let repr_hash = cell.repr_hash().to_hex_string();

let mut result = vec![format!("{workchain_id}:{repr_hash}")];
result.extend(serialize_into_boc_with_hash(&cell)?);
Ok(result)
Ok(vec![
format!("{workchain_id}:{repr_hash}"),
make_boc(&cell)?,
repr_hash,
])
}

/// Returns base64-encoded body that was encoded or throws error
Expand Down Expand Up @@ -465,22 +466,26 @@ pub fn get_boc_hash(boc: String) -> anyhow::Result<String> {

/// Return base64 encoded bytes of tokens or throws error
/// returns [tvc, hash]
pub fn pack_into_cell(params: String, tokens: String, version: Option<String>,) -> anyhow::Result<Vec<String>> {
pub fn pack_into_cell(
params: String,
tokens: String,
version: Option<String>,
) -> anyhow::Result<Vec<String>> {
let params = parse_params_list(params)?;
let tokens = serde_json::from_str::<serde_json::Value>(&tokens).handle_error()?;
let tokens = nekoton_abi::parse_abi_tokens(&params, tokens).handle_error()?;
let version = parse_optional_abi_version(version)?;

let cell = nekoton_abi::pack_into_cell(&tokens, version).handle_error()?;
serialize_into_boc_with_hash(&cell)
make_boc_with_hash(cell)
}

/// Parse list of params and return json-encoded Tokens or throws error
pub fn unpack_from_cell(
params: String,
boc: String,
allow_partial: bool,
version: Option<String>,
version: Option<String>,
) -> anyhow::Result<String> {
let params = parse_params_list(params)?;
let body = base64::decode(boc).handle_error()?;
Expand Down Expand Up @@ -543,10 +548,9 @@ pub fn extract_public_key(boc: String) -> anyhow::Result<String> {
/// Convert code to base64 tvc string and return it or throw error
/// returns [tvc, hash]
pub fn code_to_tvc(code: String) -> anyhow::Result<Vec<String>> {
let cell = base64::decode(code).handle_error()?;

let cell = ton_types::deserialize_tree_of_cells(&mut cell.as_slice())?;
serialize_into_boc_with_hash(&cell)
let cell = parse_cell(code).handle_error()?;
let state_init = nekoton_abi::code_to_tvc(cell).handle_error()?;
serialize_into_boc_with_hash(&state_init)
}

/// Merge code and data to tvc base64 string and return it or throw error
Expand All @@ -558,8 +562,7 @@ pub fn merge_tvc(code: String, data: String) -> anyhow::Result<Vec<String>> {
..Default::default()
};

let cell = state_init.serialize().handle_error()?;
serialize_into_boc_with_hash(&cell)
serialize_into_boc_with_hash(&state_init)
}

/// Split base64 tvc string into data and code.
Expand Down Expand Up @@ -592,7 +595,7 @@ pub fn split_tvc(tvc: String) -> anyhow::Result<Vec<Option<String>>> {
/// returns [tvc, hash]
pub fn set_code_salt(code: String, salt: String) -> anyhow::Result<Vec<String>> {
let cell = nekoton_abi::set_code_salt(parse_cell(code)?, parse_cell(salt)?)?;
serialize_into_boc_with_hash(&cell)
make_boc_with_hash(cell)
}

/// Get salt from code if possible and return base64-encoded salt or throw error
Expand Down
Loading

0 comments on commit 5734b8e

Please sign in to comment.