From a71d3deea83484003e438521101449d1cbdcfb8a Mon Sep 17 00:00:00 2001 From: Rakshith G Date: Tue, 23 Jun 2020 12:10:48 +0530 Subject: [PATCH 01/12] TezosNodeReader added --- example/lib/main.dart | 146 +++++++++++---------- example/pubspec.yaml | 5 + lib/helper/nodeWriterHelper.dart | 19 +++ lib/tezsterNodeReader.dart | 209 +++++++++++++++++++++++++++++++ lib/tezsterNodeWriter.dart | 74 +++++++++++ lib/tezster_dart.dart | 178 +------------------------- 6 files changed, 394 insertions(+), 237 deletions(-) create mode 100644 lib/helper/nodeWriterHelper.dart create mode 100644 lib/tezsterNodeReader.dart create mode 100644 lib/tezsterNodeWriter.dart diff --git a/example/lib/main.dart b/example/lib/main.dart index d25f1e7..9885f21 100644 --- a/example/lib/main.dart +++ b/example/lib/main.dart @@ -70,101 +70,120 @@ class _MyAppState extends State { request() async { String testNetServer = "https://testnet.tezster.tech"; - dynamic response = await TezsterDart.performGetRequest( + //Working functions + dynamic response = await TezsterNodeReader.performGetRequest( server: testNetServer, command: "chains/main/blocks", ); print("Response ===> $response"); - dynamic getBlock = await TezsterDart.getBlock( + dynamic getBlock = await TezsterNodeReader.getBlock( server: testNetServer, - hash: "", - chainid: "", + hash: "head", + chainid: "NetXjD3HPJJjmcd", ); print("GET-Block ===> $getBlock"); - dynamic blockhead = await TezsterDart.getBlockHead( + dynamic blockhead = await TezsterNodeReader.getBlockHead( server: testNetServer, ); print("Block-Head ===> $blockhead"); - dynamic getAccForBlock = await TezsterDart.getAccountForBlock( + dynamic getCounterForAccount = await TezsterNodeReader.getCounterForAccount( server: testNetServer, - accountHash: "", - blockHash: "", - chainid: "", + accountHash: "tz1ZfFASQvmmz47ru5nn9GhX5oswCRVX5z1r", + chainid: "NetXjD3HPJJjmcd", ); - print("GET-Acc-ForBlock ===> $getAccForBlock"); + print("GET-Counter-ForAccount ===> $getCounterForAccount"); - // dynamic getCounterForAccount = await TezsterDart.getCounterForAccount( - // server: testNetServer, - // accountHash: "", - // chainid: "", - // ); - // print("GET-Counter-ForAccount ===> $getCounterForAccount"); - - // dynamic getSpendableBalanceForAccount = - // await TezsterDart.getSpendableBalanceForAccount( - // server: testNetServer, - // accountHash: "", - // chainid: "", - // ); - // print( - // "GET-SpendableBalance-ForAccount ===> $getSpendableBalanceForAccount"); - - dynamic getAccountManagerForBlock = - await TezsterDart.getAccountManagerForBlock( + dynamic getMempoolOperation = await TezsterNodeReader.getMempoolOperation( server: testNetServer, - chainid: "", - accountHash: "", - block: "", + chainid: "NetXjD3HPJJjmcd", + operationGroupId: "opAPztkmYpEG754JGjkKi4snUTaa879fvgWfGFeDrdmTAbaoLNp", ); - print("GET-Account-Manager-ForBlock ===> $getAccountManagerForBlock"); - - // dynamic isImplicitAndEmpty = await TezsterDart.isImplicitAndEmpty( - // server: testNetServer, - // accountHash: "", - // ); - // print("Is-ImplicitAndEmpty ===> $isImplicitAndEmpty"); + print("GET-MempoolOperation ===> $getMempoolOperation"); - dynamic isManagerKeyRevealedForAccount = - await TezsterDart.isManagerKeyRevealedForAccount( + dynamic getSpendableBalanceForAccount = + await TezsterNodeReader.getSpendableBalanceForAccount( server: testNetServer, - accountHash: "", + accountHash: "tz1ZfFASQvmmz47ru5nn9GhX5oswCRVX5z1r", + chainid: "NetXjD3HPJJjmcd", ); print( - "Is-ManagerKey-Revealed-ForAccount ===> $isManagerKeyRevealedForAccount"); + "GET-SpendableBalance-ForAccount ===> $getSpendableBalanceForAccount"); - dynamic getContractStorage = await TezsterDart.getContractStorage( + dynamic getBalance = await TezsterNodeReader.getBalance( + accountHash: "tz1ZfFASQvmmz47ru5nn9GhX5oswCRVX5z1r", server: testNetServer, - accountHash: "", - block: "", - chainid: "", ); - print("GET-Contract-Storage ===> $getContractStorage"); + print("Get-Balance ===> $getBalance"); - dynamic getValueForBigMapKey = await TezsterDart.getValueForBigMapKey( + dynamic getMempoolOperationsForAccount = + await TezsterNodeReader.getMempoolOperationsForAccount( server: testNetServer, - key: "", - block: "", - chainid: "", - index: 1, + chainid: "NetXjD3HPJJjmcd", + accountHash: "tz1Y8zdtVe2wWe7QdNTnAdwBceqYBCdA3Jj8", ); - print("GET-Value-ForBigMapKey ===> $getValueForBigMapKey"); + print( + "GET-MempoolOperations-ForAccount ===> $getMempoolOperationsForAccount"); - dynamic getMempoolOperation = await TezsterDart.getMempoolOperation( + dynamic isManagerKeyRevealedForAccount = + await TezsterNodeReader.isManagerKeyRevealedForAccount( server: testNetServer, - chainid: "", - operationGroupId: "", + accountHash: "tz1ZfFASQvmmz47ru5nn9GhX5oswCRVX5z1r", ); - print("GET-MempoolOperation ===> $getMempoolOperation"); + print( + "Is-ManagerKey-Revealed-ForAccount ===> $isManagerKeyRevealedForAccount"); - dynamic getMempoolOperationsForAccount = - await TezsterDart.getMempoolOperationsForAccount( - server: testNetServer, - chainid: "", - ); - print("GET-MempoolOperations-ForAccount ===> $getMempoolOperationsForAccount"); + //Not WORKING + // dynamic getAccForBlock = await TezsterNodeReader.getAccountForBlock( + // server: testNetServer, + // accountHash: "tz1ZfFASQvmmz47ru5nn9GhX5oswCRVX5z1r", + // blockHash: "", + // chainid: "NetXjD3HPJJjmcd", + // ); + // print("GET-Acc-ForBlock ===> $getAccForBlock"); + + // dynamic getAccountManagerForBlock = + // await TezsterNodeReader.getAccountManagerForBlock( + // server: testNetServer, + // chainid: "NetXjD3HPJJjmcd", + // accountHash: "tz1ZfFASQvmmz47ru5nn9GhX5oswCRVX5z1r", + // block: "", + // ); + // print("GET-Account-Manager-ForBlock ===> $getAccountManagerForBlock"); + + // dynamic isImplicitAndEmpty = await TezsterNodeReader.isImplicitAndEmpty( + // server: testNetServer, + // accountHash: "tz1ZfFASQvmmz47ru5nn9GhX5oswCRVX5z1r", + // ); + // print("Is-ImplicitAndEmpty ===> $isImplicitAndEmpty"); + + // dynamic getContractStorage = await TezsterNodeReader.getContractStorage( + // server: testNetServer, + // accountHash: "tz1ZfFASQvmmz47ru5nn9GhX5oswCRVX5z1r", + // block: "", + // chainid: "NetXjD3HPJJjmcd", + // ); + // print("GET-Contract-Storage ===> $getContractStorage"); + + // dynamic getValueForBigMapKey = await TezsterNodeReader.getValueForBigMapKey( + // server: testNetServer, + // key: "", + // block: "", + // chainid: "NetXjD3HPJJjmcd", + // index: 1, + // ); + // print("GET-Value-ForBigMapKey ===> $getValueForBigMapKey"); + } + + nodeWriter() { + TezsterNodeWriter.signOperationGroup( + derivationPath: "", + forgedOperation: + "713cb068fe3ac078351727eb5c34279e22b75b0cf4dc0a8d3d599e27031db136040cb9f9da085607c05cac1ca4c62a3f3cfb8146aa9b7f631e52f877a1d363474404da8130b0b940ee", + privateKey: + "edskRdVS5H9YCRAG8yqZkX2nUTbGcaDqjYgopkJwRuPUnYzCn3t9ZGksncTLYe33bFjq29pRhpvjQizCCzmugMGhJiXezixvdC"); } @override @@ -172,6 +191,7 @@ class _MyAppState extends State { super.initState(); // example(); request(); + // nodeWriter(); } @override diff --git a/example/pubspec.yaml b/example/pubspec.yaml index ec9c92a..329262e 100644 --- a/example/pubspec.yaml +++ b/example/pubspec.yaml @@ -24,6 +24,11 @@ dependencies: flutter: sdk: flutter + # tezster_dart: + # git: + # url: git@github.com:Rakshak1344/Tezster_dart.git + # ref: master + tezster_dart: path: ../ diff --git a/lib/helper/nodeWriterHelper.dart b/lib/helper/nodeWriterHelper.dart new file mode 100644 index 0000000..0b91ba1 --- /dev/null +++ b/lib/helper/nodeWriterHelper.dart @@ -0,0 +1,19 @@ +import 'dart:typed_data'; + +import 'package:convert/convert.dart'; +import 'package:bs58check/bs58check.dart' as bs58check; + +class NodeWriterHelper { + static String _readSignatureWithHint(Uint8List payload, String hint) { + String encodedPayoad = hex.encode(payload); + String concatEncodedPayload = '09f5cd8612' + encodedPayoad; + String encodedPayoadToHexString = + hex.encode(concatEncodedPayload.codeUnits); + Uint8List finlaListForBS58CHECK = hex.decode(encodedPayoadToHexString); + if (hint == 'edsig') { + return bs58check.encode(finlaListForBS58CHECK); + } else { + throw {"messgae": "Unrecognized key hint, '$hint'"}; + } + } +} diff --git a/lib/tezsterNodeReader.dart b/lib/tezsterNodeReader.dart new file mode 100644 index 0000000..a7d9870 --- /dev/null +++ b/lib/tezsterNodeReader.dart @@ -0,0 +1,209 @@ +part of tezster_dart; + +class TezsterNodeReader { + static dynamic performGetRequest({ + String server, + String command = "", + }) async { + assert(server != null); + String url = "$server/$command"; + http.Response response = await http.get(url); + if (response.statusCode != 200) { + return "Invalid URL"; + } + dynamic data = jsonDecode(response.body); + return data; + } + + static dynamic getBlock({ + String server, + String hash = "head", + String chainid = "main", + }) async { + assert(server != null); + dynamic response = await performGetRequest( + server: server, + command: "chains/$chainid/blocks/$hash", + ); + return response; + } + + static dynamic getBlockHead({ + String server, + }) async { + assert(server != null); + dynamic response = await getBlock(server: server); + return response; + } + + static dynamic getAccountForBlock({ + String server, + String blockHash, + String accountHash, + String chainid = "main", + }) { + dynamic response = performGetRequest( + server: server, + command: + "chains/$chainid/blocks/$blockHash/context/contracts/$accountHash", + ); + return response; + } + + static dynamic getCounterForAccount({ + String server, + String accountHash, + String chainid = "main", + }) async { + dynamic counter = await performGetRequest( + server: server, + command: + "chains/$chainid/blocks/head/context/contracts/$accountHash/counter", + ); + return int.parse(counter, radix: 10); + } + + static dynamic getSpendableBalanceForAccount({ + String server, + String accountHash, + String chainid = "main", + }) async { + dynamic account = await performGetRequest( + server: server, + command: "chains/$chainid/blocks/head/context/contracts/$accountHash"); + return int.parse(account["balance"], radix: 10); + } + + static dynamic getAccountManagerForBlock({ + String server, + String block, + String accountHash, + String chainid = "main", + }) async { + try { + dynamic result = await performGetRequest( + server: server, + command: + "chains/$chainid/blocks/$block/context/contracts/$accountHash/manager_key", + ); + if (result.toString() == null) { + return ""; + } + return result.toString(); + } catch (e) { + throw (e); + } + } + + static dynamic isImplicitAndEmpty({ + String server, + String accountHash, + }) async { + dynamic account = await getAccountForBlock( + server: server, + blockHash: "head", + accountHash: accountHash, + ); + bool isImplicit = accountHash.toLowerCase().startsWith("tz"); + bool isEmpty = account.balance == 0; + + if (isImplicit && isEmpty) + return true; + else + return false; + } + + static dynamic isManagerKeyRevealedForAccount({ + String server, + String accountHash, + }) async { + dynamic managerKey = await getAccountManagerForBlock( + server: server, + block: "head", + accountHash: accountHash, + ); + return managerKey.toString().length > 0 ? true : false; + } + + static dynamic getContractStorage({ + String server, + String accountHash, + String chainid = "main", + String block = "head", + }) async { + dynamic response = performGetRequest( + server: server, + command: + "chains/$chainid/blocks/$block/context/contracts/$accountHash/storage", + ); + return response; + } + + static dynamic getValueForBigMapKey({ + String server, + num index, + String key, + String block = "main", + String chainid = "head", + }) async { + dynamic response = performGetRequest( + server: server, + command: "chains/$chainid/blocks/$block/context/big_maps/$index/$key", + ); + return response; + } + + static dynamic getMempoolOperation({ + String server, + String operationGroupId, + String chainid = "main", + }) async { + dynamic mempoolContent = await performGetRequest( + server: server, + command: "chains/$chainid/mempool/pending_operations", + ); + List applied = mempoolContent["applied"]; + print("applied ===> $applied"); + dynamic response; + applied.forEach((data) { + if (data["hash"] == operationGroupId) { + response = data; + } else { + response = "Hash not found"; + } + }); + return response; + } + + static dynamic getMempoolOperationsForAccount({ + String server, + String accountHash, + String chainid = "main", + }) async { + dynamic mempoolContent = await performGetRequest( + server: server, + command: "chains/$chainid/mempool/pending_operations", + ); + List data = []; + dynamic applied = mempoolContent["applied"]; + applied.forEach((g) { + if (g["contents"][0]["source"] == accountHash || + g["contents"][0]["destination"] == accountHash) { + //print("G ===> ${g["contents"]}"); + data.insertAll(0,g["contents"]); + } + }); + return data; + } + + static dynamic getBalance({ + String server, + String accountHash, + }) async { + dynamic balance = performGetRequest( + server: server, + command: "chains/main/blocks/head/context/contracts/$accountHash/balance", + ); + return balance; + } +} diff --git a/lib/tezsterNodeWriter.dart b/lib/tezsterNodeWriter.dart new file mode 100644 index 0000000..fd4bfa6 --- /dev/null +++ b/lib/tezsterNodeWriter.dart @@ -0,0 +1,74 @@ +part of tezster_dart; + +class TezsterNodeWriter { + static performPostRequest({ + String server, + String command, + Object payload, + }) async { + assert(server != null); + assert(command != null); + String url = '$server/$command'; + try { + String payloadString = jsonEncode(payload); + http.Response data = await http.post( + url, + body: payloadString, + headers: { + 'content-type': 'application/json', + }, + ); + return data; + } catch (e) { + return {"message": "Something went wrong"}; + } + } + + static Uint8List _simpleHash(Uint8List payload, int digestSize) { + return Blake2bHash.hashWithDigestSize(digestSize, payload); + } + + static Uint8List _writeKeyWithHint(String key, String hint) { + if (hint == "edsk" || hint == "edpk") { + return bs58check.decode(key).sublist(0, 4); + } else { + throw {"message": "Unrecognized key hint, '$hint'"}; + } + } + + static String _readSignatureWithHint(Uint8List payload, String hint) { + String encodedPayoad = hex.encode(payload); + String concatEncodedPayload = '09f5cd8612' + encodedPayoad; + String encodedPayoadToHexString = + hex.encode(concatEncodedPayload.codeUnits); + Uint8List finlaListForBS58CHECK = hex.decode(encodedPayoadToHexString); + if (hint == 'edsig') { + return bs58check.encode(finlaListForBS58CHECK); + } else { + throw {"message": "Unrecognized key hint, '$hint'"}; + } + } + + static signOperationGroup({ + String forgedOperation, + String derivationPath, + String privateKey, + }) { + String watermarkedForgedOperationBytesHex = "03" + forgedOperation; + String stringToHexString = + hex.encode(watermarkedForgedOperationBytesHex.codeUnits); + // print(stringToHexString); + List hexStringToListOfInt = hex.decode(stringToHexString); + // print(hexStringToListOfInt); + Uint8List hashedWatermarkedOpBytes = _simpleHash(hexStringToListOfInt, 256); + print("hashedWatermarkedOpBytes ===> $hashedWatermarkedOpBytes"); + print("hashedWatermarkedOpBytes ===> ${hashedWatermarkedOpBytes.length}"); + Uint8List bs58List = _writeKeyWithHint(privateKey, "edsk"); + print("bs58List ===> $bs58List"); + } + + + + + +} diff --git a/lib/tezster_dart.dart b/lib/tezster_dart.dart index 433ea32..17ddccc 100644 --- a/lib/tezster_dart.dart +++ b/lib/tezster_dart.dart @@ -4,6 +4,7 @@ import 'dart:convert'; import 'dart:typed_data'; import 'package:blake2b/blake2b_hash.dart'; import 'package:crypto/crypto.dart'; +import 'package:flutter/cupertino.dart'; import 'package:password_hash/password_hash.dart'; import 'helper/generateKeys.dart'; import 'package:bip39/bip39.dart' as bip39; @@ -13,6 +14,9 @@ import 'package:flutter_sodium/flutter_sodium.dart'; import 'package:convert/convert.dart'; import 'package:http/http.dart' as http; +part 'tezsterNodeReader.dart'; +part 'tezsterNodeWriter.dart'; + class TezsterDart { static String generateMnemonic({int strength = 256}) { return bip39.generateMnemonic(strength: strength); @@ -116,178 +120,4 @@ class TezsterDart { String pkKeyHash = GenerateKeys.computeKeyHash(pk); return [skKey, pkKey, pkKeyHash]; } - - static dynamic performGetRequest({ - String server, - String command = "", - }) async { - assert(server != null); - String url = "$server/$command"; - http.Response response = await http.get(url); - if (response.statusCode != 200) { - return "Invalid url"; - } - dynamic data = jsonDecode(response.body); - return data; - } - - static dynamic getBlock({ - String server, - String hash = "head", - String chainid = "main", - }) async { - assert(server != null); - dynamic response = await performGetRequest( - server: server, - command: "chains/$chainid/blocks/$hash", - ); - return response; - } - - static dynamic getBlockHead({ - String server, - }) async { - assert(server != null); - dynamic response = await getBlock(server: server); - return response; - } - - static dynamic getAccountForBlock({ - String server, - String blockHash, - String accountHash, - String chainid = "main", - }) async { - dynamic response = await performGetRequest( - server: server, - command: - "chains/$chainid/blocks/$blockHash/context/contracts/$accountHash}", - ); - return response; - } - - static dynamic getCounterForAccount({ - String server, - String accountHash, - String chainid = "main", - }) async { - dynamic counter = await performGetRequest( - server: server, - command: - "chains/$chainid/blocks/head/context/contracts/$accountHash/counter", - ); - return int.parse(counter, radix: 10); - } - - static dynamic getSpendableBalanceForAccount({ - String server, - String accountHash, - String chainid = "main", - }) async { - dynamic account = await performGetRequest( - server: server, - command: "chains/$chainid/blocks/head/context/contracts/$accountHash"); - return int.parse(account.toString(), radix: 10); - } - - static dynamic getAccountManagerForBlock({ - String server, - String block, - String accountHash, - String chainid = "main", - }) async { - try { - dynamic result = await performGetRequest( - server: server, - command: - "chains/$chainid/blocks/$block/context/contracts/$accountHash/manager_key", - ); - if (result.toString() == null) { - return ""; - } - return result.toString(); - } catch (e) { - throw (e); - } - } - - static dynamic isImplicitAndEmpty({ - String server, - String accountHash, - }) async { - dynamic account = await getAccountForBlock( - server: server, - blockHash: "head", - accountHash: accountHash, - ); - bool isImplicit = accountHash.toLowerCase().startsWith("tz"); - bool isEmpty = account.balance == 0; - return (isImplicit && isEmpty) ? true : false; - } - - static dynamic isManagerKeyRevealedForAccount({ - String server, - String accountHash, - }) async { - dynamic managerKey = await getAccountManagerForBlock( - server: server, - block: "head", - accountHash: accountHash, - ); - return managerKey.toString().length > 0 ? true : false; - } - - static dynamic getContractStorage({ - String server, - String accountHash, - String chainid = "main", - String block = "head", - }) async { - dynamic response = performGetRequest( - server: server, - command: - "chains/$chainid/blocks/$block/context/contracts/$accountHash/storage", - ); - return response; - } - - static dynamic getValueForBigMapKey({ - String server, - num index, - String key, - String block = "main", - String chainid = "head", - }) async { - dynamic response = performGetRequest( - server: server, - command: "chains/$chainid/blocks/$block/context/big_maps/$index/$key", - ); - return response; - } - - static dynamic getMempoolOperation({ - String server, - String operationGroupId, - String chainid = "main", - }) async { - dynamic mempoolContent = performGetRequest( - server: server, - command: "chains/$chainid/mempool/pending_operations", - ); - //TODO: mempoolContent - return mempoolContent; - } - - static dynamic getMempoolOperationsForAccount({ - String server, - String accountHash, - String chainid = "main", - }) async { - dynamic mempoolContent = await performGetRequest( - server: server, - command: "chains/$chainid/mempool/pending_operations", - ); - //TODO : Modification to be done. - return mempoolContent; - } } From 8c4ad0e9ac14aa5a4c9eaab4fb8eee78139212c7 Mon Sep 17 00:00:00 2001 From: Rakshak1344 Date: Tue, 14 Jul 2020 21:28:32 +0530 Subject: [PATCH 02/12] invoke operations done --- example/lib/main.dart | 26 +++-- example/pubspec.yaml | 4 +- lib/helper/nodeWriterHelper.dart | 19 ---- lib/helper/tezosMessageUtil.dart | 11 +++ lib/tezsterNodeWriter.dart | 157 +++++++++++++++++++++++++++++-- lib/tezster_dart.dart | 5 + 6 files changed, 184 insertions(+), 38 deletions(-) delete mode 100644 lib/helper/nodeWriterHelper.dart create mode 100644 lib/helper/tezosMessageUtil.dart diff --git a/example/lib/main.dart b/example/lib/main.dart index 9885f21..3639f9b 100644 --- a/example/lib/main.dart +++ b/example/lib/main.dart @@ -17,7 +17,7 @@ class MyApp extends StatefulWidget { } class _MyAppState extends State { - example() async { + tezosWalletUtil() async { //Generate mnemonic String mnemonic = TezsterDart .generateMnemonic(); // strength is optional, by default it's 256 ==> Generates 24 words. @@ -67,7 +67,7 @@ class _MyAppState extends State { //Accessing: private key ===> identityFundraiser[0] | public key ===> identityFundraiser[1] | public Key Hash ===> identityFundraiser[2] all of type string. } - request() async { + tezosNodeWriter() async { String testNetServer = "https://testnet.tezster.tech"; //Working functions @@ -135,7 +135,7 @@ class _MyAppState extends State { print( "Is-ManagerKey-Revealed-ForAccount ===> $isManagerKeyRevealedForAccount"); - //Not WORKING +//Yet to be tested // dynamic getAccForBlock = await TezsterNodeReader.getAccountForBlock( // server: testNetServer, // accountHash: "tz1ZfFASQvmmz47ru5nn9GhX5oswCRVX5z1r", @@ -177,21 +177,29 @@ class _MyAppState extends State { // print("GET-Value-ForBigMapKey ===> $getValueForBigMapKey"); } - nodeWriter() { - TezsterNodeWriter.signOperationGroup( - derivationPath: "", + nodeWriter() async { + List opGroup = await TezsterNodeWriter.signOperationGroup( forgedOperation: "713cb068fe3ac078351727eb5c34279e22b75b0cf4dc0a8d3d599e27031db136040cb9f9da085607c05cac1ca4c62a3f3cfb8146aa9b7f631e52f877a1d363474404da8130b0b940ee", privateKey: "edskRdVS5H9YCRAG8yqZkX2nUTbGcaDqjYgopkJwRuPUnYzCn3t9ZGksncTLYe33bFjq29pRhpvjQizCCzmugMGhJiXezixvdC"); + print("bytes ===> ${opGroup[0]}"); + print("Signature ===> ${opGroup[1]}"); + + TezsterNodeWriter.forgeOperations( + branch: "BKzEzxCwQcXBJNHCxGbnq9H8P3aV7EfFZaot54nShmF3YAgwHDj", + ); + + // TezsterNodeWriter.writeBranch( + // "BKzEzxCwQcXBJNHCxGbnq9H8P3aV7EfFZaot54nShmF3YAgwHDj"); } @override void initState() { super.initState(); - // example(); - request(); - // nodeWriter(); + // tezosWalletUtil(); + // tezosNodeWriter(); + nodeWriter(); } @override diff --git a/example/pubspec.yaml b/example/pubspec.yaml index 329262e..c565310 100644 --- a/example/pubspec.yaml +++ b/example/pubspec.yaml @@ -26,8 +26,8 @@ dependencies: # tezster_dart: # git: - # url: git@github.com:Rakshak1344/Tezster_dart.git - # ref: master + # url: git@github.com:TechSatya/Tezster_dart.git + # ref: dev tezster_dart: path: ../ diff --git a/lib/helper/nodeWriterHelper.dart b/lib/helper/nodeWriterHelper.dart deleted file mode 100644 index 0b91ba1..0000000 --- a/lib/helper/nodeWriterHelper.dart +++ /dev/null @@ -1,19 +0,0 @@ -import 'dart:typed_data'; - -import 'package:convert/convert.dart'; -import 'package:bs58check/bs58check.dart' as bs58check; - -class NodeWriterHelper { - static String _readSignatureWithHint(Uint8List payload, String hint) { - String encodedPayoad = hex.encode(payload); - String concatEncodedPayload = '09f5cd8612' + encodedPayoad; - String encodedPayoadToHexString = - hex.encode(concatEncodedPayload.codeUnits); - Uint8List finlaListForBS58CHECK = hex.decode(encodedPayoadToHexString); - if (hint == 'edsig') { - return bs58check.encode(finlaListForBS58CHECK); - } else { - throw {"messgae": "Unrecognized key hint, '$hint'"}; - } - } -} diff --git a/lib/helper/tezosMessageUtil.dart b/lib/helper/tezosMessageUtil.dart new file mode 100644 index 0000000..736dc8f --- /dev/null +++ b/lib/helper/tezosMessageUtil.dart @@ -0,0 +1,11 @@ +import 'dart:typed_data'; + +import 'package:bs58check/bs58check.dart' as bs58check; +import 'package:flutter/material.dart'; + +class TezosMessageUtil { + static writeInt() {} + + + +} diff --git a/lib/tezsterNodeWriter.dart b/lib/tezsterNodeWriter.dart index fd4bfa6..bc1bbd4 100644 --- a/lib/tezsterNodeWriter.dart +++ b/lib/tezsterNodeWriter.dart @@ -1,6 +1,6 @@ part of tezster_dart; -class TezsterNodeWriter { +class TezsterNodeWriter with TezosMessageUtil { static performPostRequest({ String server, String command, @@ -30,7 +30,7 @@ class TezsterNodeWriter { static Uint8List _writeKeyWithHint(String key, String hint) { if (hint == "edsk" || hint == "edpk") { - return bs58check.decode(key).sublist(0, 4); + return bs58check.decode(key).sublist(0, 64); } else { throw {"message": "Unrecognized key hint, '$hint'"}; } @@ -49,11 +49,17 @@ class TezsterNodeWriter { } } + static Future _signDetach(Uint8List message, Uint8List sk) async { + return Sodium.cryptoSignDetached(message, sk); + } + static signOperationGroup({ String forgedOperation, String derivationPath, String privateKey, - }) { + }) async { + assert(forgedOperation != null); + assert(privateKey != null); String watermarkedForgedOperationBytesHex = "03" + forgedOperation; String stringToHexString = hex.encode(watermarkedForgedOperationBytesHex.codeUnits); @@ -61,14 +67,149 @@ class TezsterNodeWriter { List hexStringToListOfInt = hex.decode(stringToHexString); // print(hexStringToListOfInt); Uint8List hashedWatermarkedOpBytes = _simpleHash(hexStringToListOfInt, 256); - print("hashedWatermarkedOpBytes ===> $hashedWatermarkedOpBytes"); - print("hashedWatermarkedOpBytes ===> ${hashedWatermarkedOpBytes.length}"); - Uint8List bs58List = _writeKeyWithHint(privateKey, "edsk"); - print("bs58List ===> $bs58List"); + // print("hashedWatermarkedOpBytes ===> $hashedWatermarkedOpBytes"); + // print("hashedWatermarkedOpBytes ===> ${hashedWatermarkedOpBytes.length}"); + Uint8List privateKeyBytes = _writeKeyWithHint(privateKey, "edsk"); + // print("bs58List ===> $privateKeyBytes"); + Uint8List opSignature = + await _signDetach(hashedWatermarkedOpBytes, privateKeyBytes); + // print("opSignature ===> $opSignature"); + + String hexString = _readSignatureWithHint(opSignature, 'edsig'); + // print("hexString ===> $hexString"); + + List listforgedOperation = hex.decode(forgedOperation); + Uint8List uint8ListforgedOperation = + Uint8List.fromList(listforgedOperation); + List signedOpBytes = uint8ListforgedOperation + opSignature; + // print("signedOpBytes ===> $signedOpBytes"); + + return [signedOpBytes, hexString]; + } + + // FORGED OPERATION GROUP + static encodeOpertion(k, v) { + if (k.containsKey('pkh') && k.containsKey('secret')) { + return encodeActivation(k as Activation); + } + + if (k.containsKey('Kind')) { + if (k.kind == 'reveal') return 'reveal'; + if (k.kind == 'transaction') return 'transaction'; + if (k.kind == 'origination') return 'origination'; + if (k.kind == 'delegation') return 'delegation'; + } + + if (k.containsKey('vote')) { + return "encodeBallot"; + } + throw new ErrorDescription("Unsupported message type"); + } + + static String twoByteHex(int n) { + if (n < 128) { + return "0" + n.toRadixString(16).substring(0, 2); + } + + String h = ''; + if (n > 2147483648) { + BigInt r = BigInt.from(n); + while (!r.isNegative) { + //Review + h = ('0' + r.toRadixString(16) + 127.toRadixString(16)) + .substring(0, 2) + + h; + r = r >> 7; + } + } else { + int r = n; + while (r > 0) { + // Review + h = ('0' + (r & 127).toRadixString(16)).substring(0,2) + h; + r = r >>7; + } + } + return h; + } + + + static String writeInt(int value) { + if (value < 0) { + throw new ErrorDescription( + "Use writeSignedInt to encode negative numbers"); + } + + List twoByteListOfIntvalue = hex.decode(twoByteHex(value)); + Uint8List twoByteUint8Listvalue = Uint8List.fromList(twoByteListOfIntvalue); + //pending + Map data = twoByteUint8Listvalue.asMap(); + } + + static Map sepyTnoitarepo = { + 'endorsement': 0, + 'seedNonceRevelation': 1, + 'doubleEndorsementEvidence': 2, + 'doubleBakingEvidence': 3, + 'accountActivation': 4, + 'proposal': 5, + 'ballot': 6, + 'reveal': 7, + 'transaction': 8, + 'origination': 9, + 'delegation': 10, + 'Newreveal': 107, + 'Newtransaction': 108, + 'Neworigination': 109, + 'Newdelegation': 110 + }; + + static String encodeActivation(Activation k) { + String writeIntHex = writeInt(sepyTnoitarepo['accountActivation']); + print("writeIntHex ===> $writeIntHex"); + String hexCode = writeAddress(k.pkh); + writeIntHex += hexCode.substring(4); + writeIntHex += k.secret; + return writeIntHex; } - + static String writeAddress(String address) { + Uint8List uintBsList = bs58check.decode(address).sublist(3); + List bsList = List.from(uintBsList); + String hexString = hex.encode(bsList); + print("hexString ===> $hexString"); + if (address.startsWith("tz1")) { + return "0000" + hexString; + } else if (address.startsWith("tz2")) { + return "0001" + hexString; + } else if (address.startsWith("tz3")) { + return "0002" + hexString; + } else if (address.startsWith("KT1")) { + return "01" + hexString + "00"; + } else { + throw new ErrorDescription("Unrecognized address prefix: "); + } + } + static forgeOperations({ + String branch, + Map operation, + }) { + String encoded = _writeBranch(branch); + print("encoded ===> $encoded"); + operation.forEach((k, v) => encoded += encodeOpertion(k, v)); + return encoded; + } + + static String _writeBranch(String branch) { + Uint8List branchUint8List = bs58check.decode(branch).sublist(2); + String branchHexString = hex.encode(branchUint8List); + return branchHexString; + } +} +class Activation { + String kind; // activate_account + String pkh; + String secret; } diff --git a/lib/tezster_dart.dart b/lib/tezster_dart.dart index 17ddccc..2f7ab75 100644 --- a/lib/tezster_dart.dart +++ b/lib/tezster_dart.dart @@ -1,7 +1,9 @@ library tezster_dart; +import 'dart:async'; import 'dart:convert'; import 'dart:typed_data'; +import 'dart:core'; import 'package:blake2b/blake2b_hash.dart'; import 'package:crypto/crypto.dart'; import 'package:flutter/cupertino.dart'; @@ -14,6 +16,9 @@ import 'package:flutter_sodium/flutter_sodium.dart'; import 'package:convert/convert.dart'; import 'package:http/http.dart' as http; +import './helper/tezosMessageUtil.dart'; + + part 'tezsterNodeReader.dart'; part 'tezsterNodeWriter.dart'; From 5a4e784adb0fbe618a28feb69779375a1d21e0a9 Mon Sep 17 00:00:00 2001 From: Rakshak1344 Date: Mon, 3 Aug 2020 16:14:36 +0530 Subject: [PATCH 03/12] added encode origination and ballot --- .vscode/launch.json | 13 ++ example/lib/main.dart | 42 +++-- lib/tezsterNodeWriter.dart | 319 +++++++++++++++++++++++++++++++------ lib/tezster_dart.dart | 1 + 4 files changed, 320 insertions(+), 55 deletions(-) create mode 100644 .vscode/launch.json diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 0000000..3287bb6 --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,13 @@ +{ + // Use IntelliSense to learn about possible attributes. + // Hover to view descriptions of existing attributes. + // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 + "version": "0.2.0", + "configurations": [ + { + "name": "Flutter", + "request": "launch", + "type": "dart" + } + ] +} \ No newline at end of file diff --git a/example/lib/main.dart b/example/lib/main.dart index 3639f9b..f01783c 100644 --- a/example/lib/main.dart +++ b/example/lib/main.dart @@ -4,6 +4,8 @@ // NOTE: please get the tezster_dart package under pubspec.yaml before running the project +import 'dart:convert'; + import 'package:flutter/material.dart'; import 'package:tezster_dart/tezster_dart.dart'; @@ -178,18 +180,40 @@ class _MyAppState extends State { } nodeWriter() async { - List opGroup = await TezsterNodeWriter.signOperationGroup( - forgedOperation: - "713cb068fe3ac078351727eb5c34279e22b75b0cf4dc0a8d3d599e27031db136040cb9f9da085607c05cac1ca4c62a3f3cfb8146aa9b7f631e52f877a1d363474404da8130b0b940ee", - privateKey: - "edskRdVS5H9YCRAG8yqZkX2nUTbGcaDqjYgopkJwRuPUnYzCn3t9ZGksncTLYe33bFjq29pRhpvjQizCCzmugMGhJiXezixvdC"); - print("bytes ===> ${opGroup[0]}"); - print("Signature ===> ${opGroup[1]}"); + // List keys = await TezsterDart.getKeysFromMnemonic( + // mnemonic: + // "luxury bulb roast timber sense stove sugar sketch goddess host meadow decorate gather salmon funny person canoe daring machine network camp moment wrong dice", + // ); + // print("keys ===> $keys"); + Activation activation = Activation( + pkh: "tz1hhkSbaocSWm3wawZUuUdX57L3maSH16Pv", + secret: "9802d2dcc227576700acf963979792d0abf53340", + ); + + Reveal reveal = Reveal( + gasLimit: "129", + storageLimit: "10", + counter: "213", + fee: "100", + publicKey: "edpkuLog552hecagkykJ3fTvop6grTMhfZY4TWbvchDWdYyxCHcrQL", + source: "tz1VwWdetdADCEMySCumYXWtvf9pZQV3CmE5", + ); + + String activationData = TezsterNodeWriter.forgeOperations( + branch: "BLjxPLCWUuFBewguqrojaHhgAcc8jLZneFkpnrVVcYn2zQz4pmW", + operation: activation, + ); + print("activationData => $activationData"); - TezsterNodeWriter.forgeOperations( - branch: "BKzEzxCwQcXBJNHCxGbnq9H8P3aV7EfFZaot54nShmF3YAgwHDj", + String revealData = TezsterNodeWriter.forgeOperations( + branch: "BLjxPLCWUuFBewguqrojaHhgAcc8jLZneFkpnrVVcYn2zQz4pmW", + operation: reveal, ); + print("revealData => $revealData"); + // var pubkey = TezsterNodeWriter.writePublicKey( + // "edpkuLog552hecagkykJ3fTvop6grTMhfZY4TWbvchDWdYyxCHcrQL"); + // print("pubkey ===> $pubkey"); // TezsterNodeWriter.writeBranch( // "BKzEzxCwQcXBJNHCxGbnq9H8P3aV7EfFZaot54nShmF3YAgwHDj"); } diff --git a/lib/tezsterNodeWriter.dart b/lib/tezsterNodeWriter.dart index bc1bbd4..02cf663 100644 --- a/lib/tezsterNodeWriter.dart +++ b/lib/tezsterNodeWriter.dart @@ -88,61 +88,71 @@ class TezsterNodeWriter with TezosMessageUtil { } // FORGED OPERATION GROUP - static encodeOpertion(k, v) { - if (k.containsKey('pkh') && k.containsKey('secret')) { - return encodeActivation(k as Activation); - } - - if (k.containsKey('Kind')) { - if (k.kind == 'reveal') return 'reveal'; - if (k.kind == 'transaction') return 'transaction'; - if (k.kind == 'origination') return 'origination'; - if (k.kind == 'delegation') return 'delegation'; - } - - if (k.containsKey('vote')) { - return "encodeBallot"; - } - throw new ErrorDescription("Unsupported message type"); - } static String twoByteHex(int n) { if (n < 128) { - return "0" + n.toRadixString(16).substring(0, 2); + String hexString = "0" + n.toRadixString(16); + return hexString.substring(hexString.length - 2); } String h = ''; + if (n > 2147483648) { BigInt r = BigInt.from(n); - while (!r.isNegative) { + while (r > BigInt.zero) { //Review - h = ('0' + r.toRadixString(16) + 127.toRadixString(16)) - .substring(0, 2) + - h; + String data = ('0' + r.toRadixString(16) + 127.toRadixString(16)); + h = data.substring(data.length - 2) + h; r = r >> 7; } } else { int r = n; while (r > 0) { // Review - h = ('0' + (r & 127).toRadixString(16)).substring(0,2) + h; - r = r >>7; + String data = ('0' + (r & 127).toRadixString(16)); + h = data.substring(data.length - 2) + h; + r = r >> 7; } } return h; } - - static String writeInt(int value) { + static writeInt(int value) { if (value < 0) { - throw new ErrorDescription( - "Use writeSignedInt to encode negative numbers"); + return "Use writeSignedInt to encode negative numbers"; } - List twoByteListOfIntvalue = hex.decode(twoByteHex(value)); - Uint8List twoByteUint8Listvalue = Uint8List.fromList(twoByteListOfIntvalue); - //pending - Map data = twoByteUint8Listvalue.asMap(); + String twoByteHexString = twoByteHex(value); + print("twoByteHexString ==> $twoByteHexString"); + + List hexStringToList = hex.decode(twoByteHexString); + print("hexStringToList ===> $hexStringToList"); + + Uint8List twoByteUint8List = Uint8List.fromList(hexStringToList); + print("twoByteUint8List ===> $twoByteUint8List"); + + Map mapData = twoByteUint8List.asMap(); + print("mapData ===> $mapData"); + + List hexList = []; + + mapData.forEach((key, value) { + var hexValue = key == 0 ? value : value ^ 0x80; + print(key.toString() + " " + value.toString()); + print(hexValue); + hexList.add(hexValue); + }); + print("hexList ===> $hexList"); + + List reversedList = (hexList.reversed).toList(); + + Uint8List conversion = Uint8List.fromList((hexList.reversed).toList()); + print("conversion $conversion"); + + var reversedIntListDataToHex = hex.encode(reversedList); + print("reversedIntListDataToHex ===> $reversedIntListDataToHex"); + + return reversedIntListDataToHex; } static Map sepyTnoitarepo = { @@ -163,20 +173,88 @@ class TezsterNodeWriter with TezosMessageUtil { 'Newdelegation': 110 }; - static String encodeActivation(Activation k) { - String writeIntHex = writeInt(sepyTnoitarepo['accountActivation']); - print("writeIntHex ===> $writeIntHex"); - String hexCode = writeAddress(k.pkh); - writeIntHex += hexCode.substring(4); - writeIntHex += k.secret; - return writeIntHex; + static String encodeActivation(Activation operation) { + String hexString = writeInt(sepyTnoitarepo['accountActivation']); + // print("writeIntHex ===> $writeIntHex"); + String hexCode = writeAddress(operation.pkh); + // print("hexCode ===> $hexCode"); + hexString += hexCode.substring(4); + hexString += operation.secret; + return hexString; + } + + static String encodeReveal(Reveal reveal) { + var hex = writeInt(sepyTnoitarepo['reveal']); + hex += writeAddress(reveal.source).substring(2); + hex += writeInt(int.parse(reveal.fee)); + hex += writeInt(int.parse(reveal.counter)); + hex += writeInt(int.parse(reveal.gasLimit)); + hex += writeInt(int.parse(reveal.storageLimit)); + hex += writePublicKey(reveal.publicKey); + return hex; + } + + static String encodeDelegation(Delegation delegation) { + String hexString = writeInt(sepyTnoitarepo['delegation']); + String hexCode = writeAddress(delegation.source); + hexString += hexCode.substring(2); + hexString += writeInt(int.parse(delegation.fee)); + hexString += writeInt(int.parse(delegation.counter)); + hexString += writeInt(int.parse(delegation.gasLimit)); + hexString += writeInt(int.parse(delegation.storageLimit)); + + //tobe moved to seperate file + writeBoolean(bool value) => value ? "ff" : "00"; + + if (delegation.delegate != null && delegation.delegate != "") { + hexString += writeBoolean(true); + // String writeAddressForDelegation = ; + hexString += writeAddress(delegation.delegate).substring(2); + } else { + hexString += writeBoolean(false); + } + + return hexString; + } + + static String encodeBallot(Ballot ballot) { + Uint8List writeBufferWithInt(String value) => bs58check.decode(value); + + String hexString = writeInt(sepyTnoitarepo['ballot']); + hexString += writeAddress(ballot.source).substring(2); + String ballotPeriodHexString = '00000000' + ballot.period.toRadixString(16); + hexString += + ballotPeriodHexString.substring(ballotPeriodHexString.length - 8); + + Uint8List ballotProposalList = writeBufferWithInt(ballot.proposal); + String ballotProposalHexString = hex.encode(ballotProposalList); + + hexString += ballotProposalHexString.substring(4); + String ballotVote = '00' + ballot.vote.toRadixString(16); + hexString += ballotVote.substring(ballotVote.length - 2); + return hexString; + } + + static writePublicKey(String publicKey) { + String _decodeAndAdd(String number) { + Uint8List publicKeyList = bs58check.decode(publicKey).sublist(4); + return number + hex.encode(publicKeyList); + } + + if (publicKey.startsWith("edpk")) { + return _decodeAndAdd("00"); + } else if (publicKey.startsWith("sppk")) { + return _decodeAndAdd("01"); + } else if (publicKey.startsWith("p2pk")) { + return _decodeAndAdd("02"); + } } static String writeAddress(String address) { Uint8List uintBsList = bs58check.decode(address).sublist(3); - List bsList = List.from(uintBsList); - String hexString = hex.encode(bsList); - print("hexString ===> $hexString"); + // List bsList = List.from(uintBsList); + String hexString = hex.encode(uintBsList); + // print("hexString ===> $hexString"); if (address.startsWith("tz1")) { return "0000" + hexString; @@ -193,14 +271,55 @@ class TezsterNodeWriter with TezosMessageUtil { static forgeOperations({ String branch, - Map operation, + dynamic operation, }) { String encoded = _writeBranch(branch); - print("encoded ===> $encoded"); - operation.forEach((k, v) => encoded += encodeOpertion(k, v)); + // print("encoded ===> $encoded"); + encoded += encodeOperationValue(operation); + // print("encoded ===> $newEncode"); return encoded; } + static encodeOperationValue(operation) { + if (operation is Activation) { + return encodeActivation( + Activation( + pkh: operation.pkh, + secret: operation.secret, + ), + ); + } else if (operation is Reveal) { + return encodeReveal(Reveal( + source: operation.source, + fee: operation.fee, + counter: operation.counter, + gasLimit: operation.gasLimit, + publicKey: operation.publicKey, + storageLimit: operation.storageLimit, + )); + } else if (operation is Transaction) { + return 'transaction'; + } else if (operation is Origination) { + return 'origination'; + } else if (operation is Delegation) { + return encodeDelegation(Delegation( + source: operation.source, + fee: operation.fee, + counter: operation.counter, + gasLimit: operation.gasLimit, + storageLimit: operation.storageLimit, + delegate: operation.delegate, + )); + } else if (operation is Ballot) { + return encodeBallot(Ballot( + source: operation.source, + period: operation.period, + proposal: operation.proposal, + vote: operation.vote, + )); + } + } + static String _writeBranch(String branch) { Uint8List branchUint8List = bs58check.decode(branch).sublist(2); String branchHexString = hex.encode(branchUint8List); @@ -209,7 +328,115 @@ class TezsterNodeWriter with TezosMessageUtil { } class Activation { - String kind; // activate_account + // activate_account String pkh; String secret; + Activation({this.pkh, this.secret}); +} + +class Ballot { + String source; + int period; + String proposal; + //Review + int vote; + Ballot({this.source, this.period, this.proposal, this.vote}); +} + +// class BallotVote { +// int yay = 0; +// int nay = 1; +// int pass = 2; +// BallotVote({this.nay,this.pass,this.yay}); +// } + +class Transaction { + String source; + String fee; + String counter; + String gasLimit; + String storageLimit; + String amount; + String destination; + ContractParameters contractParameters; + Transaction({ + this.source, + this.fee, + this.counter, + this.gasLimit, + this.storageLimit, + this.amount, + this.destination, + this.contractParameters, + }); +} + +class ContractParameters { + String entrypoint; + dynamic value; + ContractParameters({ + this.entrypoint, + this.value, + }); +} + +class Delegation { + String source; + String fee; + String counter; + String gasLimit; + String storageLimit; + String delegate; + Delegation({ + this.source, + this.fee, + this.counter, + this.gasLimit, + this.storageLimit, + this.delegate, + }); +} + +class Reveal { + String source; + String fee; + String counter; + String gasLimit; + String storageLimit; + String publicKey; + Reveal({ + this.source, + this.fee, + this.counter, + this.gasLimit, + this.storageLimit, + this.publicKey, + }); +} + +class Origination { + String source; + String fee; + String counter; + String gasLimit; + String storageLimit; + String managerPubkey; // deprecated in P005 + String balance; + bool spendable; // deprecated in P005 + bool delegatable; // deprecated in P005 + String delegate; + dynamic script; + Origination({ + this.source, + this.fee, + this.counter, + this.gasLimit, + this.storageLimit, + this.managerPubkey, + this.balance, + this.spendable, + this.delegatable, + this.delegate, + this.script, + }); } diff --git a/lib/tezster_dart.dart b/lib/tezster_dart.dart index 2f7ab75..2a499a4 100644 --- a/lib/tezster_dart.dart +++ b/lib/tezster_dart.dart @@ -7,6 +7,7 @@ import 'dart:core'; import 'package:blake2b/blake2b_hash.dart'; import 'package:crypto/crypto.dart'; import 'package:flutter/cupertino.dart'; +import 'package:flutter/gestures.dart'; import 'package:password_hash/password_hash.dart'; import 'helper/generateKeys.dart'; import 'package:bip39/bip39.dart' as bip39; From 5febe0c1f237952abdc612be9bc7184ca3b1f174 Mon Sep 17 00:00:00 2001 From: Rakshak1344 Date: Thu, 6 Aug 2020 13:23:40 +0530 Subject: [PATCH 04/12] encodeTransaction method added --- lib/tezsterNodeWriter.dart | 77 ++++++++++++++++++++++++++++++++++++-- 1 file changed, 73 insertions(+), 4 deletions(-) diff --git a/lib/tezsterNodeWriter.dart b/lib/tezsterNodeWriter.dart index 02cf663..72bd987 100644 --- a/lib/tezsterNodeWriter.dart +++ b/lib/tezsterNodeWriter.dart @@ -117,7 +117,7 @@ class TezsterNodeWriter with TezosMessageUtil { return h; } - static writeInt(int value) { + static String writeInt(int value) { if (value < 0) { return "Use writeSignedInt to encode negative numbers"; } @@ -149,7 +149,7 @@ class TezsterNodeWriter with TezosMessageUtil { Uint8List conversion = Uint8List.fromList((hexList.reversed).toList()); print("conversion $conversion"); - var reversedIntListDataToHex = hex.encode(reversedList); + String reversedIntListDataToHex = hex.encode(reversedList); print("reversedIntListDataToHex ===> $reversedIntListDataToHex"); return reversedIntListDataToHex; @@ -184,7 +184,7 @@ class TezsterNodeWriter with TezosMessageUtil { } static String encodeReveal(Reveal reveal) { - var hex = writeInt(sepyTnoitarepo['reveal']); + String hex = writeInt(sepyTnoitarepo['reveal']); hex += writeAddress(reveal.source).substring(2); hex += writeInt(int.parse(reveal.fee)); hex += writeInt(int.parse(reveal.counter)); @@ -194,8 +194,78 @@ class TezsterNodeWriter with TezosMessageUtil { return hex; } + static String normalizeMichelineWhiteSpace(String compositevalue) { + return "normalized"; + } + + static String translateMichelineToHex(String code) { + return "030b"; + } + + static String encodeTransaction(Transaction transaction) { + String hexString = writeInt(sepyTnoitarepo['transaction']); + hexString += writeAddress(transaction.source).substring(2); + hexString += writeInt(int.parse(transaction.fee)); + hexString += writeInt(int.parse(transaction.counter)); + hexString += writeInt(int.parse(transaction.gasLimit)); + hexString += writeInt(int.parse(transaction.storageLimit)); + hexString += writeInt(int.parse(transaction.amount)); + hexString += writeInt(int.parse(transaction.destination)); + + ContractParameters composite = ContractParameters( + entrypoint: transaction.contractParameters.entrypoint, + value: transaction.contractParameters.value, + ); + if (transaction.contractParameters != null) { +// TODO : TranslateMichelineToHex to be done + String code = normalizeMichelineWhiteSpace(jsonEncode(composite.value)); + String result = translateMichelineToHex(code); + + if ((composite.entrypoint == 'default' || composite.entrypoint == '') && + result == '030b') { + hexString += '00'; + } else { + hexString += 'ff'; + + if (composite.entrypoint == 'default' || composite.entrypoint == '') { + hexString += '00'; + } else if (composite.entrypoint == 'root') { + hexString += '01'; + } else if (composite.entrypoint == 'do') { + hexString += '02'; + } else if (composite.entrypoint == 'set_delegate') { + hexString += '03'; + } else if (composite.entrypoint == 'remove_delegate') { + hexString += '04'; + } else { + hexString += 'ff' + + ('0' + composite.entrypoint.length.toRadixString(16)) + .substring(2) + + composite.entrypoint + .split('') + .map((c) => c.codeUnitAt(0).toRadixString(16)) + .join(); + } + + if (result == '030b') { + hexString += '00'; + } else { + int resultLengthDiv2 = int.parse((result.length / 2).toString()); + String data = ('0000000' + resultLengthDiv2.toRadixString(16)); + hexString += data.substring(data.length - 8) + result; + } + } + } else { + hexString += '00'; + } + + return hexString; + } + static String encodeDelegation(Delegation delegation) { String hexString = writeInt(sepyTnoitarepo['delegation']); + + /// Review [hexCode] String hexCode = writeAddress(delegation.source); hexString += hexCode.substring(2); hexString += writeInt(int.parse(delegation.fee)); @@ -328,7 +398,6 @@ class TezsterNodeWriter with TezosMessageUtil { } class Activation { - // activate_account String pkh; String secret; Activation({this.pkh, this.secret}); From ee3328ee949ec7a8dde3265f7e63bf4e083adb65 Mon Sep 17 00:00:00 2001 From: Rakshak1344 Date: Tue, 25 Aug 2020 23:24:27 +0530 Subject: [PATCH 05/12] working on send transaction operation --- example/lib/main.dart | 113 +++++++++++-- example/pubspec.lock | 9 +- example/pubspec.yaml | 11 +- lib/helper/tezosMessageUtil.dart | 93 ++++++++++- lib/{ => src}/tezsterNodeReader.dart | 8 +- lib/{ => src}/tezsterNodeWriter.dart | 231 +++++++++++++++++++++++--- lib/src/tezster_dart.dart | 121 ++++++++++++++ lib/tezster_dart.dart | 235 ++++++++++++++------------- pubspec.lock | 7 + pubspec.yaml | 4 +- 10 files changed, 655 insertions(+), 177 deletions(-) rename lib/{ => src}/tezsterNodeReader.dart (97%) rename lib/{ => src}/tezsterNodeWriter.dart (67%) create mode 100644 lib/src/tezster_dart.dart diff --git a/example/lib/main.dart b/example/lib/main.dart index f01783c..9708eb9 100644 --- a/example/lib/main.dart +++ b/example/lib/main.dart @@ -4,8 +4,6 @@ // NOTE: please get the tezster_dart package under pubspec.yaml before running the project -import 'dart:convert'; - import 'package:flutter/material.dart'; import 'package:tezster_dart/tezster_dart.dart'; @@ -180,11 +178,6 @@ class _MyAppState extends State { } nodeWriter() async { - // List keys = await TezsterDart.getKeysFromMnemonic( - // mnemonic: - // "luxury bulb roast timber sense stove sugar sketch goddess host meadow decorate gather salmon funny person canoe daring machine network camp moment wrong dice", - // ); - // print("keys ===> $keys"); Activation activation = Activation( pkh: "tz1hhkSbaocSWm3wawZUuUdX57L3maSH16Pv", secret: "9802d2dcc227576700acf963979792d0abf53340", @@ -199,23 +192,113 @@ class _MyAppState extends State { source: "tz1VwWdetdADCEMySCumYXWtvf9pZQV3CmE5", ); - String activationData = TezsterNodeWriter.forgeOperations( - branch: "BLjxPLCWUuFBewguqrojaHhgAcc8jLZneFkpnrVVcYn2zQz4pmW", - operation: activation, + Transaction transaction = Transaction( + contractParameters: ContractParameters( + entrypoint: "", + value: "", + ), + amount: "", + counter: "", + destination: "", + fee: "", + gasLimit: "", + source: "", + storageLimit: "", ); - print("activationData => $activationData"); - String revealData = TezsterNodeWriter.forgeOperations( - branch: "BLjxPLCWUuFBewguqrojaHhgAcc8jLZneFkpnrVVcYn2zQz4pmW", - operation: reveal, + Ballot ballot = Ballot( + period: 1, + proposal: "", + source: "", + vote: 0, ); - print("revealData => $revealData"); + // String activationData = TezsterNodeWriter.forgeOperations( + // branch: "BLjxPLCWUuFBewguqrojaHhgAcc8jLZneFkpnrVVcYn2zQz4pmW", + // operation: activation, + // ); + // print("activationData => $activationData"); + + // String revealData = TezsterNodeWriter.forgeOperations( + // branch: "BLjxPLCWUuFBewguqrojaHhgAcc8jLZneFkpnrVVcYn2zQz4pmW", + // operation: reveal, + // ); + // // print("revealData => $revealData"); + + // String transactionData = TezsterNodeWriter.forgeOperations( + // branch: "BLjxPLCWUuFBewguqrojaHhgAcc8jLZneFkpnrVVcYn2zQz4pmW", + // operation: transaction, + // ); + // // print("transactionData ===> $transactionData"); + + // String ballotData = TezsterNodeWriter.forgeOperations( + // branch: "BLjxPLCWUuFBewguqrojaHhgAcc8jLZneFkpnrVVcYn2zQz4pmW", + // operation: ballot, + // ); + // print("ballotData ===> $ballotData"); + + // String jsonDecod = jsonDecode( + // '{"name":{"first":"foo","last":"bar"}, "age":31, "city":"New York"}'); + // print(jsonDecod); + + // String jsonData = TezsterNodeWriter.normalizeMichelineWhiteSpace(jsonDecod); + // print("JSONDATA ===> $jsonData"); + + // var jsonData = + // '{"accounting":[{"firstName":"John","lastName":"Doe","age":23},{"firstName":"Mary","lastName":"Smith","age":32}],"sales":[{"firstName":"Sally","lastName":"Green","age":27},{"firstName":"Jim","lastName":"Galley","age":41}]}'; + + // String newJsonData = + // TezsterNodeWriter.normalizeMichelineWhiteSpace(jsonData); + // print("newJsonData ==> $newJsonData"); + // // String prettyJson(Map json, {int indent = 4}) { + // // var spaces = ' ' * indent; + // // var encoder = JsonEncoder.withIndent(spaces); + // // return encoder.convert(json); + // // } + + // print(TezsterNodeWriter.prettyJson({ + // "prim": "Right", + // "args": [ + // { + // "prim": "Left", + // "args": [ + // {"prim": "Unit"} + // ] + // } + // ] + // })); + + // print("newJsonData ===> $newJsonData"); // var pubkey = TezsterNodeWriter.writePublicKey( // "edpkuLog552hecagkykJ3fTvop6grTMhfZY4TWbvchDWdYyxCHcrQL"); // print("pubkey ===> $pubkey"); // TezsterNodeWriter.writeBranch( // "BKzEzxCwQcXBJNHCxGbnq9H8P3aV7EfFZaot54nShmF3YAgwHDj"); + + // { + // "destination": "KT1LRre6w4EgkCRLwUugQLEdRGPvJdTmx3Ae", + // "amount": "10", + // "storage_limit": "1000", + // "gas_limit": "100000", + // "counter": "606113", + // "fee": "100000", + // "source": "tz1NN5QooJWkW44KFfrXqLRaxEa5Wxw3f9FF", + // "kind": "transaction", + // "parameters": { + // "entrypoint": "default", + // "value": { + // "prim": "Right", + // "args": [ + // { + // "prim": "Left", + // "args": [ + // {"prim": "Unit"} + // ] + // } + // ] + // } + // } + // } } @override diff --git a/example/pubspec.lock b/example/pubspec.lock index b991210..74a5013 100644 --- a/example/pubspec.lock +++ b/example/pubspec.lock @@ -122,7 +122,7 @@ packages: name: http url: "https://pub.dartlang.org" source: hosted - version: "0.12.1" + version: "0.12.2" http_parser: dependency: transitive description: @@ -137,6 +137,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "2.1.12" + js: + dependency: transitive + description: + name: js + url: "https://pub.dartlang.org" + source: hosted + version: "0.6.2" matcher: dependency: transitive description: diff --git a/example/pubspec.yaml b/example/pubspec.yaml index c565310..a77bc68 100644 --- a/example/pubspec.yaml +++ b/example/pubspec.yaml @@ -3,7 +3,7 @@ description: A new Flutter project. # The following line prevents the package from being accidentally published to # pub.dev using `pub publish`. This is preferred for private packages. -publish_to: 'none' # Remove this line if you wish to publish to pub.dev +publish_to: "none" # Remove this line if you wish to publish to pub.dev # The following defines the version and build number for your application. # A version number is three numbers separated by dots, like 1.2.43 @@ -28,40 +28,33 @@ dependencies: # git: # url: git@github.com:TechSatya/Tezster_dart.git # ref: dev - tezster_dart: path: ../ # The following adds the Cupertino Icons font to your application. # Use with the CupertinoIcons class for iOS style icons. cupertino_icons: ^0.1.3 - + dev_dependencies: flutter_test: sdk: flutter # For information on the generic Dart part of this file, see the # following page: https://dart.dev/tools/pub/pubspec - # The following section is specific to Flutter. flutter: - # The following line ensures that the Material Icons font is # included with your application, so that you can use the icons in # the material Icons class. uses-material-design: true - # To add assets to your application, add an assets section, like this: # assets: # - images/a_dot_burr.jpeg # - images/a_dot_ham.jpeg - # An image asset can refer to one or more resolution-specific "variants", see # https://flutter.dev/assets-and-images/#resolution-aware. - # For details regarding adding assets from package dependencies, see # https://flutter.dev/assets-and-images/#from-packages - # To add custom fonts to your application, add a fonts section here, # in this "flutter" section. Each entry in this list should have a # "family" key with the font family name, and a "fonts" key with a diff --git a/lib/helper/tezosMessageUtil.dart b/lib/helper/tezosMessageUtil.dart index 736dc8f..6c9ff6e 100644 --- a/lib/helper/tezosMessageUtil.dart +++ b/lib/helper/tezosMessageUtil.dart @@ -1,11 +1,94 @@ import 'dart:typed_data'; - -import 'package:bs58check/bs58check.dart' as bs58check; +import 'package:convert/convert.dart'; import 'package:flutter/material.dart'; +import 'package:bs58check/bs58check.dart' as bs58check; + +class TezsterMessageUtil { + TezsterMessageUtil._(); + static String twoByteHex(int n) { + if (n < 128) { + String hexString = "0" + n.toRadixString(16); + return hexString.substring(hexString.length - 2); + } + + String h = ''; + + if (n > 2147483648) { + BigInt r = BigInt.from(n); + while (r > BigInt.zero) { + //Review + String data = ('0' + r.toRadixString(16) + 127.toRadixString(16)); + h = data.substring(data.length - 2) + h; + r = r >> 7; + } + } else { + int r = n; + while (r > 0) { + // Review + String data = ('0' + (r & 127).toRadixString(16)); + h = data.substring(data.length - 2) + h; + r = r >> 7; + } + } + return h; + } + + static String writeInt(int value) { + if (value < 0) { + return "Use writeSignedInt to encode negative numbers"; + } + + String twoByteHexString = twoByteHex(value); + // print("twoByteHexString ==> $twoByteHexString"); + + List hexStringToList = hex.decode(twoByteHexString); + // print("hexStringToList ===> $hexStringToList"); + + Uint8List twoByteUint8List = Uint8List.fromList(hexStringToList); + // print("twoByteUint8List ===> $twoByteUint8List"); + + Map mapData = twoByteUint8List.asMap(); + // print("mapData ===> $mapData"); + + List hexList = []; + + mapData.forEach((key, value) { + var hexValue = key == 0 ? value : value ^ 0x80; + // print(key.toString() + " " + value.toString()); + // print(hexValue); + hexList.add(hexValue); + }); + // print("hexList ===> $hexList"); + + List reversedList = (hexList.reversed).toList(); + + Uint8List conversion = Uint8List.fromList((hexList.reversed).toList()); + // print("conversion $conversion"); + + String reversedIntListDataToHex = hex.encode(reversedList); + // print("reversedIntListDataToHex ===> $reversedIntListDataToHex"); + + return reversedIntListDataToHex; + } -class TezosMessageUtil { - static writeInt() {} + static String writeAddress(String address) { + Uint8List uintBsList = bs58check.decode(address).sublist(3); + // List bsList = List.from(uintBsList); + String hexString = hex.encode(uintBsList); + // print("hexString ===> $hexString"); - + if (address.startsWith("tz1")) { + return "0000" + hexString; + } else if (address.startsWith("tz2")) { + return "0001" + hexString; + } else if (address.startsWith("tz3")) { + return "0002" + hexString; + } else if (address.startsWith("KT1")) { + return "01" + hexString + "00"; + } else { + throw ErrorDescription("Unrecognized address prefix: "); + } + } + static String writeBoolean(bool value) => value ? "ff" : "00"; } diff --git a/lib/tezsterNodeReader.dart b/lib/src/tezsterNodeReader.dart similarity index 97% rename from lib/tezsterNodeReader.dart rename to lib/src/tezsterNodeReader.dart index a7d9870..1f87782 100644 --- a/lib/tezsterNodeReader.dart +++ b/lib/src/tezsterNodeReader.dart @@ -1,4 +1,6 @@ -part of tezster_dart; +import 'dart:convert'; + +import 'package:http/http.dart' as http; class TezsterNodeReader { static dynamic performGetRequest({ @@ -189,8 +191,8 @@ class TezsterNodeReader { applied.forEach((g) { if (g["contents"][0]["source"] == accountHash || g["contents"][0]["destination"] == accountHash) { - //print("G ===> ${g["contents"]}"); - data.insertAll(0,g["contents"]); + //print("G ===> ${g["contents"]}"); + data.insertAll(0, g["contents"]); } }); return data; diff --git a/lib/tezsterNodeWriter.dart b/lib/src/tezsterNodeWriter.dart similarity index 67% rename from lib/tezsterNodeWriter.dart rename to lib/src/tezsterNodeWriter.dart index 72bd987..96722a7 100644 --- a/lib/tezsterNodeWriter.dart +++ b/lib/src/tezsterNodeWriter.dart @@ -1,6 +1,17 @@ -part of tezster_dart; - -class TezsterNodeWriter with TezosMessageUtil { +import 'dart:convert'; +import 'dart:typed_data'; +import 'dart:async'; +import 'dart:core'; + +import 'package:blake2b/blake2b_hash.dart'; +import 'package:flutter/material.dart'; +import 'package:bs58check/bs58check.dart' as bs58check; +import 'package:flutter_sodium/flutter_sodium.dart'; +import 'package:convert/convert.dart'; +import 'package:http/http.dart' as http; +import 'package:tezster_dart/tezster_dart.dart'; + +class TezsterNodeWriter { static performPostRequest({ String server, String command, @@ -184,22 +195,47 @@ class TezsterNodeWriter with TezosMessageUtil { } static String encodeReveal(Reveal reveal) { - String hex = writeInt(sepyTnoitarepo['reveal']); - hex += writeAddress(reveal.source).substring(2); - hex += writeInt(int.parse(reveal.fee)); - hex += writeInt(int.parse(reveal.counter)); - hex += writeInt(int.parse(reveal.gasLimit)); - hex += writeInt(int.parse(reveal.storageLimit)); - hex += writePublicKey(reveal.publicKey); - return hex; + String hexString = writeInt(sepyTnoitarepo['reveal']); + hexString += writeAddress(reveal.source).substring(2); + hexString += writeInt(int.parse(reveal.fee)); + hexString += writeInt(int.parse(reveal.counter)); + hexString += writeInt(int.parse(reveal.gasLimit)); + hexString += writeInt(int.parse(reveal.storageLimit)); + hexString += writePublicKey(reveal.publicKey); + return hexString; } + /// TODO : This is pending [normalizeMichelineWhiteSpace] function static String normalizeMichelineWhiteSpace(String compositevalue) { - return "normalized"; + return compositevalue + .replaceAll(RegExp('/ +/g'), ' ') + .replaceAll(RegExp(r'/\[{/g'), '[ {') + .replaceAll(RegExp('/}\]/g'), '} ]') + .replaceAll(RegExp('/},{/g'), '}, {') + .replaceAll(RegExp('/\]}/g'), '] }') + .replaceAll(RegExp('/":"/g'), '": "') + .replaceAll(RegExp(r'/":\[/g'), '": [') + .replaceAll(RegExp('/{"/g'), '{ "') + .replaceAll(RegExp('/"}/g'), '" }') + .replaceAll(RegExp('/,"/g'), ', "') + .replaceAll(RegExp('/","/g'), '", "') + .replaceAll(RegExp(r'/\[\[/g'), '[ [') + .replaceAll(RegExp('/\]\]/g'), '] ]') + .replaceAll(RegExp(r'/\["/g'), '\[ "') + .replaceAll(RegExp('/"\]/g'), '" \]') + .replaceAll(RegExp('/\[ +\]/g'), '\[\]') + .trim(); + // return compositevalue.replace(RegExp(/ +/g), ' '); + } + + static String prettyJson(Map json, {int indent = 4}) { + var spaces = ' ' * indent; + var encoder = JsonEncoder.withIndent(spaces); + return encoder.convert(json); } static String translateMichelineToHex(String code) { - return "030b"; + return ""; } static String encodeTransaction(Transaction transaction) { @@ -212,12 +248,10 @@ class TezsterNodeWriter with TezosMessageUtil { hexString += writeInt(int.parse(transaction.amount)); hexString += writeInt(int.parse(transaction.destination)); - ContractParameters composite = ContractParameters( - entrypoint: transaction.contractParameters.entrypoint, - value: transaction.contractParameters.value, - ); if (transaction.contractParameters != null) { -// TODO : TranslateMichelineToHex to be done + ContractParameters composite = transaction.contractParameters; + + // TODO : TranslateMichelineToHex to be done String code = normalizeMichelineWhiteSpace(jsonEncode(composite.value)); String result = translateMichelineToHex(code); @@ -262,6 +296,36 @@ class TezsterNodeWriter with TezosMessageUtil { return hexString; } + static String encodeOrigination(Origination origination) { + String hexString = writeInt(sepyTnoitarepo['origination']); + hexString = writeAddress(origination.source).substring(2); + hexString = writeInt(int.parse(origination.fee)); + hexString = writeInt(int.parse(origination.counter)); + hexString = writeInt(int.parse(origination.gasLimit)); + hexString = writeInt(int.parse(origination.storageLimit)); + hexString = writeInt(int.parse(origination.balance)); + + writeBoolean(bool value) => value ? "ff" : "00"; + + if (origination.delegate != null) { + hexString += writeBoolean(true); + hexString += writeAddress(origination.delegate).substring(2); + } else { + hexString += writeBoolean(false); + } + + if (origination.script) { + List parts = []; + parts.add(origination.script['code']); + parts.add(origination.script['storage']); + + /// TODO : Pending to review [normalizeMichelineWhiteSpace] and [translateMichelineToHex]. + // hexString += + // parts. + } + return hexString; + } + static String encodeDelegation(Delegation delegation) { String hexString = writeInt(sepyTnoitarepo['delegation']); @@ -352,12 +416,10 @@ class TezsterNodeWriter with TezosMessageUtil { static encodeOperationValue(operation) { if (operation is Activation) { - return encodeActivation( - Activation( - pkh: operation.pkh, - secret: operation.secret, - ), - ); + return encodeActivation(Activation( + pkh: operation.pkh, + secret: operation.secret, + )); } else if (operation is Reveal) { return encodeReveal(Reveal( source: operation.source, @@ -368,9 +430,30 @@ class TezsterNodeWriter with TezosMessageUtil { storageLimit: operation.storageLimit, )); } else if (operation is Transaction) { - return 'transaction'; + return encodeTransaction(Transaction( + amount: operation.amount, + counter: operation.counter, + destination: operation.destination, + contractParameters: operation.contractParameters, + fee: operation.fee, + gasLimit: operation.gasLimit, + source: operation.source, + storageLimit: operation.storageLimit, + )); } else if (operation is Origination) { - return 'origination'; + return encodeOrigination(Origination( + source: operation.source, + balance: operation.balance, + counter: operation.counter, + fee: operation.fee, + gasLimit: operation.gasLimit, + storageLimit: operation.storageLimit, + delegate: operation.delegate, + delegatable: operation.delegatable, + managerPubkey: operation.managerPubkey, + script: operation.script, + spendable: operation.spendable, + )); } else if (operation is Delegation) { return encodeDelegation(Delegation( source: operation.source, @@ -395,6 +478,102 @@ class TezsterNodeWriter with TezosMessageUtil { String branchHexString = hex.encode(branchUint8List); return branchHexString; } + + /// TODO : Send Transaction Operation + sendTransactionOperation({ + String server, + KeyStore keyStore, + String to, + int amount, + int fee, + String derivationPath = '', + }) async { + dynamic counter = await TezsterNodeReader.getCounterForAccount( + server: server, accountHash: keyStore.publicKeyHash) + + 1; + Transaction transaction = Transaction( + destination: to, + amount: amount.toString(), + storageLimit: 496.toString(), + gasLimit: 10600.toString(), + counter: counter.toString(), + fee: fee.toString(), + source: keyStore.publicKeyHash, + ); + + dynamic transactionOperation = await appendRevealOperation( + server: server, + keyStore: keyStore, + accountHash: keyStore.publicKeyHash, + accountOperationIndex: counter - 1, + transactions: transaction, + ); + + return transactionOperation; + } + + sendOperation(String server, dynamic operations, dynamic keyStore, + String derivationPath) async { + var blockHead = await TezsterNodeReader.getBlockHead(server: server); + var forgedOperationGroup = + forgeOperations(branch: blockHead.hash, operation: operations); + var signedOpGroup = await signOperationGroup( + forgedOperation: forgedOperationGroup, + privateKey: keyStore.privateKey, + derivationPath: derivationPath, + ); + + /// TODO : Pending Task + } + + appendRevealOperation({ + @required String server, + @required dynamic keyStore, + @required String accountHash, + @required int accountOperationIndex, + @required dynamic transactions, + }) { + dynamic isKeyRevealed = TezsterNodeReader.isManagerKeyRevealedForAccount( + server: server, accountHash: accountHash); + int counter = accountOperationIndex + 1; + + if (!isKeyRevealed) { + Reveal revealOp = Reveal( + source: accountHash, + fee: '0', + counter: counter.toString(), + gasLimit: '10600', + storageLimit: '0', + publicKey: keyStore.publicKey, + ); + + transactions.forEach((transaction, i) { + var c = accountOperationIndex + 2 + i; + transaction.counter = c.toString(); + }); + + return [revealOp, ...transactions]; + } + return transactions; + } +} + +enum StoreType { mnemonic, fundraiser, hardware } + +class KeyStore { + String publicKey; + String privateKey; + String publicKeyHash; + String seed; + String derivationPath; + StoreType storeType = StoreType.mnemonic; + KeyStore( + {this.publicKey, + this.privateKey, + this.publicKeyHash, + this.seed, + this.derivationPath, + this.storeType}); } class Activation { diff --git a/lib/src/tezster_dart.dart b/lib/src/tezster_dart.dart new file mode 100644 index 0000000..6742110 --- /dev/null +++ b/lib/src/tezster_dart.dart @@ -0,0 +1,121 @@ +library tezster_dart; + +import 'dart:async'; +import 'dart:convert'; +import 'dart:typed_data'; +import 'dart:core'; +import 'package:convert/convert.dart'; +import 'package:blake2b/blake2b_hash.dart'; +import 'package:crypto/crypto.dart'; +import 'package:password_hash/password_hash.dart'; +import 'package:bip39/bip39.dart' as bip39; +import 'package:bs58check/bs58check.dart' as bs58check; +import "package:unorm_dart/unorm_dart.dart" as unorm; +import 'package:flutter_sodium/flutter_sodium.dart'; + +import 'package:tezster_dart/helper/generateKeys.dart'; + +class TezsterDart { + static String generateMnemonic({int strength = 256}) { + return bip39.generateMnemonic(strength: strength); + } + + static Future> getKeysFromMnemonic({ + String mnemonic, + }) async { + assert(mnemonic != null); + Uint8List seed = bip39.mnemonicToSeed(mnemonic); + Uint8List seedLength32 = seed.sublist(0, 32); + Map keys = + await Sodium.cryptoSignSeedKeypair(seedLength32); + Uint8List sk = keys['sk']; + Uint8List pk = keys['pk']; + String skKey = GenerateKeys.readKeysWithHint(sk, '2bf64e07'); + String pkKey = GenerateKeys.readKeysWithHint(pk, '0d0f25d9'); + String pkKeyHash = GenerateKeys.computeKeyHash(pk); + return [skKey, pkKey, pkKeyHash]; + } + + static Future> getKeysFromMnemonicAndPassphrase({ + String mnemonic, + String passphrase, + }) async { + assert(mnemonic != null); + assert(passphrase != null); + return await _unlockKeys( + passphrase: passphrase, + mnemonic: mnemonic, + ); + } + + static Future> unlockFundraiserIdentity({ + String mnemonic, + String email, + String passphrase = "", + }) async { + assert(mnemonic != null); + assert(email != null); + return await _unlockKeys( + email: email, + passphrase: passphrase, + mnemonic: mnemonic, + ); + } + + static Future> signOperationGroup({ + String privateKey, + String forgedOperation, + }) async { + assert(privateKey != null); + assert(forgedOperation != null); + String watermarkedForgedOperationBytesHex = '03' + forgedOperation; + List hexStringToListOfInt = + hex.decode(watermarkedForgedOperationBytesHex); + Uint8List hashedWatermarkedOpBytes = + Blake2bHash.hashWithDigestSize(256, hexStringToListOfInt); + Uint8List privateKeyBytes = bs58check.decode(privateKey); + List pkB = List.from(privateKeyBytes); + pkB.removeRange(0, 4); + Uint8List finalPKb = Uint8List.fromList(pkB); + Uint8List value = await Sodium.cryptoSignDetached( + hashedWatermarkedOpBytes, + finalPKb, + useBackgroundThread: false, + ); + String opSignatureHex = hex.encode(value); + String hexStringToEncode = '09f5cd8612' + opSignatureHex; + Uint8List hexDeco = hex.decode(hexStringToEncode); + String hexSignature = bs58check.encode(hexDeco); + String signedOpBytes = forgedOperation + opSignatureHex; + return [hexSignature, signedOpBytes]; + } + + static Future> _unlockKeys({ + String mnemonic, + String passphrase = "", + String email = "", + }) async { + assert(mnemonic != null); + assert(passphrase != null); + + List stringNormalize(String stringToNormalize) { + String normalizedString = unorm.nfkd(stringToNormalize); + List stringToBuffer = utf8.encode(normalizedString); + return stringToBuffer; + } + + List mnemonicsBuffer = stringNormalize(mnemonic); + String m = String.fromCharCodes(mnemonicsBuffer); + List normalizedPassphrase = stringNormalize("$email" + "$passphrase"); + String normString = String.fromCharCodes(normalizedPassphrase); + String p = "mnemonic" + normString; + Uint8List seed = PBKDF2(hashAlgorithm: sha512).generateKey(m, p, 2048, 32); + Map keys = await Sodium.cryptoSignSeedKeypair(seed); + Uint8List sk = keys['sk']; + Uint8List pk = keys['pk']; + String skKey = GenerateKeys.readKeysWithHint(sk, '2bf64e07'); + String pkKey = GenerateKeys.readKeysWithHint(pk, '0d0f25d9'); + String pkKeyHash = GenerateKeys.computeKeyHash(pk); + return [skKey, pkKey, pkKeyHash]; + } +} diff --git a/lib/tezster_dart.dart b/lib/tezster_dart.dart index 2a499a4..9c25897 100644 --- a/lib/tezster_dart.dart +++ b/lib/tezster_dart.dart @@ -1,129 +1,130 @@ library tezster_dart; -import 'dart:async'; -import 'dart:convert'; -import 'dart:typed_data'; -import 'dart:core'; -import 'package:blake2b/blake2b_hash.dart'; -import 'package:crypto/crypto.dart'; -import 'package:flutter/cupertino.dart'; -import 'package:flutter/gestures.dart'; -import 'package:password_hash/password_hash.dart'; -import 'helper/generateKeys.dart'; -import 'package:bip39/bip39.dart' as bip39; -import 'package:bs58check/bs58check.dart' as bs58check; -import "package:unorm_dart/unorm_dart.dart" as unorm; -import 'package:flutter_sodium/flutter_sodium.dart'; -import 'package:convert/convert.dart'; -import 'package:http/http.dart' as http; +export 'src/tezster_dart.dart'; +export 'src/tezsterNodeReader.dart'; +export 'src/tezsterNodeWriter.dart'; -import './helper/tezosMessageUtil.dart'; +// import 'dart:async'; +// import 'dart:convert'; +// import 'dart:typed_data'; +// import 'dart:core'; +// import 'package:blake2b/blake2b_hash.dart'; +// import 'package:crypto/crypto.dart'; +// import 'package:flutter/cupertino.dart'; +// import 'package:password_hash/password_hash.dart'; +// import 'helper/generateKeys.dart'; +// import 'package:bip39/bip39.dart' as bip39; +// import 'package:bs58check/bs58check.dart' as bs58check; +// import "package:unorm_dart/unorm_dart.dart" as unorm; +// import 'package:flutter_sodium/flutter_sodium.dart'; +// import 'package:convert/convert.dart'; +// import 'package:http/http.dart' as http; +// import 'helper/tezosMessageUtil.dart'; +// part 'tezsterNodeReader.dart'; +// part 'tezsterNodeWriter.dart'; -part 'tezsterNodeReader.dart'; -part 'tezsterNodeWriter.dart'; +// class TezsterDart { +// static String generateMnemonic({int strength = 256}) { +// return bip39.generateMnemonic(strength: strength); +// } -class TezsterDart { - static String generateMnemonic({int strength = 256}) { - return bip39.generateMnemonic(strength: strength); - } +// static Future> getKeysFromMnemonic({ +// String mnemonic, +// }) async { +// assert(mnemonic != null); +// Uint8List seed = bip39.mnemonicToSeed(mnemonic); +// Uint8List seedLength32 = seed.sublist(0, 32); +// Map keys = +// await Sodium.cryptoSignSeedKeypair(seedLength32); +// Uint8List sk = keys['sk']; +// Uint8List pk = keys['pk']; +// String skKey = GenerateKeys.readKeysWithHint(sk, '2bf64e07'); +// String pkKey = GenerateKeys.readKeysWithHint(pk, '0d0f25d9'); +// String pkKeyHash = GenerateKeys.computeKeyHash(pk); +// return [skKey, pkKey, pkKeyHash]; +// } - static Future> getKeysFromMnemonic({ - String mnemonic, - }) async { - assert(mnemonic != null); - Uint8List seed = bip39.mnemonicToSeed(mnemonic); - Uint8List seedLength32 = seed.sublist(0, 32); - Map keys = - await Sodium.cryptoSignSeedKeypair(seedLength32); - Uint8List sk = keys['sk']; - Uint8List pk = keys['pk']; - String skKey = GenerateKeys.readKeysWithHint(sk, '2bf64e07'); - String pkKey = GenerateKeys.readKeysWithHint(pk, '0d0f25d9'); - String pkKeyHash = GenerateKeys.computeKeyHash(pk); - return [skKey, pkKey, pkKeyHash]; - } +// static Future> getKeysFromMnemonicAndPassphrase({ +// String mnemonic, +// String passphrase, +// }) async { +// assert(mnemonic != null); +// assert(passphrase != null); +// return await _unlockKeys( +// passphrase: passphrase, +// mnemonic: mnemonic, +// ); +// } - static Future> getKeysFromMnemonicAndPassphrase({ - String mnemonic, - String passphrase, - }) async { - assert(mnemonic != null); - assert(passphrase != null); - return await _unlockKeys( - passphrase: passphrase, - mnemonic: mnemonic, - ); - } +// static Future> unlockFundraiserIdentity({ +// String mnemonic, +// String email, +// String passphrase = "", +// }) async { +// assert(mnemonic != null); +// assert(email != null); +// return await _unlockKeys( +// email: email, +// passphrase: passphrase, +// mnemonic: mnemonic, +// ); +// } - static Future> unlockFundraiserIdentity({ - String mnemonic, - String email, - String passphrase = "", - }) async { - assert(mnemonic != null); - assert(email != null); - return await _unlockKeys( - email: email, - passphrase: passphrase, - mnemonic: mnemonic, - ); - } +// static Future> signOperationGroup({ +// String privateKey, +// String forgedOperation, +// }) async { +// assert(privateKey != null); +// assert(forgedOperation != null); +// String watermarkedForgedOperationBytesHex = '03' + forgedOperation; +// List hexStringToListOfInt = +// hex.decode(watermarkedForgedOperationBytesHex); +// Uint8List hashedWatermarkedOpBytes = +// Blake2bHash.hashWithDigestSize(256, hexStringToListOfInt); +// Uint8List privateKeyBytes = bs58check.decode(privateKey); +// List pkB = List.from(privateKeyBytes); +// pkB.removeRange(0, 4); +// Uint8List finalPKb = Uint8List.fromList(pkB); +// Uint8List value = await Sodium.cryptoSignDetached( +// hashedWatermarkedOpBytes, +// finalPKb, +// useBackgroundThread: false, +// ); +// String opSignatureHex = hex.encode(value); +// String hexStringToEncode = '09f5cd8612' + opSignatureHex; +// Uint8List hexDeco = hex.decode(hexStringToEncode); +// String hexSignature = bs58check.encode(hexDeco); +// String signedOpBytes = forgedOperation + opSignatureHex; +// return [hexSignature, signedOpBytes]; +// } - static Future> signOperationGroup({ - String privateKey, - String forgedOperation, - }) async { - assert(privateKey != null); - assert(forgedOperation != null); - String watermarkedForgedOperationBytesHex = '03' + forgedOperation; - List hexStringToListOfInt = - hex.decode(watermarkedForgedOperationBytesHex); - Uint8List hashedWatermarkedOpBytes = - Blake2bHash.hashWithDigestSize(256, hexStringToListOfInt); - Uint8List privateKeyBytes = bs58check.decode(privateKey); - List pkB = List.from(privateKeyBytes); - pkB.removeRange(0, 4); - Uint8List finalPKb = Uint8List.fromList(pkB); - Uint8List value = await Sodium.cryptoSignDetached( - hashedWatermarkedOpBytes, - finalPKb, - useBackgroundThread: false, - ); - String opSignatureHex = hex.encode(value); - String hexStringToEncode = '09f5cd8612' + opSignatureHex; - Uint8List hexDeco = hex.decode(hexStringToEncode); - String hexSignature = bs58check.encode(hexDeco); - String signedOpBytes = forgedOperation + opSignatureHex; - return [hexSignature, signedOpBytes]; - } +// static Future> _unlockKeys({ +// String mnemonic, +// String passphrase = "", +// String email = "", +// }) async { +// assert(mnemonic != null); +// assert(passphrase != null); - static Future> _unlockKeys({ - String mnemonic, - String passphrase = "", - String email = "", - }) async { - assert(mnemonic != null); - assert(passphrase != null); +// List stringNormalize(String stringToNormalize) { +// String normalizedString = unorm.nfkd(stringToNormalize); +// List stringToBuffer = utf8.encode(normalizedString); +// return stringToBuffer; +// } - List stringNormalize(String stringToNormalize) { - String normalizedString = unorm.nfkd(stringToNormalize); - List stringToBuffer = utf8.encode(normalizedString); - return stringToBuffer; - } - - List mnemonicsBuffer = stringNormalize(mnemonic); - String m = String.fromCharCodes(mnemonicsBuffer); - List normalizedPassphrase = stringNormalize("$email" + "$passphrase"); - String normString = String.fromCharCodes(normalizedPassphrase); - String p = "mnemonic" + normString; - Uint8List seed = PBKDF2(hashAlgorithm: sha512).generateKey(m, p, 2048, 32); - Map keys = await Sodium.cryptoSignSeedKeypair(seed); - Uint8List sk = keys['sk']; - Uint8List pk = keys['pk']; - String skKey = GenerateKeys.readKeysWithHint(sk, '2bf64e07'); - String pkKey = GenerateKeys.readKeysWithHint(pk, '0d0f25d9'); - String pkKeyHash = GenerateKeys.computeKeyHash(pk); - return [skKey, pkKey, pkKeyHash]; - } -} +// List mnemonicsBuffer = stringNormalize(mnemonic); +// String m = String.fromCharCodes(mnemonicsBuffer); +// List normalizedPassphrase = stringNormalize("$email" + "$passphrase"); +// String normString = String.fromCharCodes(normalizedPassphrase); +// String p = "mnemonic" + normString; +// Uint8List seed = PBKDF2(hashAlgorithm: sha512).generateKey(m, p, 2048, 32); +// Map keys = await Sodium.cryptoSignSeedKeypair(seed); +// Uint8List sk = keys['sk']; +// Uint8List pk = keys['pk']; +// String skKey = GenerateKeys.readKeysWithHint(sk, '2bf64e07'); +// String pkKey = GenerateKeys.readKeysWithHint(pk, '0d0f25d9'); +// String pkKeyHash = GenerateKeys.computeKeyHash(pk); +// return [skKey, pkKey, pkKeyHash]; +// } +// } diff --git a/pubspec.lock b/pubspec.lock index f844fe7..7c5c865 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -130,6 +130,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "2.1.12" + js: + dependency: "direct main" + description: + name: js + url: "https://pub.dartlang.org" + source: hosted + version: "0.6.2" matcher: dependency: transitive description: diff --git a/pubspec.yaml b/pubspec.yaml index cb7b477..386d237 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,5 +1,6 @@ name: tezster_dart -description: A flutter package which provides the functionalities to play around with tezos dApps +description: A flutter package which provides the functionalities to play around + with tezos dApps version: 1.0.0 homepage: https://github.com/Tezsure/tezster_dart repository: https://github.com/Tezsure/tezster_dart @@ -20,6 +21,7 @@ dependencies: password_hash: ^2.0.0 convert: ^2.1.1 http: ^0.12.1 + js: ^0.6.2 dev_dependencies: flutter_test: From 0daaf7dd9a5f1f715017fd8d16529458b1a929e1 Mon Sep 17 00:00:00 2001 From: Rakshak1344 Date: Thu, 3 Sep 2020 19:18:07 +0530 Subject: [PATCH 06/12] Working on send transaction operation --- example/lib/main.dart | 43 ++- example/pubspec.lock | 7 + lib/src/tezsterNodeReader.dart | 21 +- lib/src/tezsterNodeWriter.dart | 141 +++++++-- lib/src/tezsterSendOperation.dart | 469 ++++++++++++++++++++++++++++++ lib/tezster_dart.dart | 1 + pubspec.lock | 7 + pubspec.yaml | 1 + 8 files changed, 656 insertions(+), 34 deletions(-) create mode 100644 lib/src/tezsterSendOperation.dart diff --git a/example/lib/main.dart b/example/lib/main.dart index 9708eb9..3b53f16 100644 --- a/example/lib/main.dart +++ b/example/lib/main.dart @@ -127,13 +127,11 @@ class _MyAppState extends State { print( "GET-MempoolOperations-ForAccount ===> $getMempoolOperationsForAccount"); - dynamic isManagerKeyRevealedForAccount = - await TezsterNodeReader.isManagerKeyRevealedForAccount( - server: testNetServer, - accountHash: "tz1ZfFASQvmmz47ru5nn9GhX5oswCRVX5z1r", + bool isRevealed = await TezsterNodeReader.isManagerKeyRevealedForAccount( + server: "https://testnet.tezster.tech/", + accountHash: 'tz1KqTpEZ7Yob7QbPE4Hy4Wo8fHG8LhKxZSx', ); - print( - "Is-ManagerKey-Revealed-ForAccount ===> $isManagerKeyRevealedForAccount"); + print("isRevealed ===> $isRevealed"); //Yet to be tested // dynamic getAccForBlock = await TezsterNodeReader.getAccountForBlock( @@ -213,6 +211,39 @@ class _MyAppState extends State { vote: 0, ); + var sendOP = TezsterSendOperation.sendTransactionOperation( + server: 'https://testnet.tezster.tech/', + amount: 10, + fee: 2, + to: 'tz1PrMATKhpXz81CnEZL2sudhVmhbz8W7Lm5', + derivationPath: "", + keyStore: KeyStore( + publicKey: 'edpkuBknW28nW72KG6RoHtYW7p12T6GKc7nAbwYX5m8Wd9sDVC9yav', + privateKey: + 'edskRuR1azSfboG86YPTyxrQgosh5zChf5bVDmptqLTb5EuXAm9rsnDYfTKhq7rDQujdn5WWzwUMeV3agaZ6J2vPQT58jJAJPi', + publicKeyHash: 'tz1KqTpEZ7Yob7QbPE4Hy4Wo8fHG8LhKxZSx', + seed: '', + storeType: StoreType.mnemonic, + ), + ); + print("sendOP ===> $sendOP"); + + //Sign operation with public-Key and forged operation + // List signOpGrp = await TezsterDart.signOperationGroup( + // privateKey: + // "edskRdVS5H9YCRAG8yqZkX2nUTbGcaDqjYgopkJwRuPUnYzCn3t9ZGksncTLYe33bFjq29pRhpvjQizCCzmugMGhJiXezixvdC", + // forgedOperation: + // "713cb068fe3ac078351727eb5c34279e22b75b0cf4dc0a8d3d599e27031db136040cb9f9da085607c05cac1ca4c62a3f3cfb8146aa9b7f631e52f877a1d363474404da8130b0b940ee", + // ); + // print("signOpGrp ==> $signOpGrp"); + + // dynamic getBlock = await TezsterNodeReader.getBlock( + // server: 'https://testnet.tezster.tech/', + // hash: "head", + // chainid: "NetXjD3HPJJjmcd", + // ); + // print("GET-Block ===> $getBlock"); + // String activationData = TezsterNodeWriter.forgeOperations( // branch: "BLjxPLCWUuFBewguqrojaHhgAcc8jLZneFkpnrVVcYn2zQz4pmW", // operation: activation, diff --git a/example/pubspec.lock b/example/pubspec.lock index 74a5013..2f14943 100644 --- a/example/pubspec.lock +++ b/example/pubspec.lock @@ -85,6 +85,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "0.1.3" + ed25519: + dependency: transitive + description: + name: ed25519 + url: "https://pub.dartlang.org" + source: hosted + version: "0.0.1" fixnum: dependency: transitive description: diff --git a/lib/src/tezsterNodeReader.dart b/lib/src/tezsterNodeReader.dart index 1f87782..9ada535 100644 --- a/lib/src/tezsterNodeReader.dart +++ b/lib/src/tezsterNodeReader.dart @@ -27,10 +27,12 @@ class TezsterNodeReader { server: server, command: "chains/$chainid/blocks/$hash", ); + + // print(response['hash']); return response; } - static dynamic getBlockHead({ + static Future getBlockHead({ String server, }) async { assert(server != null); @@ -71,11 +73,13 @@ class TezsterNodeReader { String chainid = "main", }) async { dynamic account = await performGetRequest( - server: server, - command: "chains/$chainid/blocks/head/context/contracts/$accountHash"); + server: server, + command: "chains/$chainid/blocks/head/context/contracts/$accountHash", + ); return int.parse(account["balance"], radix: 10); } + /// Testing is Done [getAccountManagerForBlock] static dynamic getAccountManagerForBlock({ String server, String block, @@ -115,16 +119,21 @@ class TezsterNodeReader { return false; } - static dynamic isManagerKeyRevealedForAccount({ + /// Testing done [isManagerKeyRevealedForAccount] + static Future isManagerKeyRevealedForAccount({ String server, String accountHash, }) async { - dynamic managerKey = await getAccountManagerForBlock( + bool isRevealed; + String managerKey = await getAccountManagerForBlock( server: server, block: "head", accountHash: accountHash, ); - return managerKey.toString().length > 0 ? true : false; + managerKey == null ? isRevealed = false : isRevealed = true; + + return isRevealed; + // return managerKey.length > 0 ? true : false; } static dynamic getContractStorage({ diff --git a/lib/src/tezsterNodeWriter.dart b/lib/src/tezsterNodeWriter.dart index 96722a7..bb55563 100644 --- a/lib/src/tezsterNodeWriter.dart +++ b/lib/src/tezsterNodeWriter.dart @@ -48,23 +48,30 @@ class TezsterNodeWriter { } static String _readSignatureWithHint(Uint8List payload, String hint) { - String encodedPayoad = hex.encode(payload); + List intConversionPayload = List.from(payload); + String encodedPayoad = hex.encode(intConversionPayload); String concatEncodedPayload = '09f5cd8612' + encodedPayoad; String encodedPayoadToHexString = hex.encode(concatEncodedPayload.codeUnits); Uint8List finlaListForBS58CHECK = hex.decode(encodedPayoadToHexString); + print(finlaListForBS58CHECK); if (hint == 'edsig') { - return bs58check.encode(finlaListForBS58CHECK); + String bs58checkVal = bs58check.encode(finlaListForBS58CHECK); + var encodedHex = hex.encode(bs58checkVal.codeUnits); + print(encodedHex); + return bs58checkVal; } else { throw {"message": "Unrecognized key hint, '$hint'"}; } } static Future _signDetach(Uint8List message, Uint8List sk) async { + print("message ===> $message"); + print("sk ===> $sk"); return Sodium.cryptoSignDetached(message, sk); } - static signOperationGroup({ + static Future signOperationGroup({ String forgedOperation, String derivationPath, String privateKey, @@ -82,11 +89,14 @@ class TezsterNodeWriter { // print("hashedWatermarkedOpBytes ===> ${hashedWatermarkedOpBytes.length}"); Uint8List privateKeyBytes = _writeKeyWithHint(privateKey, "edsk"); // print("bs58List ===> $privateKeyBytes"); + Uint8List opSignature = await _signDetach(hashedWatermarkedOpBytes, privateKeyBytes); - // print("opSignature ===> $opSignature"); + print("opSignature ===> $opSignature"); String hexString = _readSignatureWithHint(opSignature, 'edsig'); + // var data = hex.decode(hexString); + // print(data); // print("hexString ===> $hexString"); List listforgedOperation = hex.decode(forgedOperation); @@ -95,7 +105,7 @@ class TezsterNodeWriter { List signedOpBytes = uint8ListforgedOperation + opSignature; // print("signedOpBytes ===> $signedOpBytes"); - return [signedOpBytes, hexString]; + return SignedOperationGroup(bytes: signedOpBytes, signature: hexString); } // FORGED OPERATION GROUP @@ -246,7 +256,7 @@ class TezsterNodeWriter { hexString += writeInt(int.parse(transaction.gasLimit)); hexString += writeInt(int.parse(transaction.storageLimit)); hexString += writeInt(int.parse(transaction.amount)); - hexString += writeInt(int.parse(transaction.destination)); + // hexString += writeInt(int.parse(transaction.destination)); if (transaction.contractParameters != null) { ContractParameters composite = transaction.contractParameters; @@ -408,7 +418,7 @@ class TezsterNodeWriter { dynamic operation, }) { String encoded = _writeBranch(branch); - // print("encoded ===> $encoded"); + print("encoded ===> $encoded"); encoded += encodeOperationValue(operation); // print("encoded ===> $newEncode"); return encoded; @@ -480,7 +490,7 @@ class TezsterNodeWriter { } /// TODO : Send Transaction Operation - sendTransactionOperation({ + static sendTransactionOperation({ String server, KeyStore keyStore, String to, @@ -501,6 +511,7 @@ class TezsterNodeWriter { source: keyStore.publicKeyHash, ); + /// [appendRevealOperation] dynamic transactionOperation = await appendRevealOperation( server: server, keyStore: keyStore, @@ -508,32 +519,91 @@ class TezsterNodeWriter { accountOperationIndex: counter - 1, transactions: transaction, ); + print("transactionOperation ===> ${transactionOperation.source}"); - return transactionOperation; + return sendOperation( + server, transactionOperation, keyStore, derivationPath); } - sendOperation(String server, dynamic operations, dynamic keyStore, + static sendOperation(String server, dynamic operations, KeyStore keyStore, String derivationPath) async { var blockHead = await TezsterNodeReader.getBlockHead(server: server); + print("blockHead ===> ${blockHead['hash']}"); var forgedOperationGroup = - forgeOperations(branch: blockHead.hash, operation: operations); - var signedOpGroup = await signOperationGroup( + forgeOperations(branch: blockHead['hash'], operation: operations); + SignedOperationGroup signedOpGroup = await signOperationGroup( forgedOperation: forgedOperationGroup, privateKey: keyStore.privateKey, derivationPath: derivationPath, ); + print("signedOpGroup ===> ${signedOpGroup.signature}"); + + var injectedOperation = + await injectOperation(server: server, signedOpGroup: signedOpGroup); + + var appliedOp = await preapplyOperation( + server: server, + branch: blockHead['hash'], + protocol: blockHead['protocol'], + keyStore: keyStore, + signedOpGroup: signedOpGroup, + ); + print("appliedOp ===> $appliedOp"); + // server, blockHead.hash, blockHead.protocol, operations, signedOpGroup); /// TODO : Pending Task + return {"results": appliedOp[0], "operationGroupID": injectedOperation}; + } + + static Future injectOperation({ + String server, + SignedOperationGroup signedOpGroup, + String chainid = 'main', + }) { + var signedOpByteHex = hex.encode(signedOpGroup.bytes); + print("signedOpByteHex ===> $signedOpByteHex"); + var response = performPostRequest( + server: server, + command: "injection/operation?chain=$chainid", + payload: signedOpByteHex, + ); + print("response ===> $response"); + return response; + } + + static preapplyOperation({ + String server, + String branch, + String protocol, + KeyStore keyStore, + SignedOperationGroup signedOpGroup, + String chainid = 'main', + }) async { + List payload = [ + { + "protocol": protocol, + "branch": branch, + "contents": keyStore, + "signature": signedOpGroup.signature + } + ]; + var response = await performPostRequest( + server: server, + command: "chains/$chainid/blocks/head/helpers/preapply/operations", + payload: json.encode(payload), + ); + + return response; } - appendRevealOperation({ + static appendRevealOperation({ @required String server, @required dynamic keyStore, @required String accountHash, @required int accountOperationIndex, @required dynamic transactions, - }) { - dynamic isKeyRevealed = TezsterNodeReader.isManagerKeyRevealedForAccount( + }) async { + bool isKeyRevealed = await TezsterNodeReader.isManagerKeyRevealedForAccount( server: server, accountHash: accountHash); int counter = accountOperationIndex + 1; @@ -567,13 +637,40 @@ class KeyStore { String seed; String derivationPath; StoreType storeType = StoreType.mnemonic; - KeyStore( - {this.publicKey, - this.privateKey, - this.publicKeyHash, - this.seed, - this.derivationPath, - this.storeType}); + KeyStore({ + this.publicKey, + this.privateKey, + this.publicKeyHash, + this.seed, + this.derivationPath, + this.storeType, + }); + + KeyStore.fromJson(Map json) { + publicKey = json['publicKey']; + privateKey = json['privateKey']; + publicKeyHash = json['publicKeyHash']; + seed = json['seed']; + derivationPath = json['derivationPath']; + storeType = json['storeType']; + } + + Map toJson() { + final Map data = new Map(); + data['publicKey'] = this.publicKey; + data['privateKey'] = this.privateKey; + data['publicKeyHash'] = this.publicKeyHash; + data['seed'] = this.seed; + data['derivationPath'] = this.derivationPath; + data['storeType'] = this.storeType; + return data; + } +} + +class SignedOperationGroup { + List bytes; + String signature; + SignedOperationGroup({this.bytes, this.signature}); } class Activation { diff --git a/lib/src/tezsterSendOperation.dart b/lib/src/tezsterSendOperation.dart new file mode 100644 index 0000000..fedb2da --- /dev/null +++ b/lib/src/tezsterSendOperation.dart @@ -0,0 +1,469 @@ +import 'dart:convert'; +import 'dart:typed_data'; + +import 'package:blake2b/blake2b_hash.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_sodium/flutter_sodium.dart'; + +import '../tezster_dart.dart'; +// import 'package:blake2b/blake2b_hash.dart'; +// import 'package:flutter/material.dart'; +import 'package:bs58check/bs58check.dart' as bs58check; +// import 'package:flutter_sodium/flutter_sodium.dart'; +import 'package:convert/convert.dart'; +import 'package:http/http.dart' as http; +import 'package:tezster_dart/tezster_dart.dart'; + +class TezsterSendOperation { + static performPostRequest({ + String server, + String command, + Object payload, + }) async { + assert(server != null); + assert(command != null); + String url = '$server/$command'; + try { + String payloadString = jsonEncode(payload); + http.Response data = await http.post( + url, + body: payloadString, + headers: { + 'content-type': 'application/json', + }, + ); + return data; + } catch (e) { + return {"message": "Something went wrong"}; + } + } + + static String _writeBranch(String branch) { + Uint8List branchUint8List = bs58check.decode(branch).sublist(2); + String branchHexString = hex.encode(branchUint8List); + return branchHexString; + } + + static forgeOperations({ + String branch, + dynamic operation, + }) { + String encoded = _writeBranch(branch); + print("encoded ===> $encoded"); + encoded += encodeOperationValue(operation); + // print("encoded ===> $newEncode"); + return encoded; + } + + static String twoByteHex(int n) { + if (n < 128) { + String hexString = "0" + n.toRadixString(16); + return hexString.substring(hexString.length - 2); + } + + String h = ''; + + if (n > 2147483648) { + BigInt r = BigInt.from(n); + while (r > BigInt.zero) { + //Review + String data = ('0' + r.toRadixString(16) + 127.toRadixString(16)); + h = data.substring(data.length - 2) + h; + r = r >> 7; + } + } else { + int r = n; + while (r > 0) { + // Review + String data = ('0' + (r & 127).toRadixString(16)); + h = data.substring(data.length - 2) + h; + r = r >> 7; + } + } + return h; + } + + static String writeInt(int value) { + if (value < 0) { + return "Use writeSignedInt to encode negative numbers"; + } + + String twoByteHexString = twoByteHex(value); + print("twoByteHexString ==> $twoByteHexString"); + + List hexStringToList = hex.decode(twoByteHexString); + print("hexStringToList ===> $hexStringToList"); + + Uint8List twoByteUint8List = Uint8List.fromList(hexStringToList); + print("twoByteUint8List ===> $twoByteUint8List"); + + Map mapData = twoByteUint8List.asMap(); + print("mapData ===> $mapData"); + + List hexList = []; + + mapData.forEach((key, value) { + var hexValue = key == 0 ? value : value ^ 0x80; + print(key.toString() + " " + value.toString()); + print(hexValue); + hexList.add(hexValue); + }); + print("hexList ===> $hexList"); + + List reversedList = (hexList.reversed).toList(); + + Uint8List conversion = Uint8List.fromList((hexList.reversed).toList()); + print("conversion $conversion"); + + String reversedIntListDataToHex = hex.encode(reversedList); + print("reversedIntListDataToHex ===> $reversedIntListDataToHex"); + + return reversedIntListDataToHex; + } + + static Map sepyTnoitarepo = { + 'endorsement': 0, + 'seedNonceRevelation': 1, + 'doubleEndorsementEvidence': 2, + 'doubleBakingEvidence': 3, + 'accountActivation': 4, + 'proposal': 5, + 'ballot': 6, + 'reveal': 7, + 'transaction': 8, + 'origination': 9, + 'delegation': 10, + 'Newreveal': 107, + 'Newtransaction': 108, + 'Neworigination': 109, + 'Newdelegation': 110 + }; + + static String writeAddress(String address) { + Uint8List uintBsList = bs58check.decode(address).sublist(3); + // List bsList = List.from(uintBsList); + String hexString = hex.encode(uintBsList); + // print("hexString ===> $hexString"); + + if (address.startsWith("tz1")) { + return "0000" + hexString; + } else if (address.startsWith("tz2")) { + return "0001" + hexString; + } else if (address.startsWith("tz3")) { + return "0002" + hexString; + } else if (address.startsWith("KT1")) { + return "01" + hexString + "00"; + } else { + throw new ErrorDescription("Unrecognized address prefix: "); + } + } + + static String encodeTransaction(Transaction transaction) { + String hexString = writeInt(sepyTnoitarepo['transaction']); + hexString += writeAddress(transaction.source).substring(2); + hexString += writeInt(int.parse(transaction.fee)); + hexString += writeInt(int.parse(transaction.counter)); + hexString += writeInt(int.parse(transaction.gasLimit)); + hexString += writeInt(int.parse(transaction.storageLimit)); + hexString += writeInt(int.parse(transaction.amount)); + // hexString += writeInt(int.parse(transaction.destination)); + + if (transaction.contractParameters != null) { + ContractParameters composite = transaction.contractParameters; + + // TODO : TranslateMichelineToHex to be done + // String code = normalizeMichelineWhiteSpace(jsonEncode(composite.value)); + // String result = translateMichelineToHex(code); + String result = ""; + + if ((composite.entrypoint == 'default' || composite.entrypoint == '') && + result == '030b') { + hexString += '00'; + } else { + hexString += 'ff'; + + if (composite.entrypoint == 'default' || composite.entrypoint == '') { + hexString += '00'; + } else if (composite.entrypoint == 'root') { + hexString += '01'; + } else if (composite.entrypoint == 'do') { + hexString += '02'; + } else if (composite.entrypoint == 'set_delegate') { + hexString += '03'; + } else if (composite.entrypoint == 'remove_delegate') { + hexString += '04'; + } else { + hexString += 'ff' + + ('0' + composite.entrypoint.length.toRadixString(16)) + .substring(2) + + composite.entrypoint + .split('') + .map((c) => c.codeUnitAt(0).toRadixString(16)) + .join(); + } + + if (result == '030b') { + hexString += '00'; + } else { + int resultLengthDiv2 = int.parse((result.length / 2).toString()); + String data = ('0000000' + resultLengthDiv2.toRadixString(16)); + hexString += data.substring(data.length - 8) + result; + } + } + } else { + hexString += '00'; + } + + return hexString; + } + + static encodeOperationValue(operation) { + return encodeTransaction(Transaction( + amount: operation.amount, + counter: operation.counter, + destination: operation.destination, + contractParameters: operation.contractParameters, + fee: operation.fee, + gasLimit: operation.gasLimit, + source: operation.source, + storageLimit: operation.storageLimit, + )); + } + + static sendTransactionOperation({ + String server, + KeyStore keyStore, + String to, + int amount, + int fee, + String derivationPath = '', + }) async { + dynamic counter = await TezsterNodeReader.getCounterForAccount( + server: server, accountHash: keyStore.publicKeyHash) + + 1; + + Transaction transaction = Transaction( + destination: to, + amount: amount.toString(), + storageLimit: 496.toString(), + gasLimit: 10600.toString(), + counter: counter.toString(), + fee: fee.toString(), + source: keyStore.publicKeyHash, + ); + + /// [appendRevealOperation] + dynamic transactionOperation = await appendRevealOperation( + server: server, + keyStore: keyStore, + accountHash: keyStore.publicKeyHash, + accountOperationIndex: counter - 1, + transactions: transaction, + ); + print("transactionOperation ===> ${transactionOperation.source}"); + + return sendOperation( + server, transactionOperation, keyStore, derivationPath); + } + + static sendOperation(String server, Transaction operations, KeyStore keyStore, + String derivationPath) async { + var blockHead = await TezsterNodeReader.getBlockHead(server: server); + print("blockHead ===> ${blockHead['hash']}"); + var forgedOperationGroup = + forgeOperations(branch: blockHead['hash'], operation: operations); + SignedOperationGroup signedOpGroup = await signOperationGroup( + forgedOperation: forgedOperationGroup, + privateKey: keyStore.privateKey, + derivationPath: derivationPath, + ); + print("signedOpGroup ===> ${signedOpGroup.signature}"); + + var injectedOperation = + await injectOperation(server: server, signedOpGroup: signedOpGroup); + print("injectedOperation ===> $injectedOperation"); + var appliedOp = await preapplyOperation( + server: server, + branch: blockHead['hash'], + protocol: blockHead['protocol'], + keyStore: keyStore, + signedOpGroup: signedOpGroup, + ); + print("appliedOp ===> $appliedOp"); + // server, blockHead.hash, blockHead.protocol, operations, signedOpGroup); + + /// TODO : Pending Task + /// "results": appliedOp[0], + return {"operationGroupID": injectedOperation}; + } + + static Future signOperationGroup({ + String forgedOperation, + String derivationPath, + String privateKey, + }) async { + assert(forgedOperation != null); + assert(privateKey != null); + + String watermarkedForgedOperationBytesHex = '03' + forgedOperation; + List hexStringToListOfInt = + hex.decode(watermarkedForgedOperationBytesHex); + Uint8List hashedWatermarkedOpBytes = + Blake2bHash.hashWithDigestSize(256, hexStringToListOfInt); + Uint8List privateKeyBytes = bs58check.decode(privateKey); + List pkB = List.from(privateKeyBytes); + pkB.removeRange(0, 4); + Uint8List finalPKb = Uint8List.fromList(pkB); + Uint8List value = await Sodium.cryptoSignDetached( + hashedWatermarkedOpBytes, + finalPKb, + useBackgroundThread: false, + ); + String opSignatureHex = hex.encode(value); + String hexStringToEncode = '09f5cd8612' + opSignatureHex; + Uint8List hexDeco = hex.decode(hexStringToEncode); + String hexSignature = bs58check.encode(hexDeco); + String signedOpBytes = forgedOperation + opSignatureHex; + List signedOpBytestoList = hex.decode(signedOpBytes); + return SignedOperationGroup( + bytes: signedOpBytestoList, signature: hexSignature); + + // String watermarkedForgedOperationBytesHex = "03" + forgedOperation; + // String stringToHexString = + // hex.encode(watermarkedForgedOperationBytesHex.codeUnits); + // // print(stringToHexString); + // List hexStringToListOfInt = hex.decode(stringToHexString); + // // print(hexStringToListOfInt); + // Uint8List hashedWatermarkedOpBytes = _simpleHash(hexStringToListOfInt, 256); + // print("hashedWatermarkedOpBytes ===> $hashedWatermarkedOpBytes"); + // print("hashedWatermarkedOpBytes ===> ${hashedWatermarkedOpBytes.length}"); + // Uint8List privateKeyBytes = _writeKeyWithHint(privateKey, "edsk"); + // // print("bs58List ===> $privateKeyBytes"); + + // Uint8List opSignature = + // await _signDetach(hashedWatermarkedOpBytes, privateKeyBytes); + // print("opSignature ===> $opSignature"); + + // String hexString = _readSignatureWithHint(opSignature, 'edsig'); + // print("hexString ===> $hexString"); + + // List listforgedOperation = hex.decode(forgedOperation); + // Uint8List uint8ListforgedOperation = + // Uint8List.fromList(listforgedOperation); + // List signedOpBytes = uint8ListforgedOperation + opSignature; + // print("signedOpBytes ===> $signedOpBytes"); + + // return SignedOperationGroup(bytes: signedOpBytes, signature: hexString); + } + + static preapplyOperation({ + String server, + String branch, + String protocol, + KeyStore keyStore, + SignedOperationGroup signedOpGroup, + String chainid = 'main', + }) async { + print(json.encode(keyStore.toJson()).toString()); + List payload = [ + { + "protocol": protocol, + "branch": branch, + "contents": [keyStore.toJson()], + "signature": signedOpGroup.signature + } + ]; + var response = await performPostRequest( + server: server, + command: "chains/$chainid/blocks/head/helpers/preapply/operations", + payload: json.encode(payload), + ); + + return response; + } + + /// TODO: pending + static Future injectOperation({ + String server, + SignedOperationGroup signedOpGroup, + String chainid = 'main', + }) { + String signedOpByteHex = hex.encode(signedOpGroup.bytes); + print("signedOpByteHex ===> $signedOpByteHex"); + var response = performPostRequest( + server: server, + command: "injection/operation?chain=$chainid", + payload: signedOpByteHex, + ); + print("response ===> $response"); + return response; + } + + static appendRevealOperation({ + String server, + dynamic keyStore, + String accountHash, + int accountOperationIndex, + dynamic transactions, + }) async { + bool isKeyRevealed = await TezsterNodeReader.isManagerKeyRevealedForAccount( + server: server, accountHash: accountHash); + int counter = accountOperationIndex + 1; + + if (!isKeyRevealed) { + Reveal revealOp = Reveal( + source: accountHash, + fee: '0', + counter: counter.toString(), + gasLimit: '10600', + storageLimit: '0', + publicKey: keyStore.publicKey, + ); + + transactions.forEach((transaction, i) { + var c = accountOperationIndex + 2 + i; + transaction.counter = c.toString(); + }); + + return [revealOp, ...transactions]; + } + return transactions; + } +} + +// static Uint8List _simpleHash(Uint8List payload, int digestSize) { +// return Blake2bHash.hashWithDigestSize(digestSize, payload); +// } + +// static Uint8List _writeKeyWithHint(String key, String hint) { +// if (hint == "edsk" || hint == "edpk") { +// return bs58check.decode(key).sublist(0, 64); +// } else { +// throw {"message": "Unrecognized key hint, '$hint'"}; +// } +// } + +// static Future _signDetach(Uint8List message, Uint8List sk) async { +// return Sodium.cryptoSignDetached(message, sk); +// } + +// static String _readSignatureWithHint(Uint8List payload, String hint) { +// List intConversionPayload = List.from(payload); +// String encodedPayoad = hex.encode(intConversionPayload); +// // String concatEncodedPayload = '09f5cd8612' + encodedPayoad; +// String concatEncodedPayload = '09f5cd8612'; + +// // String encodedPayoadToHexString = +// // hex.encode(concatEncodedPayload.codeUnits); +// Uint8List finlaListForBS58CHECK = hex.decode(concatEncodedPayload); +// // Uint8List finlaListForBS58CHECK = hex.decode(encodedPayoadToHexString); + +// print(finlaListForBS58CHECK); +// if (hint == 'edsig') { +// String bs58checkVal = bs58check.encode(finlaListForBS58CHECK); + +// return bs58checkVal; +// } else { +// throw {"message": "Unrecognized key hint, '$hint'"}; +// } +// } diff --git a/lib/tezster_dart.dart b/lib/tezster_dart.dart index 9c25897..60be5c1 100644 --- a/lib/tezster_dart.dart +++ b/lib/tezster_dart.dart @@ -3,6 +3,7 @@ library tezster_dart; export 'src/tezster_dart.dart'; export 'src/tezsterNodeReader.dart'; export 'src/tezsterNodeWriter.dart'; +export 'src/tezsterSendOperation.dart'; // import 'dart:async'; // import 'dart:convert'; diff --git a/pubspec.lock b/pubspec.lock index 7c5c865..6a5bade 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -78,6 +78,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "2.1.4" + ed25519: + dependency: "direct main" + description: + name: ed25519 + url: "https://pub.dartlang.org" + source: hosted + version: "0.0.1" fixnum: dependency: transitive description: diff --git a/pubspec.yaml b/pubspec.yaml index 386d237..e52ea5f 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -22,6 +22,7 @@ dependencies: convert: ^2.1.1 http: ^0.12.1 js: ^0.6.2 + ed25519: ^0.0.1 dev_dependencies: flutter_test: From 2e2dd5b7f8482e11c2a6ef98c6e90f4c2535c943 Mon Sep 17 00:00:00 2001 From: Rakshak1344 Date: Tue, 8 Sep 2020 21:52:36 +0530 Subject: [PATCH 07/12] issue sendTransactionOperation --- example/lib/main.dart | 6 +- lib/src/tezsterNodeWriter.dart | 2 +- lib/src/tezsterSendOperation.dart | 167 +++++++++++++++++++----------- 3 files changed, 109 insertions(+), 66 deletions(-) diff --git a/example/lib/main.dart b/example/lib/main.dart index 3b53f16..7776e88 100644 --- a/example/lib/main.dart +++ b/example/lib/main.dart @@ -218,10 +218,10 @@ class _MyAppState extends State { to: 'tz1PrMATKhpXz81CnEZL2sudhVmhbz8W7Lm5', derivationPath: "", keyStore: KeyStore( - publicKey: 'edpkuBknW28nW72KG6RoHtYW7p12T6GKc7nAbwYX5m8Wd9sDVC9yav', + publicKey: 'edpktyB3RAiSjcwxtH6rroVgZmwDUGRtEJt1cjj4yk67munxciGcn7', privateKey: - 'edskRuR1azSfboG86YPTyxrQgosh5zChf5bVDmptqLTb5EuXAm9rsnDYfTKhq7rDQujdn5WWzwUMeV3agaZ6J2vPQT58jJAJPi', - publicKeyHash: 'tz1KqTpEZ7Yob7QbPE4Hy4Wo8fHG8LhKxZSx', + 'edskRdeVDqUZtg6MXc8rpR8cQ9yEHCjGxjMtFQGmqYbYXQcDzuefUX2mh7AYunnwqaYf4oNGMT1Y9w9xvL2aZjth3GdriJFPQ5', + publicKeyHash: 'tz1MXeJCqZMam9698kyQapZNkQ1Bvdfu8uza', seed: '', storeType: StoreType.mnemonic, ), diff --git a/lib/src/tezsterNodeWriter.dart b/lib/src/tezsterNodeWriter.dart index bb55563..4d6dcc7 100644 --- a/lib/src/tezsterNodeWriter.dart +++ b/lib/src/tezsterNodeWriter.dart @@ -668,7 +668,7 @@ class KeyStore { } class SignedOperationGroup { - List bytes; + List bytes; String signature; SignedOperationGroup({this.bytes, this.signature}); } diff --git a/lib/src/tezsterSendOperation.dart b/lib/src/tezsterSendOperation.dart index fedb2da..4430e5c 100644 --- a/lib/src/tezsterSendOperation.dart +++ b/lib/src/tezsterSendOperation.dart @@ -166,7 +166,7 @@ class TezsterSendOperation { hexString += writeInt(int.parse(transaction.gasLimit)); hexString += writeInt(int.parse(transaction.storageLimit)); hexString += writeInt(int.parse(transaction.amount)); - // hexString += writeInt(int.parse(transaction.destination)); + hexString += writeAddress(transaction.destination); if (transaction.contractParameters != null) { ContractParameters composite = transaction.contractParameters; @@ -279,18 +279,18 @@ class TezsterSendOperation { ); print("signedOpGroup ===> ${signedOpGroup.signature}"); - var injectedOperation = - await injectOperation(server: server, signedOpGroup: signedOpGroup); - print("injectedOperation ===> $injectedOperation"); var appliedOp = await preapplyOperation( server: server, branch: blockHead['hash'], protocol: blockHead['protocol'], - keyStore: keyStore, + transaction: operations, signedOpGroup: signedOpGroup, ); - print("appliedOp ===> $appliedOp"); - // server, blockHead.hash, blockHead.protocol, operations, signedOpGroup); + print("appliedOp ===> ${appliedOp.body.toString()}"); + + var injectedOperation = + await injectOperation(server: server, signedOpGroup: signedOpGroup); + print("injectedOperation ===> $injectedOperation"); /// TODO : Pending Task /// "results": appliedOp[0], @@ -306,28 +306,57 @@ class TezsterSendOperation { assert(privateKey != null); String watermarkedForgedOperationBytesHex = '03' + forgedOperation; - List hexStringToListOfInt = + + /// converting String to HexString [waterMarkHexIntList] + List waterMarkHexIntList = hex.decode(watermarkedForgedOperationBytesHex); - Uint8List hashedWatermarkedOpBytes = - Blake2bHash.hashWithDigestSize(256, hexStringToListOfInt); - Uint8List privateKeyBytes = bs58check.decode(privateKey); - List pkB = List.from(privateKeyBytes); - pkB.removeRange(0, 4); - Uint8List finalPKb = Uint8List.fromList(pkB); - Uint8List value = await Sodium.cryptoSignDetached( - hashedWatermarkedOpBytes, - finalPKb, - useBackgroundThread: false, - ); - String opSignatureHex = hex.encode(value); - String hexStringToEncode = '09f5cd8612' + opSignatureHex; - Uint8List hexDeco = hex.decode(hexStringToEncode); - String hexSignature = bs58check.encode(hexDeco); - String signedOpBytes = forgedOperation + opSignatureHex; - List signedOpBytestoList = hex.decode(signedOpBytes); - return SignedOperationGroup( - bytes: signedOpBytestoList, signature: hexSignature); + /// converting List [waterMarkHexIntList] to Uint8List [waterMarkHexUint8List] + Uint8List waterMarkHexUint8List = Uint8List.fromList(waterMarkHexIntList); + + Uint8List hashedWatermarkedOpBytes = + await _simpleHash(waterMarkHexUint8List, 32); + Uint8List privateKeyBytes = _writeKeyWithHint(privateKey, "edsk"); + print("bs58List ===> $privateKeyBytes"); + Uint8List opSignature = await Sodium.cryptoSignDetached( + hashedWatermarkedOpBytes, privateKeyBytes); + print("opSignature ===> $opSignature"); + + String hexSignature = _readSignatureWithHint(opSignature, 'edsig'); + print("hexString ===> $hexSignature"); + + List forgedOperationListInt = hex.decode(forgedOperation); + Uint8List forgedOperationUint8List = + Uint8List.fromList(forgedOperationListInt); + + List signedOpBytes = forgedOperationUint8List + opSignature; + + return SignedOperationGroup(bytes: signedOpBytes, signature: hexSignature); + +// Trial 2 + // List hexStringToListOfInt = + // hex.decode(watermarkedForgedOperationBytesHex); + // Uint8List hashedWatermarkedOpBytes = + // Blake2bHash.hashWithDigestSize(256, hexStringToListOfInt); + // Uint8List privateKeyBytes = bs58check.decode(privateKey); + // List pkB = List.from(privateKeyBytes); + // pkB.removeRange(0, 4); + // Uint8List finalPKb = Uint8List.fromList(pkB); + // Uint8List value = await Sodium.cryptoSignDetached( + // hashedWatermarkedOpBytes, + // finalPKb, + // useBackgroundThread: false, + // ); + // String opSignatureHex = hex.encode(value); + // String hexStringToEncode = '09f5cd8612' + opSignatureHex; + // Uint8List hexDeco = hex.decode(hexStringToEncode); + // String hexSignature = bs58check.encode(hexDeco); + // String signedOpBytes = forgedOperation + opSignatureHex; + // List signedOpBytestoList = hex.decode(signedOpBytes); + // return SignedOperationGroup( + // bytes: signedOpBytestoList, signature: hexSignature); + + /// Trial 1 // String watermarkedForgedOperationBytesHex = "03" + forgedOperation; // String stringToHexString = // hex.encode(watermarkedForgedOperationBytesHex.codeUnits); @@ -338,7 +367,7 @@ class TezsterSendOperation { // print("hashedWatermarkedOpBytes ===> $hashedWatermarkedOpBytes"); // print("hashedWatermarkedOpBytes ===> ${hashedWatermarkedOpBytes.length}"); // Uint8List privateKeyBytes = _writeKeyWithHint(privateKey, "edsk"); - // // print("bs58List ===> $privateKeyBytes"); + // print("bs58List ===> $privateKeyBytes"); // Uint8List opSignature = // await _signDetach(hashedWatermarkedOpBytes, privateKeyBytes); @@ -360,23 +389,34 @@ class TezsterSendOperation { String server, String branch, String protocol, - KeyStore keyStore, + Transaction transaction, SignedOperationGroup signedOpGroup, String chainid = 'main', }) async { - print(json.encode(keyStore.toJson()).toString()); List payload = [ { "protocol": protocol, "branch": branch, - "contents": [keyStore.toJson()], + "contents": [ + { + "kind": "transaction", + "source": transaction.source, + "fee": transaction.fee, + "counter": transaction.counter, + "gas_limit": transaction.gasLimit, + "storage_limit": transaction.storageLimit, + "amount": transaction.amount, + "destination": transaction.destination, + } + ], "signature": signedOpGroup.signature } ]; + print(json.encode(payload).toString()); var response = await performPostRequest( server: server, command: "chains/$chainid/blocks/head/helpers/preapply/operations", - payload: json.encode(payload), + payload: payload, ); return response; @@ -431,39 +471,42 @@ class TezsterSendOperation { } } -// static Uint8List _simpleHash(Uint8List payload, int digestSize) { -// return Blake2bHash.hashWithDigestSize(digestSize, payload); -// } +Future _simpleHash(Uint8List payload, int digestSize) async { + return await Sodium.cryptoGenerichash(digestSize, payload, null); + // return Blake2bHash.hashWithDigestSize(digestSize, payload); +} -// static Uint8List _writeKeyWithHint(String key, String hint) { -// if (hint == "edsk" || hint == "edpk") { -// return bs58check.decode(key).sublist(0, 64); -// } else { -// throw {"message": "Unrecognized key hint, '$hint'"}; -// } -// } +Uint8List _writeKeyWithHint(String key, String hint) { + if (hint == "edsk" || hint == "edpk") { + return bs58check.decode(key).sublist(4); + } else { + throw {"message": "Unrecognized key hint, '$hint'"}; + } +} // static Future _signDetach(Uint8List message, Uint8List sk) async { // return Sodium.cryptoSignDetached(message, sk); // } -// static String _readSignatureWithHint(Uint8List payload, String hint) { -// List intConversionPayload = List.from(payload); -// String encodedPayoad = hex.encode(intConversionPayload); -// // String concatEncodedPayload = '09f5cd8612' + encodedPayoad; -// String concatEncodedPayload = '09f5cd8612'; - -// // String encodedPayoadToHexString = -// // hex.encode(concatEncodedPayload.codeUnits); -// Uint8List finlaListForBS58CHECK = hex.decode(concatEncodedPayload); -// // Uint8List finlaListForBS58CHECK = hex.decode(encodedPayoadToHexString); - -// print(finlaListForBS58CHECK); -// if (hint == 'edsig') { -// String bs58checkVal = bs58check.encode(finlaListForBS58CHECK); - -// return bs58checkVal; -// } else { -// throw {"message": "Unrecognized key hint, '$hint'"}; -// } -// } +String _readSignatureWithHint(Uint8List payload, String hint) { + // String encodedPayoadToHexString = + // hex.encode(concatEncodedPayload.codeUnits); + // Uint8List finlaListForBS58CHECK = hex.decode(concatEncodedPayload); + // Uint8List finlaListForBS58CHECK = hex.decode(encodedPayoadToHexString); + + // print(finlaListForBS58CHECK); + if (hint == 'edsig') { + List intConversionPayload = List.from(payload); + String encodedPayoad = hex.encode(intConversionPayload); + // String concatEncodedPayload = '09f5cd8612' + encodedPayoad; + String concatEncodedPayload = '09f5cd8612' + encodedPayoad; + + List hexPayloadListInt = hex.decode(concatEncodedPayload); + Uint8List finalHexPayloadUint8ListInt = + Uint8List.fromList(hexPayloadListInt); + + return bs58check.encode(finalHexPayloadUint8ListInt); + } else { + throw {"message": "Unrecognized key hint, '$hint'"}; + } +} From 75fed9392fcd482cad98a454fe965fbf077e52e9 Mon Sep 17 00:00:00 2001 From: Rakshak1344 Date: Mon, 14 Sep 2020 12:17:51 +0530 Subject: [PATCH 08/12] inputs changed in sendsendTransactionOperation --- example/lib/main.dart | 22 +++++++++++++++------- lib/src/tezsterSendOperation.dart | 23 ++++++++++++----------- 2 files changed, 27 insertions(+), 18 deletions(-) diff --git a/example/lib/main.dart b/example/lib/main.dart index 7776e88..c20e7ab 100644 --- a/example/lib/main.dart +++ b/example/lib/main.dart @@ -212,22 +212,30 @@ class _MyAppState extends State { ); var sendOP = TezsterSendOperation.sendTransactionOperation( - server: 'https://testnet.tezster.tech/', - amount: 10, - fee: 2, - to: 'tz1PrMATKhpXz81CnEZL2sudhVmhbz8W7Lm5', + server: 'https://testnet.tezster.tech', + amount: 1000000, + fee: 100000, + to: 'tz1fX6A2miVXjNyReg2dpt2TsXLkZ4w7zRGa', derivationPath: "", keyStore: KeyStore( - publicKey: 'edpktyB3RAiSjcwxtH6rroVgZmwDUGRtEJt1cjj4yk67munxciGcn7', + publicKey: 'edpkv3azzeq9vL869TujYhdQY5FKiQH4CGwJEzqG7m6PoX7VEpdPc9', privateKey: - 'edskRdeVDqUZtg6MXc8rpR8cQ9yEHCjGxjMtFQGmqYbYXQcDzuefUX2mh7AYunnwqaYf4oNGMT1Y9w9xvL2aZjth3GdriJFPQ5', - publicKeyHash: 'tz1MXeJCqZMam9698kyQapZNkQ1Bvdfu8uza', + 'edskS5owtVaAtWifnCNo8tUpAw2535AXEDY4RXBRV1NHbQ58RDdpaWz2KyrvFXE4SuCTbHU8exUecW33GRqkAfLeNLBS5sPyoi', + publicKeyHash: 'tz1hcXqtiMYFhvuirD4guE7ts4yDuCAmtD95', seed: '', storeType: StoreType.mnemonic, ), ); print("sendOP ===> $sendOP"); + // { + // sk: + // 'edskRuR1azSfboG86YPTyxrQgosh5zChf5bVDmptqLTb5EuXAm9rsnDYfTKhq7rDQujdn5WWzwUMeV3agaZ6J2vPQT58jJAJPi', + // pk: 'edpkuBknW28nW72KG6RoHtYW7p12T6GKc7nAbwYX5m8Wd9sDVC9yav', + // pkh: 'tz1KqTpEZ7Yob7QbPE4Hy4Wo8fHG8LhKxZSx', + // label: 'bootstrap1', + // } + //Sign operation with public-Key and forged operation // List signOpGrp = await TezsterDart.signOperationGroup( // privateKey: diff --git a/lib/src/tezsterSendOperation.dart b/lib/src/tezsterSendOperation.dart index 4430e5c..7a62dce 100644 --- a/lib/src/tezsterSendOperation.dart +++ b/lib/src/tezsterSendOperation.dart @@ -39,8 +39,10 @@ class TezsterSendOperation { } static String _writeBranch(String branch) { - Uint8List branchUint8List = bs58check.decode(branch).sublist(2); - String branchHexString = hex.encode(branchUint8List); + Uint8List branchUint8List = bs58check.decode(branch); + branchUint8List.sublist(2); + List branchListInt = List.from(branchUint8List); + String branchHexString = hex.encode(branchListInt); return branchHexString; } @@ -112,10 +114,11 @@ class TezsterSendOperation { List reversedList = (hexList.reversed).toList(); - Uint8List conversion = Uint8List.fromList((hexList.reversed).toList()); + Uint8List conversion = Uint8List.fromList(reversedList); print("conversion $conversion"); - String reversedIntListDataToHex = hex.encode(reversedList); + // String reversedIntListDataToHex = hex.encode(reversedList); + String reversedIntListDataToHex = hex.encode(conversion); print("reversedIntListDataToHex ===> $reversedIntListDataToHex"); return reversedIntListDataToHex; @@ -140,6 +143,7 @@ class TezsterSendOperation { }; static String writeAddress(String address) { + print("address ===> $address"); Uint8List uintBsList = bs58check.decode(address).sublist(3); // List bsList = List.from(uintBsList); String hexString = hex.encode(uintBsList); @@ -241,6 +245,7 @@ class TezsterSendOperation { dynamic counter = await TezsterNodeReader.getCounterForAccount( server: server, accountHash: keyStore.publicKeyHash) + 1; + print("counter ===> $counter"); Transaction transaction = Transaction( destination: to, @@ -256,6 +261,7 @@ class TezsterSendOperation { dynamic transactionOperation = await appendRevealOperation( server: server, keyStore: keyStore, + // accountHash: "tz1LoKbFyYHTkCnj9mgRKFb9g8pP4Lr3zniP", accountHash: keyStore.publicKeyHash, accountOperationIndex: counter - 1, transactions: transaction, @@ -272,6 +278,7 @@ class TezsterSendOperation { print("blockHead ===> ${blockHead['hash']}"); var forgedOperationGroup = forgeOperations(branch: blockHead['hash'], operation: operations); + print("forgedOperationGroup ==> $forgedOperationGroup"); SignedOperationGroup signedOpGroup = await signOperationGroup( forgedOperation: forgedOperationGroup, privateKey: keyStore.privateKey, @@ -317,6 +324,7 @@ class TezsterSendOperation { Uint8List hashedWatermarkedOpBytes = await _simpleHash(waterMarkHexUint8List, 32); Uint8List privateKeyBytes = _writeKeyWithHint(privateKey, "edsk"); + print("bs58List ===> $privateKeyBytes"); Uint8List opSignature = await Sodium.cryptoSignDetached( hashedWatermarkedOpBytes, privateKeyBytes); @@ -489,16 +497,9 @@ Uint8List _writeKeyWithHint(String key, String hint) { // } String _readSignatureWithHint(Uint8List payload, String hint) { - // String encodedPayoadToHexString = - // hex.encode(concatEncodedPayload.codeUnits); - // Uint8List finlaListForBS58CHECK = hex.decode(concatEncodedPayload); - // Uint8List finlaListForBS58CHECK = hex.decode(encodedPayoadToHexString); - - // print(finlaListForBS58CHECK); if (hint == 'edsig') { List intConversionPayload = List.from(payload); String encodedPayoad = hex.encode(intConversionPayload); - // String concatEncodedPayload = '09f5cd8612' + encodedPayoad; String concatEncodedPayload = '09f5cd8612' + encodedPayoad; List hexPayloadListInt = hex.decode(concatEncodedPayload); From ce2492b1504b11e092cfc38c60cd6ce8dd4ee694 Mon Sep 17 00:00:00 2001 From: Rakshak1344 Date: Mon, 21 Sep 2020 16:34:58 +0530 Subject: [PATCH 09/12] resolved signature --- example/lib/main.dart | 12 ++-- lib/src/tezsterSendOperation.dart | 115 +++++++++++++++++++++++++----- 2 files changed, 104 insertions(+), 23 deletions(-) diff --git a/example/lib/main.dart b/example/lib/main.dart index c20e7ab..7f6421d 100644 --- a/example/lib/main.dart +++ b/example/lib/main.dart @@ -215,15 +215,15 @@ class _MyAppState extends State { server: 'https://testnet.tezster.tech', amount: 1000000, fee: 100000, - to: 'tz1fX6A2miVXjNyReg2dpt2TsXLkZ4w7zRGa', - derivationPath: "", + to: 'tz1a4UNywaxaAfh2LRBP2UugQTeCVcLCn5Sa', + derivationPath: '', keyStore: KeyStore( - publicKey: 'edpkv3azzeq9vL869TujYhdQY5FKiQH4CGwJEzqG7m6PoX7VEpdPc9', + publicKey: 'edpkvaUDxsbgxQwXKFph4SUz7HawNnKMG2ESHcTPkYkQXwKRdpz5tm', privateKey: - 'edskS5owtVaAtWifnCNo8tUpAw2535AXEDY4RXBRV1NHbQ58RDdpaWz2KyrvFXE4SuCTbHU8exUecW33GRqkAfLeNLBS5sPyoi', - publicKeyHash: 'tz1hcXqtiMYFhvuirD4guE7ts4yDuCAmtD95', + 'edskRoBCkDEhPzHHoXH5wtSf2LZGVe9z2AiLGNdvY7QFXVJxN62ZvW9LThG3vzMVgcuesDRDr5VSGPQqEW5ky3Te6eNfAbX8eh', + publicKeyHash: 'tz1Sr4tBA28P2QsEM7zpVUM41PSza5R1hFEz', seed: '', - storeType: StoreType.mnemonic, + storeType: StoreType.fundraiser, ), ); print("sendOP ===> $sendOP"); diff --git a/lib/src/tezsterSendOperation.dart b/lib/src/tezsterSendOperation.dart index 7a62dce..618125f 100644 --- a/lib/src/tezsterSendOperation.dart +++ b/lib/src/tezsterSendOperation.dart @@ -1,4 +1,5 @@ import 'dart:convert'; +import 'dart:ffi'; import 'dart:typed_data'; import 'package:blake2b/blake2b_hash.dart'; @@ -222,16 +223,27 @@ class TezsterSendOperation { } static encodeOperationValue(operation) { - return encodeTransaction(Transaction( - amount: operation.amount, - counter: operation.counter, - destination: operation.destination, - contractParameters: operation.contractParameters, - fee: operation.fee, - gasLimit: operation.gasLimit, - source: operation.source, - storageLimit: operation.storageLimit, - )); + if (operation is Reveal) { + return encodeReveal(Reveal( + source: operation.source, + fee: operation.fee, + counter: operation.counter, + gasLimit: operation.gasLimit, + storageLimit: operation.storageLimit, + publicKey: operation.publicKey, + )); + } else if (operation is Transaction) { + return encodeTransaction(Transaction( + amount: operation.amount, + counter: operation.counter, + destination: operation.destination, + contractParameters: operation.contractParameters, + fee: operation.fee, + gasLimit: operation.gasLimit, + source: operation.source, + storageLimit: operation.storageLimit, + )); + } } static sendTransactionOperation({ @@ -266,6 +278,7 @@ class TezsterSendOperation { accountOperationIndex: counter - 1, transactions: transaction, ); + print("transactionOperation ===> ${transactionOperation.source}"); return sendOperation( @@ -279,6 +292,9 @@ class TezsterSendOperation { var forgedOperationGroup = forgeOperations(branch: blockHead['hash'], operation: operations); print("forgedOperationGroup ==> $forgedOperationGroup"); + // var revealforgedOperationGroup = + // forgeOperations(branch: blockHead['head'], operation: revealOp); + // print("revealforgedOperationGroup ===> $revealforgedOperationGroup"); SignedOperationGroup signedOpGroup = await signOperationGroup( forgedOperation: forgedOperationGroup, privateKey: keyStore.privateKey, @@ -291,6 +307,7 @@ class TezsterSendOperation { branch: blockHead['hash'], protocol: blockHead['protocol'], transaction: operations, + keyStore: keyStore, signedOpGroup: signedOpGroup, ); print("appliedOp ===> ${appliedOp.body.toString()}"); @@ -322,10 +339,12 @@ class TezsterSendOperation { Uint8List waterMarkHexUint8List = Uint8List.fromList(waterMarkHexIntList); Uint8List hashedWatermarkedOpBytes = - await _simpleHash(waterMarkHexUint8List, 32); + await _simpleHash(waterMarkHexUint8List, 256); Uint8List privateKeyBytes = _writeKeyWithHint(privateKey, "edsk"); + print("bs58List ===> ${privateKeyBytes.length}"); + + // Uint8List hashedWatermarkedOpBytesstring = await _simpleHash(privateKeyBytes,256); - print("bs58List ===> $privateKeyBytes"); Uint8List opSignature = await Sodium.cryptoSignDetached( hashedWatermarkedOpBytes, privateKeyBytes); print("opSignature ===> $opSignature"); @@ -398,14 +417,39 @@ class TezsterSendOperation { String branch, String protocol, Transaction transaction, + KeyStore keyStore, SignedOperationGroup signedOpGroup, String chainid = 'main', }) async { + // Reveal revealOp = Reveal( + // counter: transaction.counter.toString(), + // fee: "0", + // gasLimit: 10600.toString(), + // source: keyStore.publicKeyHash, + // storageLimit: "0", + // publicKey: keyStore.publicKey, + // ); + // dynamic counter = await TezsterNodeReader.getCounterForAccount( + // server: server, accountHash: keyStore.publicKeyHash) + + // 1; + // print("counter ===> $counter"); + + // var counterVal = int.parse(counter); + List payload = [ { "protocol": protocol, "branch": branch, "contents": [ + // { + // "kind": "reveal", + // "source": keyStore.publicKeyHash, + // "fee": "0", + // "counter": counter.toString(), + // "gas_limit": 10600.toString(), + // "storage_limit": "0", + // "public_key": keyStore.publicKey + // }, { "kind": "transaction", "source": transaction.source, @@ -447,6 +491,32 @@ class TezsterSendOperation { return response; } + static writePublicKey(String publicKey) { + String _decodeAndAdd(String number) { + Uint8List publicKeyList = bs58check.decode(publicKey).sublist(4); + return number + hex.encode(publicKeyList); + } + + if (publicKey.startsWith("edpk")) { + return _decodeAndAdd("00"); + } else if (publicKey.startsWith("sppk")) { + return _decodeAndAdd("01"); + } else if (publicKey.startsWith("p2pk")) { + return _decodeAndAdd("02"); + } + } + + static String encodeReveal(Reveal reveal) { + String hexString = writeInt(sepyTnoitarepo['reveal']); + hexString += writeAddress(reveal.source).substring(2); + hexString += writeInt(int.parse(reveal.fee)); + hexString += writeInt(int.parse(reveal.counter)); + hexString += writeInt(int.parse(reveal.gasLimit)); + hexString += writeInt(int.parse(reveal.storageLimit)); + hexString += writePublicKey(reveal.publicKey); + return hexString; + } + static appendRevealOperation({ String server, dynamic keyStore, @@ -480,13 +550,25 @@ class TezsterSendOperation { } Future _simpleHash(Uint8List payload, int digestSize) async { - return await Sodium.cryptoGenerichash(digestSize, payload, null); - // return Blake2bHash.hashWithDigestSize(digestSize, payload); + // return await Sodium.cryptoGenerichash(digestSize, payload, null); + return Blake2bHash.hashWithDigestSize(digestSize, payload); } Uint8List _writeKeyWithHint(String key, String hint) { if (hint == "edsk" || hint == "edpk") { - return bs58check.decode(key).sublist(4); + print("key ===> $key"); + var bs58CheckDecodced = bs58check.decode(key); + print("bs58CheckDecodced ===> $bs58CheckDecodced"); + print( + "bs58check.encode(bs58CheckDecodced) ===> ${bs58check.encode(bs58CheckDecodced)}"); + print( + "hex.encode(bs58CheckDecodced) ===> ${hex.encode(bs58CheckDecodced)}"); + var data = hex.encode(bs58CheckDecodced).substring(8); + print("data ===> $data"); + var decodedData = hex.decode(data); + Uint8List bs58String = Uint8List.fromList(decodedData); + print("bs58String ===> $bs58String"); + return bs58String; } else { throw {"message": "Unrecognized key hint, '$hint'"}; } @@ -500,8 +582,7 @@ String _readSignatureWithHint(Uint8List payload, String hint) { if (hint == 'edsig') { List intConversionPayload = List.from(payload); String encodedPayoad = hex.encode(intConversionPayload); - String concatEncodedPayload = '09f5cd8612' + encodedPayoad; - + String concatEncodedPayload = '09f5cd8612' + encodedPayoad; List hexPayloadListInt = hex.decode(concatEncodedPayload); Uint8List finalHexPayloadUint8ListInt = Uint8List.fromList(hexPayloadListInt); From f5f23c4e102bbfb600274237ab41a551325282f4 Mon Sep 17 00:00:00 2001 From: Rakshak1344 Date: Wed, 21 Oct 2020 20:13:25 +0530 Subject: [PATCH 10/12] resolved flutter_sodium version & made changes --- example/android/settings_aar.gradle | 1 + example/lib/main.dart | 4 +- example/pubspec.lock | 105 ++++++++++++---------------- lib/src/tezsterSendOperation.dart | 1 - lib/src/tezster_dart.dart | 32 +++++---- pubspec.lock | 105 ++++++++++++---------------- pubspec.yaml | 16 ++--- 7 files changed, 120 insertions(+), 144 deletions(-) create mode 100644 example/android/settings_aar.gradle diff --git a/example/android/settings_aar.gradle b/example/android/settings_aar.gradle new file mode 100644 index 0000000..e7b4def --- /dev/null +++ b/example/android/settings_aar.gradle @@ -0,0 +1 @@ +include ':app' diff --git a/example/lib/main.dart b/example/lib/main.dart index 7f6421d..a911294 100644 --- a/example/lib/main.dart +++ b/example/lib/main.dart @@ -343,9 +343,9 @@ class _MyAppState extends State { @override void initState() { super.initState(); - // tezosWalletUtil(); + tezosWalletUtil(); // tezosNodeWriter(); - nodeWriter(); + // nodeWriter(); } @override diff --git a/example/pubspec.lock b/example/pubspec.lock index 2f14943..8643145 100644 --- a/example/pubspec.lock +++ b/example/pubspec.lock @@ -1,27 +1,13 @@ # Generated by pub # See https://dart.dev/tools/pub/glossary#lockfile packages: - archive: - dependency: transitive - description: - name: archive - url: "https://pub.dartlang.org" - source: hosted - version: "2.0.13" - args: - dependency: transitive - description: - name: args - url: "https://pub.dartlang.org" - source: hosted - version: "1.6.0" async: dependency: transitive description: name: async url: "https://pub.dartlang.org" source: hosted - version: "2.4.1" + version: "2.5.0-nullsafety.1" bip39: dependency: transitive description: @@ -42,7 +28,7 @@ packages: name: boolean_selector url: "https://pub.dartlang.org" source: hosted - version: "2.0.0" + version: "2.1.0-nullsafety.1" bs58check: dependency: transitive description: @@ -50,20 +36,34 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "1.0.1" + characters: + dependency: transitive + description: + name: characters + url: "https://pub.dartlang.org" + source: hosted + version: "1.1.0-nullsafety.3" charcode: dependency: transitive description: name: charcode url: "https://pub.dartlang.org" source: hosted - version: "1.1.3" + version: "1.2.0-nullsafety.1" + clock: + dependency: transitive + description: + name: clock + url: "https://pub.dartlang.org" + source: hosted + version: "1.1.0-nullsafety.1" collection: dependency: transitive description: name: collection url: "https://pub.dartlang.org" source: hosted - version: "1.14.12" + version: "1.15.0-nullsafety.3" convert: dependency: transitive description: @@ -92,6 +92,20 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "0.0.1" + fake_async: + dependency: transitive + description: + name: fake_async + url: "https://pub.dartlang.org" + source: hosted + version: "1.2.0-nullsafety.1" + ffi: + dependency: transitive + description: + name: ffi + url: "https://pub.dartlang.org" + source: hosted + version: "0.1.3" fixnum: dependency: transitive description: @@ -110,7 +124,7 @@ packages: name: flutter_sodium url: "https://pub.dartlang.org" source: hosted - version: "0.0.11" + version: "0.1.8" flutter_test: dependency: "direct dev" description: flutter @@ -137,13 +151,6 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "3.1.4" - image: - dependency: transitive - description: - name: image - url: "https://pub.dartlang.org" - source: hosted - version: "2.1.12" js: dependency: transitive description: @@ -157,14 +164,14 @@ packages: name: matcher url: "https://pub.dartlang.org" source: hosted - version: "0.12.6" + version: "0.12.10-nullsafety.1" meta: dependency: transitive description: name: meta url: "https://pub.dartlang.org" source: hosted - version: "1.1.8" + version: "1.3.0-nullsafety.3" password_hash: dependency: transitive description: @@ -178,7 +185,7 @@ packages: name: path url: "https://pub.dartlang.org" source: hosted - version: "1.6.4" + version: "1.8.0-nullsafety.1" pedantic: dependency: transitive description: @@ -186,13 +193,6 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "1.9.0" - petitparser: - dependency: transitive - description: - name: petitparser - url: "https://pub.dartlang.org" - source: hosted - version: "2.4.0" pointycastle: dependency: transitive description: @@ -200,13 +200,6 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "1.0.2" - quiver: - dependency: transitive - description: - name: quiver - url: "https://pub.dartlang.org" - source: hosted - version: "2.1.3" sky_engine: dependency: transitive description: flutter @@ -218,42 +211,42 @@ packages: name: source_span url: "https://pub.dartlang.org" source: hosted - version: "1.7.0" + version: "1.8.0-nullsafety.2" stack_trace: dependency: transitive description: name: stack_trace url: "https://pub.dartlang.org" source: hosted - version: "1.9.3" + version: "1.10.0-nullsafety.1" stream_channel: dependency: transitive description: name: stream_channel url: "https://pub.dartlang.org" source: hosted - version: "2.0.0" + version: "2.1.0-nullsafety.1" string_scanner: dependency: transitive description: name: string_scanner url: "https://pub.dartlang.org" source: hosted - version: "1.0.5" + version: "1.1.0-nullsafety.1" term_glyph: dependency: transitive description: name: term_glyph url: "https://pub.dartlang.org" source: hosted - version: "1.1.0" + version: "1.2.0-nullsafety.1" test_api: dependency: transitive description: name: test_api url: "https://pub.dartlang.org" source: hosted - version: "0.2.15" + version: "0.2.19-nullsafety.2" tezster_dart: dependency: "direct main" description: @@ -267,7 +260,7 @@ packages: name: typed_data url: "https://pub.dartlang.org" source: hosted - version: "1.1.6" + version: "1.3.0-nullsafety.3" unorm_dart: dependency: transitive description: @@ -281,13 +274,7 @@ packages: name: vector_math url: "https://pub.dartlang.org" source: hosted - version: "2.0.8" - xml: - dependency: transitive - description: - name: xml - url: "https://pub.dartlang.org" - source: hosted - version: "3.6.1" + version: "2.1.0-nullsafety.3" sdks: - dart: ">=2.7.0 <3.0.0" + dart: ">=2.10.0-110 <2.11.0" + flutter: ">=1.10.0" diff --git a/lib/src/tezsterSendOperation.dart b/lib/src/tezsterSendOperation.dart index 618125f..3cda9df 100644 --- a/lib/src/tezsterSendOperation.dart +++ b/lib/src/tezsterSendOperation.dart @@ -1,5 +1,4 @@ import 'dart:convert'; -import 'dart:ffi'; import 'dart:typed_data'; import 'package:blake2b/blake2b_hash.dart'; diff --git a/lib/src/tezster_dart.dart b/lib/src/tezster_dart.dart index 6742110..4e924ad 100644 --- a/lib/src/tezster_dart.dart +++ b/lib/src/tezster_dart.dart @@ -26,13 +26,15 @@ class TezsterDart { assert(mnemonic != null); Uint8List seed = bip39.mnemonicToSeed(mnemonic); Uint8List seedLength32 = seed.sublist(0, 32); - Map keys = - await Sodium.cryptoSignSeedKeypair(seedLength32); - Uint8List sk = keys['sk']; - Uint8List pk = keys['pk']; - String skKey = GenerateKeys.readKeysWithHint(sk, '2bf64e07'); - String pkKey = GenerateKeys.readKeysWithHint(pk, '0d0f25d9'); - String pkKeyHash = GenerateKeys.computeKeyHash(pk); + // Map keys = + // await Sodium.cryptoSignSeedKeypair(seedLength32); + KeyPair keyPair = Sodium.cryptoSignSeedKeypair(seedLength32); + // keyPair.pk + // Uint8List sk = keys['sk']; + // Uint8List pk = keys['pk']; + String skKey = GenerateKeys.readKeysWithHint(keyPair.sk, '2bf64e07'); + String pkKey = GenerateKeys.readKeysWithHint(keyPair.pk, '0d0f25d9'); + String pkKeyHash = GenerateKeys.computeKeyHash(keyPair.pk); return [skKey, pkKey, pkKeyHash]; } @@ -77,10 +79,10 @@ class TezsterDart { List pkB = List.from(privateKeyBytes); pkB.removeRange(0, 4); Uint8List finalPKb = Uint8List.fromList(pkB); - Uint8List value = await Sodium.cryptoSignDetached( + Uint8List value = Sodium.cryptoSignDetached( hashedWatermarkedOpBytes, finalPKb, - useBackgroundThread: false, + // useBackgroundThread: false, ); String opSignatureHex = hex.encode(value); String hexStringToEncode = '09f5cd8612' + opSignatureHex; @@ -110,12 +112,12 @@ class TezsterDart { String normString = String.fromCharCodes(normalizedPassphrase); String p = "mnemonic" + normString; Uint8List seed = PBKDF2(hashAlgorithm: sha512).generateKey(m, p, 2048, 32); - Map keys = await Sodium.cryptoSignSeedKeypair(seed); - Uint8List sk = keys['sk']; - Uint8List pk = keys['pk']; - String skKey = GenerateKeys.readKeysWithHint(sk, '2bf64e07'); - String pkKey = GenerateKeys.readKeysWithHint(pk, '0d0f25d9'); - String pkKeyHash = GenerateKeys.computeKeyHash(pk); + KeyPair keyPair = Sodium.cryptoSignSeedKeypair(seed); + // Uint8List sk = keys['sk']; + // Uint8List pk = keys['pk']; + String skKey = GenerateKeys.readKeysWithHint(keyPair.sk, '2bf64e07'); + String pkKey = GenerateKeys.readKeysWithHint(keyPair.pk, '0d0f25d9'); + String pkKeyHash = GenerateKeys.computeKeyHash(keyPair.pk); return [skKey, pkKey, pkKeyHash]; } } diff --git a/pubspec.lock b/pubspec.lock index 6a5bade..3dcd354 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -1,27 +1,13 @@ # Generated by pub # See https://dart.dev/tools/pub/glossary#lockfile packages: - archive: - dependency: transitive - description: - name: archive - url: "https://pub.dartlang.org" - source: hosted - version: "2.0.13" - args: - dependency: transitive - description: - name: args - url: "https://pub.dartlang.org" - source: hosted - version: "1.6.0" async: dependency: transitive description: name: async url: "https://pub.dartlang.org" source: hosted - version: "2.4.1" + version: "2.5.0-nullsafety.1" bip39: dependency: "direct main" description: @@ -42,7 +28,7 @@ packages: name: boolean_selector url: "https://pub.dartlang.org" source: hosted - version: "2.0.0" + version: "2.1.0-nullsafety.1" bs58check: dependency: "direct main" description: @@ -50,20 +36,34 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "1.0.1" + characters: + dependency: transitive + description: + name: characters + url: "https://pub.dartlang.org" + source: hosted + version: "1.1.0-nullsafety.3" charcode: dependency: transitive description: name: charcode url: "https://pub.dartlang.org" source: hosted - version: "1.1.3" + version: "1.2.0-nullsafety.1" + clock: + dependency: transitive + description: + name: clock + url: "https://pub.dartlang.org" + source: hosted + version: "1.1.0-nullsafety.1" collection: dependency: transitive description: name: collection url: "https://pub.dartlang.org" source: hosted - version: "1.14.12" + version: "1.15.0-nullsafety.3" convert: dependency: "direct main" description: @@ -85,6 +85,20 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "0.0.1" + fake_async: + dependency: transitive + description: + name: fake_async + url: "https://pub.dartlang.org" + source: hosted + version: "1.2.0-nullsafety.1" + ffi: + dependency: transitive + description: + name: ffi + url: "https://pub.dartlang.org" + source: hosted + version: "0.1.3" fixnum: dependency: transitive description: @@ -103,7 +117,7 @@ packages: name: flutter_sodium url: "https://pub.dartlang.org" source: hosted - version: "0.0.11" + version: "0.1.8" flutter_test: dependency: "direct dev" description: flutter @@ -130,13 +144,6 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "3.1.4" - image: - dependency: transitive - description: - name: image - url: "https://pub.dartlang.org" - source: hosted - version: "2.1.12" js: dependency: "direct main" description: @@ -150,14 +157,14 @@ packages: name: matcher url: "https://pub.dartlang.org" source: hosted - version: "0.12.6" + version: "0.12.10-nullsafety.1" meta: dependency: transitive description: name: meta url: "https://pub.dartlang.org" source: hosted - version: "1.1.8" + version: "1.3.0-nullsafety.3" password_hash: dependency: "direct main" description: @@ -171,7 +178,7 @@ packages: name: path url: "https://pub.dartlang.org" source: hosted - version: "1.6.4" + version: "1.8.0-nullsafety.1" pedantic: dependency: transitive description: @@ -179,13 +186,6 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "1.9.0" - petitparser: - dependency: transitive - description: - name: petitparser - url: "https://pub.dartlang.org" - source: hosted - version: "2.4.0" pointycastle: dependency: transitive description: @@ -193,13 +193,6 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "1.0.2" - quiver: - dependency: transitive - description: - name: quiver - url: "https://pub.dartlang.org" - source: hosted - version: "2.1.3" sky_engine: dependency: transitive description: flutter @@ -211,49 +204,49 @@ packages: name: source_span url: "https://pub.dartlang.org" source: hosted - version: "1.7.0" + version: "1.8.0-nullsafety.2" stack_trace: dependency: transitive description: name: stack_trace url: "https://pub.dartlang.org" source: hosted - version: "1.9.3" + version: "1.10.0-nullsafety.1" stream_channel: dependency: transitive description: name: stream_channel url: "https://pub.dartlang.org" source: hosted - version: "2.0.0" + version: "2.1.0-nullsafety.1" string_scanner: dependency: transitive description: name: string_scanner url: "https://pub.dartlang.org" source: hosted - version: "1.0.5" + version: "1.1.0-nullsafety.1" term_glyph: dependency: transitive description: name: term_glyph url: "https://pub.dartlang.org" source: hosted - version: "1.1.0" + version: "1.2.0-nullsafety.1" test_api: dependency: transitive description: name: test_api url: "https://pub.dartlang.org" source: hosted - version: "0.2.15" + version: "0.2.19-nullsafety.2" typed_data: dependency: transitive description: name: typed_data url: "https://pub.dartlang.org" source: hosted - version: "1.1.6" + version: "1.3.0-nullsafety.3" unorm_dart: dependency: "direct main" description: @@ -267,13 +260,7 @@ packages: name: vector_math url: "https://pub.dartlang.org" source: hosted - version: "2.0.8" - xml: - dependency: transitive - description: - name: xml - url: "https://pub.dartlang.org" - source: hosted - version: "3.6.1" + version: "2.1.0-nullsafety.3" sdks: - dart: ">=2.6.0 <3.0.0" + dart: ">=2.10.0-110 <2.11.0" + flutter: ">=1.10.0" diff --git a/pubspec.yaml b/pubspec.yaml index e52ea5f..9d3cadf 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -7,22 +7,22 @@ repository: https://github.com/Tezsure/tezster_dart issue_tracker: https://github.com/Tezsure/tezster_dart/issues environment: - sdk: ">=2.6.0 <3.0.0" + sdk: ">=2.3.0 <3.0.0" dependencies: flutter: sdk: flutter - crypto: ^2.1.4 - bs58check: ^1.0.1 - blake2b: ^0.1.2 - flutter_sodium: ^0.0.11 bip39: ^1.0.3 - unorm_dart: ^0.1.2 - password_hash: ^2.0.0 + blake2b: ^0.1.2 + bs58check: ^1.0.1 convert: ^2.1.1 + crypto: ^2.1.4 + ed25519: ^0.0.1 + flutter_sodium: ^0.1.8 http: ^0.12.1 js: ^0.6.2 - ed25519: ^0.0.1 + password_hash: ^2.0.0 + unorm_dart: ^0.1.2 dev_dependencies: flutter_test: From aa9570963fe7b9e22a43a05da18e08191627d440 Mon Sep 17 00:00:00 2001 From: Rakshak1344 Date: Sat, 28 Nov 2020 15:00:07 +0530 Subject: [PATCH 11/12] Update dependencies --- example/lib/main.dart | 275 ------------------------------------------ example/pubspec.lock | 41 +------ 2 files changed, 3 insertions(+), 313 deletions(-) diff --git a/example/lib/main.dart b/example/lib/main.dart index a911294..e5cb99d 100644 --- a/example/lib/main.dart +++ b/example/lib/main.dart @@ -67,285 +67,10 @@ class _MyAppState extends State { //Accessing: private key ===> identityFundraiser[0] | public key ===> identityFundraiser[1] | public Key Hash ===> identityFundraiser[2] all of type string. } - tezosNodeWriter() async { - String testNetServer = "https://testnet.tezster.tech"; - - //Working functions - dynamic response = await TezsterNodeReader.performGetRequest( - server: testNetServer, - command: "chains/main/blocks", - ); - print("Response ===> $response"); - - dynamic getBlock = await TezsterNodeReader.getBlock( - server: testNetServer, - hash: "head", - chainid: "NetXjD3HPJJjmcd", - ); - print("GET-Block ===> $getBlock"); - - dynamic blockhead = await TezsterNodeReader.getBlockHead( - server: testNetServer, - ); - print("Block-Head ===> $blockhead"); - - dynamic getCounterForAccount = await TezsterNodeReader.getCounterForAccount( - server: testNetServer, - accountHash: "tz1ZfFASQvmmz47ru5nn9GhX5oswCRVX5z1r", - chainid: "NetXjD3HPJJjmcd", - ); - print("GET-Counter-ForAccount ===> $getCounterForAccount"); - - dynamic getMempoolOperation = await TezsterNodeReader.getMempoolOperation( - server: testNetServer, - chainid: "NetXjD3HPJJjmcd", - operationGroupId: "opAPztkmYpEG754JGjkKi4snUTaa879fvgWfGFeDrdmTAbaoLNp", - ); - print("GET-MempoolOperation ===> $getMempoolOperation"); - - dynamic getSpendableBalanceForAccount = - await TezsterNodeReader.getSpendableBalanceForAccount( - server: testNetServer, - accountHash: "tz1ZfFASQvmmz47ru5nn9GhX5oswCRVX5z1r", - chainid: "NetXjD3HPJJjmcd", - ); - print( - "GET-SpendableBalance-ForAccount ===> $getSpendableBalanceForAccount"); - - dynamic getBalance = await TezsterNodeReader.getBalance( - accountHash: "tz1ZfFASQvmmz47ru5nn9GhX5oswCRVX5z1r", - server: testNetServer, - ); - print("Get-Balance ===> $getBalance"); - - dynamic getMempoolOperationsForAccount = - await TezsterNodeReader.getMempoolOperationsForAccount( - server: testNetServer, - chainid: "NetXjD3HPJJjmcd", - accountHash: "tz1Y8zdtVe2wWe7QdNTnAdwBceqYBCdA3Jj8", - ); - print( - "GET-MempoolOperations-ForAccount ===> $getMempoolOperationsForAccount"); - - bool isRevealed = await TezsterNodeReader.isManagerKeyRevealedForAccount( - server: "https://testnet.tezster.tech/", - accountHash: 'tz1KqTpEZ7Yob7QbPE4Hy4Wo8fHG8LhKxZSx', - ); - print("isRevealed ===> $isRevealed"); - -//Yet to be tested - // dynamic getAccForBlock = await TezsterNodeReader.getAccountForBlock( - // server: testNetServer, - // accountHash: "tz1ZfFASQvmmz47ru5nn9GhX5oswCRVX5z1r", - // blockHash: "", - // chainid: "NetXjD3HPJJjmcd", - // ); - // print("GET-Acc-ForBlock ===> $getAccForBlock"); - - // dynamic getAccountManagerForBlock = - // await TezsterNodeReader.getAccountManagerForBlock( - // server: testNetServer, - // chainid: "NetXjD3HPJJjmcd", - // accountHash: "tz1ZfFASQvmmz47ru5nn9GhX5oswCRVX5z1r", - // block: "", - // ); - // print("GET-Account-Manager-ForBlock ===> $getAccountManagerForBlock"); - - // dynamic isImplicitAndEmpty = await TezsterNodeReader.isImplicitAndEmpty( - // server: testNetServer, - // accountHash: "tz1ZfFASQvmmz47ru5nn9GhX5oswCRVX5z1r", - // ); - // print("Is-ImplicitAndEmpty ===> $isImplicitAndEmpty"); - - // dynamic getContractStorage = await TezsterNodeReader.getContractStorage( - // server: testNetServer, - // accountHash: "tz1ZfFASQvmmz47ru5nn9GhX5oswCRVX5z1r", - // block: "", - // chainid: "NetXjD3HPJJjmcd", - // ); - // print("GET-Contract-Storage ===> $getContractStorage"); - - // dynamic getValueForBigMapKey = await TezsterNodeReader.getValueForBigMapKey( - // server: testNetServer, - // key: "", - // block: "", - // chainid: "NetXjD3HPJJjmcd", - // index: 1, - // ); - // print("GET-Value-ForBigMapKey ===> $getValueForBigMapKey"); - } - - nodeWriter() async { - Activation activation = Activation( - pkh: "tz1hhkSbaocSWm3wawZUuUdX57L3maSH16Pv", - secret: "9802d2dcc227576700acf963979792d0abf53340", - ); - - Reveal reveal = Reveal( - gasLimit: "129", - storageLimit: "10", - counter: "213", - fee: "100", - publicKey: "edpkuLog552hecagkykJ3fTvop6grTMhfZY4TWbvchDWdYyxCHcrQL", - source: "tz1VwWdetdADCEMySCumYXWtvf9pZQV3CmE5", - ); - - Transaction transaction = Transaction( - contractParameters: ContractParameters( - entrypoint: "", - value: "", - ), - amount: "", - counter: "", - destination: "", - fee: "", - gasLimit: "", - source: "", - storageLimit: "", - ); - - Ballot ballot = Ballot( - period: 1, - proposal: "", - source: "", - vote: 0, - ); - - var sendOP = TezsterSendOperation.sendTransactionOperation( - server: 'https://testnet.tezster.tech', - amount: 1000000, - fee: 100000, - to: 'tz1a4UNywaxaAfh2LRBP2UugQTeCVcLCn5Sa', - derivationPath: '', - keyStore: KeyStore( - publicKey: 'edpkvaUDxsbgxQwXKFph4SUz7HawNnKMG2ESHcTPkYkQXwKRdpz5tm', - privateKey: - 'edskRoBCkDEhPzHHoXH5wtSf2LZGVe9z2AiLGNdvY7QFXVJxN62ZvW9LThG3vzMVgcuesDRDr5VSGPQqEW5ky3Te6eNfAbX8eh', - publicKeyHash: 'tz1Sr4tBA28P2QsEM7zpVUM41PSza5R1hFEz', - seed: '', - storeType: StoreType.fundraiser, - ), - ); - print("sendOP ===> $sendOP"); - - // { - // sk: - // 'edskRuR1azSfboG86YPTyxrQgosh5zChf5bVDmptqLTb5EuXAm9rsnDYfTKhq7rDQujdn5WWzwUMeV3agaZ6J2vPQT58jJAJPi', - // pk: 'edpkuBknW28nW72KG6RoHtYW7p12T6GKc7nAbwYX5m8Wd9sDVC9yav', - // pkh: 'tz1KqTpEZ7Yob7QbPE4Hy4Wo8fHG8LhKxZSx', - // label: 'bootstrap1', - // } - - //Sign operation with public-Key and forged operation - // List signOpGrp = await TezsterDart.signOperationGroup( - // privateKey: - // "edskRdVS5H9YCRAG8yqZkX2nUTbGcaDqjYgopkJwRuPUnYzCn3t9ZGksncTLYe33bFjq29pRhpvjQizCCzmugMGhJiXezixvdC", - // forgedOperation: - // "713cb068fe3ac078351727eb5c34279e22b75b0cf4dc0a8d3d599e27031db136040cb9f9da085607c05cac1ca4c62a3f3cfb8146aa9b7f631e52f877a1d363474404da8130b0b940ee", - // ); - // print("signOpGrp ==> $signOpGrp"); - - // dynamic getBlock = await TezsterNodeReader.getBlock( - // server: 'https://testnet.tezster.tech/', - // hash: "head", - // chainid: "NetXjD3HPJJjmcd", - // ); - // print("GET-Block ===> $getBlock"); - - // String activationData = TezsterNodeWriter.forgeOperations( - // branch: "BLjxPLCWUuFBewguqrojaHhgAcc8jLZneFkpnrVVcYn2zQz4pmW", - // operation: activation, - // ); - // print("activationData => $activationData"); - - // String revealData = TezsterNodeWriter.forgeOperations( - // branch: "BLjxPLCWUuFBewguqrojaHhgAcc8jLZneFkpnrVVcYn2zQz4pmW", - // operation: reveal, - // ); - // // print("revealData => $revealData"); - - // String transactionData = TezsterNodeWriter.forgeOperations( - // branch: "BLjxPLCWUuFBewguqrojaHhgAcc8jLZneFkpnrVVcYn2zQz4pmW", - // operation: transaction, - // ); - // // print("transactionData ===> $transactionData"); - - // String ballotData = TezsterNodeWriter.forgeOperations( - // branch: "BLjxPLCWUuFBewguqrojaHhgAcc8jLZneFkpnrVVcYn2zQz4pmW", - // operation: ballot, - // ); - // print("ballotData ===> $ballotData"); - - // String jsonDecod = jsonDecode( - // '{"name":{"first":"foo","last":"bar"}, "age":31, "city":"New York"}'); - // print(jsonDecod); - - // String jsonData = TezsterNodeWriter.normalizeMichelineWhiteSpace(jsonDecod); - // print("JSONDATA ===> $jsonData"); - - // var jsonData = - // '{"accounting":[{"firstName":"John","lastName":"Doe","age":23},{"firstName":"Mary","lastName":"Smith","age":32}],"sales":[{"firstName":"Sally","lastName":"Green","age":27},{"firstName":"Jim","lastName":"Galley","age":41}]}'; - - // String newJsonData = - // TezsterNodeWriter.normalizeMichelineWhiteSpace(jsonData); - // print("newJsonData ==> $newJsonData"); - // // String prettyJson(Map json, {int indent = 4}) { - // // var spaces = ' ' * indent; - // // var encoder = JsonEncoder.withIndent(spaces); - // // return encoder.convert(json); - // // } - - // print(TezsterNodeWriter.prettyJson({ - // "prim": "Right", - // "args": [ - // { - // "prim": "Left", - // "args": [ - // {"prim": "Unit"} - // ] - // } - // ] - // })); - - // print("newJsonData ===> $newJsonData"); - // var pubkey = TezsterNodeWriter.writePublicKey( - // "edpkuLog552hecagkykJ3fTvop6grTMhfZY4TWbvchDWdYyxCHcrQL"); - // print("pubkey ===> $pubkey"); - // TezsterNodeWriter.writeBranch( - // "BKzEzxCwQcXBJNHCxGbnq9H8P3aV7EfFZaot54nShmF3YAgwHDj"); - - // { - // "destination": "KT1LRre6w4EgkCRLwUugQLEdRGPvJdTmx3Ae", - // "amount": "10", - // "storage_limit": "1000", - // "gas_limit": "100000", - // "counter": "606113", - // "fee": "100000", - // "source": "tz1NN5QooJWkW44KFfrXqLRaxEa5Wxw3f9FF", - // "kind": "transaction", - // "parameters": { - // "entrypoint": "default", - // "value": { - // "prim": "Right", - // "args": [ - // { - // "prim": "Left", - // "args": [ - // {"prim": "Unit"} - // ] - // } - // ] - // } - // } - // } - } - @override void initState() { super.initState(); tezosWalletUtil(); - // tezosNodeWriter(); - // nodeWriter(); } @override diff --git a/example/pubspec.lock b/example/pubspec.lock index 8643145..26dec30 100644 --- a/example/pubspec.lock +++ b/example/pubspec.lock @@ -77,7 +77,7 @@ packages: name: crypto url: "https://pub.dartlang.org" source: hosted - version: "2.1.4" + version: "2.1.5" cupertino_icons: dependency: "direct main" description: @@ -85,13 +85,6 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "0.1.3" - ed25519: - dependency: transitive - description: - name: ed25519 - url: "https://pub.dartlang.org" - source: hosted - version: "0.0.1" fake_async: dependency: transitive description: @@ -124,7 +117,7 @@ packages: name: flutter_sodium url: "https://pub.dartlang.org" source: hosted - version: "0.1.8" + version: "0.1.9" flutter_test: dependency: "direct dev" description: flutter @@ -137,27 +130,6 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "0.1.2" - http: - dependency: transitive - description: - name: http - url: "https://pub.dartlang.org" - source: hosted - version: "0.12.2" - http_parser: - dependency: transitive - description: - name: http_parser - url: "https://pub.dartlang.org" - source: hosted - version: "3.1.4" - js: - dependency: transitive - description: - name: js - url: "https://pub.dartlang.org" - source: hosted - version: "0.6.2" matcher: dependency: transitive description: @@ -186,13 +158,6 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "1.8.0-nullsafety.1" - pedantic: - dependency: transitive - description: - name: pedantic - url: "https://pub.dartlang.org" - source: hosted - version: "1.9.0" pointycastle: dependency: transitive description: @@ -253,7 +218,7 @@ packages: path: ".." relative: true source: path - version: "1.0.0" + version: "1.0.1" typed_data: dependency: transitive description: From d5e305447e8dc39b5629a386831dcfdde6939a2f Mon Sep 17 00:00:00 2001 From: Rakshak1344 Date: Sat, 28 Nov 2020 15:40:01 +0530 Subject: [PATCH 12/12] package dependencies updated - HotFix --- CHANGELOG.md | 4 + lib/helper/tezosMessageUtil.dart | 94 ---- lib/src/tezsterNodeReader.dart | 220 --------- lib/src/tezsterNodeWriter.dart | 787 ------------------------------ lib/src/tezsterSendOperation.dart | 593 ---------------------- lib/src/tezster_dart.dart | 8 - lib/tezster_dart.dart | 130 +---- pubspec.lock | 39 +- pubspec.yaml | 9 +- 9 files changed, 10 insertions(+), 1874 deletions(-) delete mode 100644 lib/helper/tezosMessageUtil.dart delete mode 100644 lib/src/tezsterNodeReader.dart delete mode 100644 lib/src/tezsterNodeWriter.dart delete mode 100644 lib/src/tezsterSendOperation.dart diff --git a/CHANGELOG.md b/CHANGELOG.md index 4d7e892..be97b35 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ +# [1.0.1] + +* Dependencies update. + # [1.0.0] Initial version of library. diff --git a/lib/helper/tezosMessageUtil.dart b/lib/helper/tezosMessageUtil.dart deleted file mode 100644 index 6c9ff6e..0000000 --- a/lib/helper/tezosMessageUtil.dart +++ /dev/null @@ -1,94 +0,0 @@ -import 'dart:typed_data'; -import 'package:convert/convert.dart'; -import 'package:flutter/material.dart'; -import 'package:bs58check/bs58check.dart' as bs58check; - -class TezsterMessageUtil { - TezsterMessageUtil._(); - static String twoByteHex(int n) { - if (n < 128) { - String hexString = "0" + n.toRadixString(16); - return hexString.substring(hexString.length - 2); - } - - String h = ''; - - if (n > 2147483648) { - BigInt r = BigInt.from(n); - while (r > BigInt.zero) { - //Review - String data = ('0' + r.toRadixString(16) + 127.toRadixString(16)); - h = data.substring(data.length - 2) + h; - r = r >> 7; - } - } else { - int r = n; - while (r > 0) { - // Review - String data = ('0' + (r & 127).toRadixString(16)); - h = data.substring(data.length - 2) + h; - r = r >> 7; - } - } - return h; - } - - static String writeInt(int value) { - if (value < 0) { - return "Use writeSignedInt to encode negative numbers"; - } - - String twoByteHexString = twoByteHex(value); - // print("twoByteHexString ==> $twoByteHexString"); - - List hexStringToList = hex.decode(twoByteHexString); - // print("hexStringToList ===> $hexStringToList"); - - Uint8List twoByteUint8List = Uint8List.fromList(hexStringToList); - // print("twoByteUint8List ===> $twoByteUint8List"); - - Map mapData = twoByteUint8List.asMap(); - // print("mapData ===> $mapData"); - - List hexList = []; - - mapData.forEach((key, value) { - var hexValue = key == 0 ? value : value ^ 0x80; - // print(key.toString() + " " + value.toString()); - // print(hexValue); - hexList.add(hexValue); - }); - // print("hexList ===> $hexList"); - - List reversedList = (hexList.reversed).toList(); - - Uint8List conversion = Uint8List.fromList((hexList.reversed).toList()); - // print("conversion $conversion"); - - String reversedIntListDataToHex = hex.encode(reversedList); - // print("reversedIntListDataToHex ===> $reversedIntListDataToHex"); - - return reversedIntListDataToHex; - } - - static String writeAddress(String address) { - Uint8List uintBsList = bs58check.decode(address).sublist(3); - // List bsList = List.from(uintBsList); - String hexString = hex.encode(uintBsList); - // print("hexString ===> $hexString"); - - if (address.startsWith("tz1")) { - return "0000" + hexString; - } else if (address.startsWith("tz2")) { - return "0001" + hexString; - } else if (address.startsWith("tz3")) { - return "0002" + hexString; - } else if (address.startsWith("KT1")) { - return "01" + hexString + "00"; - } else { - throw ErrorDescription("Unrecognized address prefix: "); - } - } - - static String writeBoolean(bool value) => value ? "ff" : "00"; -} diff --git a/lib/src/tezsterNodeReader.dart b/lib/src/tezsterNodeReader.dart deleted file mode 100644 index 9ada535..0000000 --- a/lib/src/tezsterNodeReader.dart +++ /dev/null @@ -1,220 +0,0 @@ -import 'dart:convert'; - -import 'package:http/http.dart' as http; - -class TezsterNodeReader { - static dynamic performGetRequest({ - String server, - String command = "", - }) async { - assert(server != null); - String url = "$server/$command"; - http.Response response = await http.get(url); - if (response.statusCode != 200) { - return "Invalid URL"; - } - dynamic data = jsonDecode(response.body); - return data; - } - - static dynamic getBlock({ - String server, - String hash = "head", - String chainid = "main", - }) async { - assert(server != null); - dynamic response = await performGetRequest( - server: server, - command: "chains/$chainid/blocks/$hash", - ); - - // print(response['hash']); - return response; - } - - static Future getBlockHead({ - String server, - }) async { - assert(server != null); - dynamic response = await getBlock(server: server); - return response; - } - - static dynamic getAccountForBlock({ - String server, - String blockHash, - String accountHash, - String chainid = "main", - }) { - dynamic response = performGetRequest( - server: server, - command: - "chains/$chainid/blocks/$blockHash/context/contracts/$accountHash", - ); - return response; - } - - static dynamic getCounterForAccount({ - String server, - String accountHash, - String chainid = "main", - }) async { - dynamic counter = await performGetRequest( - server: server, - command: - "chains/$chainid/blocks/head/context/contracts/$accountHash/counter", - ); - return int.parse(counter, radix: 10); - } - - static dynamic getSpendableBalanceForAccount({ - String server, - String accountHash, - String chainid = "main", - }) async { - dynamic account = await performGetRequest( - server: server, - command: "chains/$chainid/blocks/head/context/contracts/$accountHash", - ); - return int.parse(account["balance"], radix: 10); - } - - /// Testing is Done [getAccountManagerForBlock] - static dynamic getAccountManagerForBlock({ - String server, - String block, - String accountHash, - String chainid = "main", - }) async { - try { - dynamic result = await performGetRequest( - server: server, - command: - "chains/$chainid/blocks/$block/context/contracts/$accountHash/manager_key", - ); - if (result.toString() == null) { - return ""; - } - return result.toString(); - } catch (e) { - throw (e); - } - } - - static dynamic isImplicitAndEmpty({ - String server, - String accountHash, - }) async { - dynamic account = await getAccountForBlock( - server: server, - blockHash: "head", - accountHash: accountHash, - ); - bool isImplicit = accountHash.toLowerCase().startsWith("tz"); - bool isEmpty = account.balance == 0; - - if (isImplicit && isEmpty) - return true; - else - return false; - } - - /// Testing done [isManagerKeyRevealedForAccount] - static Future isManagerKeyRevealedForAccount({ - String server, - String accountHash, - }) async { - bool isRevealed; - String managerKey = await getAccountManagerForBlock( - server: server, - block: "head", - accountHash: accountHash, - ); - managerKey == null ? isRevealed = false : isRevealed = true; - - return isRevealed; - // return managerKey.length > 0 ? true : false; - } - - static dynamic getContractStorage({ - String server, - String accountHash, - String chainid = "main", - String block = "head", - }) async { - dynamic response = performGetRequest( - server: server, - command: - "chains/$chainid/blocks/$block/context/contracts/$accountHash/storage", - ); - return response; - } - - static dynamic getValueForBigMapKey({ - String server, - num index, - String key, - String block = "main", - String chainid = "head", - }) async { - dynamic response = performGetRequest( - server: server, - command: "chains/$chainid/blocks/$block/context/big_maps/$index/$key", - ); - return response; - } - - static dynamic getMempoolOperation({ - String server, - String operationGroupId, - String chainid = "main", - }) async { - dynamic mempoolContent = await performGetRequest( - server: server, - command: "chains/$chainid/mempool/pending_operations", - ); - List applied = mempoolContent["applied"]; - print("applied ===> $applied"); - dynamic response; - applied.forEach((data) { - if (data["hash"] == operationGroupId) { - response = data; - } else { - response = "Hash not found"; - } - }); - return response; - } - - static dynamic getMempoolOperationsForAccount({ - String server, - String accountHash, - String chainid = "main", - }) async { - dynamic mempoolContent = await performGetRequest( - server: server, - command: "chains/$chainid/mempool/pending_operations", - ); - List data = []; - dynamic applied = mempoolContent["applied"]; - applied.forEach((g) { - if (g["contents"][0]["source"] == accountHash || - g["contents"][0]["destination"] == accountHash) { - //print("G ===> ${g["contents"]}"); - data.insertAll(0, g["contents"]); - } - }); - return data; - } - - static dynamic getBalance({ - String server, - String accountHash, - }) async { - dynamic balance = performGetRequest( - server: server, - command: "chains/main/blocks/head/context/contracts/$accountHash/balance", - ); - return balance; - } -} diff --git a/lib/src/tezsterNodeWriter.dart b/lib/src/tezsterNodeWriter.dart deleted file mode 100644 index 4d6dcc7..0000000 --- a/lib/src/tezsterNodeWriter.dart +++ /dev/null @@ -1,787 +0,0 @@ -import 'dart:convert'; -import 'dart:typed_data'; -import 'dart:async'; -import 'dart:core'; - -import 'package:blake2b/blake2b_hash.dart'; -import 'package:flutter/material.dart'; -import 'package:bs58check/bs58check.dart' as bs58check; -import 'package:flutter_sodium/flutter_sodium.dart'; -import 'package:convert/convert.dart'; -import 'package:http/http.dart' as http; -import 'package:tezster_dart/tezster_dart.dart'; - -class TezsterNodeWriter { - static performPostRequest({ - String server, - String command, - Object payload, - }) async { - assert(server != null); - assert(command != null); - String url = '$server/$command'; - try { - String payloadString = jsonEncode(payload); - http.Response data = await http.post( - url, - body: payloadString, - headers: { - 'content-type': 'application/json', - }, - ); - return data; - } catch (e) { - return {"message": "Something went wrong"}; - } - } - - static Uint8List _simpleHash(Uint8List payload, int digestSize) { - return Blake2bHash.hashWithDigestSize(digestSize, payload); - } - - static Uint8List _writeKeyWithHint(String key, String hint) { - if (hint == "edsk" || hint == "edpk") { - return bs58check.decode(key).sublist(0, 64); - } else { - throw {"message": "Unrecognized key hint, '$hint'"}; - } - } - - static String _readSignatureWithHint(Uint8List payload, String hint) { - List intConversionPayload = List.from(payload); - String encodedPayoad = hex.encode(intConversionPayload); - String concatEncodedPayload = '09f5cd8612' + encodedPayoad; - String encodedPayoadToHexString = - hex.encode(concatEncodedPayload.codeUnits); - Uint8List finlaListForBS58CHECK = hex.decode(encodedPayoadToHexString); - print(finlaListForBS58CHECK); - if (hint == 'edsig') { - String bs58checkVal = bs58check.encode(finlaListForBS58CHECK); - var encodedHex = hex.encode(bs58checkVal.codeUnits); - print(encodedHex); - return bs58checkVal; - } else { - throw {"message": "Unrecognized key hint, '$hint'"}; - } - } - - static Future _signDetach(Uint8List message, Uint8List sk) async { - print("message ===> $message"); - print("sk ===> $sk"); - return Sodium.cryptoSignDetached(message, sk); - } - - static Future signOperationGroup({ - String forgedOperation, - String derivationPath, - String privateKey, - }) async { - assert(forgedOperation != null); - assert(privateKey != null); - String watermarkedForgedOperationBytesHex = "03" + forgedOperation; - String stringToHexString = - hex.encode(watermarkedForgedOperationBytesHex.codeUnits); - // print(stringToHexString); - List hexStringToListOfInt = hex.decode(stringToHexString); - // print(hexStringToListOfInt); - Uint8List hashedWatermarkedOpBytes = _simpleHash(hexStringToListOfInt, 256); - // print("hashedWatermarkedOpBytes ===> $hashedWatermarkedOpBytes"); - // print("hashedWatermarkedOpBytes ===> ${hashedWatermarkedOpBytes.length}"); - Uint8List privateKeyBytes = _writeKeyWithHint(privateKey, "edsk"); - // print("bs58List ===> $privateKeyBytes"); - - Uint8List opSignature = - await _signDetach(hashedWatermarkedOpBytes, privateKeyBytes); - print("opSignature ===> $opSignature"); - - String hexString = _readSignatureWithHint(opSignature, 'edsig'); - // var data = hex.decode(hexString); - // print(data); - // print("hexString ===> $hexString"); - - List listforgedOperation = hex.decode(forgedOperation); - Uint8List uint8ListforgedOperation = - Uint8List.fromList(listforgedOperation); - List signedOpBytes = uint8ListforgedOperation + opSignature; - // print("signedOpBytes ===> $signedOpBytes"); - - return SignedOperationGroup(bytes: signedOpBytes, signature: hexString); - } - - // FORGED OPERATION GROUP - - static String twoByteHex(int n) { - if (n < 128) { - String hexString = "0" + n.toRadixString(16); - return hexString.substring(hexString.length - 2); - } - - String h = ''; - - if (n > 2147483648) { - BigInt r = BigInt.from(n); - while (r > BigInt.zero) { - //Review - String data = ('0' + r.toRadixString(16) + 127.toRadixString(16)); - h = data.substring(data.length - 2) + h; - r = r >> 7; - } - } else { - int r = n; - while (r > 0) { - // Review - String data = ('0' + (r & 127).toRadixString(16)); - h = data.substring(data.length - 2) + h; - r = r >> 7; - } - } - return h; - } - - static String writeInt(int value) { - if (value < 0) { - return "Use writeSignedInt to encode negative numbers"; - } - - String twoByteHexString = twoByteHex(value); - print("twoByteHexString ==> $twoByteHexString"); - - List hexStringToList = hex.decode(twoByteHexString); - print("hexStringToList ===> $hexStringToList"); - - Uint8List twoByteUint8List = Uint8List.fromList(hexStringToList); - print("twoByteUint8List ===> $twoByteUint8List"); - - Map mapData = twoByteUint8List.asMap(); - print("mapData ===> $mapData"); - - List hexList = []; - - mapData.forEach((key, value) { - var hexValue = key == 0 ? value : value ^ 0x80; - print(key.toString() + " " + value.toString()); - print(hexValue); - hexList.add(hexValue); - }); - print("hexList ===> $hexList"); - - List reversedList = (hexList.reversed).toList(); - - Uint8List conversion = Uint8List.fromList((hexList.reversed).toList()); - print("conversion $conversion"); - - String reversedIntListDataToHex = hex.encode(reversedList); - print("reversedIntListDataToHex ===> $reversedIntListDataToHex"); - - return reversedIntListDataToHex; - } - - static Map sepyTnoitarepo = { - 'endorsement': 0, - 'seedNonceRevelation': 1, - 'doubleEndorsementEvidence': 2, - 'doubleBakingEvidence': 3, - 'accountActivation': 4, - 'proposal': 5, - 'ballot': 6, - 'reveal': 7, - 'transaction': 8, - 'origination': 9, - 'delegation': 10, - 'Newreveal': 107, - 'Newtransaction': 108, - 'Neworigination': 109, - 'Newdelegation': 110 - }; - - static String encodeActivation(Activation operation) { - String hexString = writeInt(sepyTnoitarepo['accountActivation']); - // print("writeIntHex ===> $writeIntHex"); - String hexCode = writeAddress(operation.pkh); - // print("hexCode ===> $hexCode"); - hexString += hexCode.substring(4); - hexString += operation.secret; - return hexString; - } - - static String encodeReveal(Reveal reveal) { - String hexString = writeInt(sepyTnoitarepo['reveal']); - hexString += writeAddress(reveal.source).substring(2); - hexString += writeInt(int.parse(reveal.fee)); - hexString += writeInt(int.parse(reveal.counter)); - hexString += writeInt(int.parse(reveal.gasLimit)); - hexString += writeInt(int.parse(reveal.storageLimit)); - hexString += writePublicKey(reveal.publicKey); - return hexString; - } - - /// TODO : This is pending [normalizeMichelineWhiteSpace] function - static String normalizeMichelineWhiteSpace(String compositevalue) { - return compositevalue - .replaceAll(RegExp('/ +/g'), ' ') - .replaceAll(RegExp(r'/\[{/g'), '[ {') - .replaceAll(RegExp('/}\]/g'), '} ]') - .replaceAll(RegExp('/},{/g'), '}, {') - .replaceAll(RegExp('/\]}/g'), '] }') - .replaceAll(RegExp('/":"/g'), '": "') - .replaceAll(RegExp(r'/":\[/g'), '": [') - .replaceAll(RegExp('/{"/g'), '{ "') - .replaceAll(RegExp('/"}/g'), '" }') - .replaceAll(RegExp('/,"/g'), ', "') - .replaceAll(RegExp('/","/g'), '", "') - .replaceAll(RegExp(r'/\[\[/g'), '[ [') - .replaceAll(RegExp('/\]\]/g'), '] ]') - .replaceAll(RegExp(r'/\["/g'), '\[ "') - .replaceAll(RegExp('/"\]/g'), '" \]') - .replaceAll(RegExp('/\[ +\]/g'), '\[\]') - .trim(); - // return compositevalue.replace(RegExp(/ +/g), ' '); - } - - static String prettyJson(Map json, {int indent = 4}) { - var spaces = ' ' * indent; - var encoder = JsonEncoder.withIndent(spaces); - return encoder.convert(json); - } - - static String translateMichelineToHex(String code) { - return ""; - } - - static String encodeTransaction(Transaction transaction) { - String hexString = writeInt(sepyTnoitarepo['transaction']); - hexString += writeAddress(transaction.source).substring(2); - hexString += writeInt(int.parse(transaction.fee)); - hexString += writeInt(int.parse(transaction.counter)); - hexString += writeInt(int.parse(transaction.gasLimit)); - hexString += writeInt(int.parse(transaction.storageLimit)); - hexString += writeInt(int.parse(transaction.amount)); - // hexString += writeInt(int.parse(transaction.destination)); - - if (transaction.contractParameters != null) { - ContractParameters composite = transaction.contractParameters; - - // TODO : TranslateMichelineToHex to be done - String code = normalizeMichelineWhiteSpace(jsonEncode(composite.value)); - String result = translateMichelineToHex(code); - - if ((composite.entrypoint == 'default' || composite.entrypoint == '') && - result == '030b') { - hexString += '00'; - } else { - hexString += 'ff'; - - if (composite.entrypoint == 'default' || composite.entrypoint == '') { - hexString += '00'; - } else if (composite.entrypoint == 'root') { - hexString += '01'; - } else if (composite.entrypoint == 'do') { - hexString += '02'; - } else if (composite.entrypoint == 'set_delegate') { - hexString += '03'; - } else if (composite.entrypoint == 'remove_delegate') { - hexString += '04'; - } else { - hexString += 'ff' + - ('0' + composite.entrypoint.length.toRadixString(16)) - .substring(2) + - composite.entrypoint - .split('') - .map((c) => c.codeUnitAt(0).toRadixString(16)) - .join(); - } - - if (result == '030b') { - hexString += '00'; - } else { - int resultLengthDiv2 = int.parse((result.length / 2).toString()); - String data = ('0000000' + resultLengthDiv2.toRadixString(16)); - hexString += data.substring(data.length - 8) + result; - } - } - } else { - hexString += '00'; - } - - return hexString; - } - - static String encodeOrigination(Origination origination) { - String hexString = writeInt(sepyTnoitarepo['origination']); - hexString = writeAddress(origination.source).substring(2); - hexString = writeInt(int.parse(origination.fee)); - hexString = writeInt(int.parse(origination.counter)); - hexString = writeInt(int.parse(origination.gasLimit)); - hexString = writeInt(int.parse(origination.storageLimit)); - hexString = writeInt(int.parse(origination.balance)); - - writeBoolean(bool value) => value ? "ff" : "00"; - - if (origination.delegate != null) { - hexString += writeBoolean(true); - hexString += writeAddress(origination.delegate).substring(2); - } else { - hexString += writeBoolean(false); - } - - if (origination.script) { - List parts = []; - parts.add(origination.script['code']); - parts.add(origination.script['storage']); - - /// TODO : Pending to review [normalizeMichelineWhiteSpace] and [translateMichelineToHex]. - // hexString += - // parts. - } - return hexString; - } - - static String encodeDelegation(Delegation delegation) { - String hexString = writeInt(sepyTnoitarepo['delegation']); - - /// Review [hexCode] - String hexCode = writeAddress(delegation.source); - hexString += hexCode.substring(2); - hexString += writeInt(int.parse(delegation.fee)); - hexString += writeInt(int.parse(delegation.counter)); - hexString += writeInt(int.parse(delegation.gasLimit)); - hexString += writeInt(int.parse(delegation.storageLimit)); - - //tobe moved to seperate file - writeBoolean(bool value) => value ? "ff" : "00"; - - if (delegation.delegate != null && delegation.delegate != "") { - hexString += writeBoolean(true); - // String writeAddressForDelegation = ; - hexString += writeAddress(delegation.delegate).substring(2); - } else { - hexString += writeBoolean(false); - } - - return hexString; - } - - static String encodeBallot(Ballot ballot) { - Uint8List writeBufferWithInt(String value) => bs58check.decode(value); - - String hexString = writeInt(sepyTnoitarepo['ballot']); - hexString += writeAddress(ballot.source).substring(2); - String ballotPeriodHexString = '00000000' + ballot.period.toRadixString(16); - hexString += - ballotPeriodHexString.substring(ballotPeriodHexString.length - 8); - - Uint8List ballotProposalList = writeBufferWithInt(ballot.proposal); - String ballotProposalHexString = hex.encode(ballotProposalList); - - hexString += ballotProposalHexString.substring(4); - String ballotVote = '00' + ballot.vote.toRadixString(16); - hexString += ballotVote.substring(ballotVote.length - 2); - return hexString; - } - - static writePublicKey(String publicKey) { - String _decodeAndAdd(String number) { - Uint8List publicKeyList = bs58check.decode(publicKey).sublist(4); - return number + hex.encode(publicKeyList); - } - - if (publicKey.startsWith("edpk")) { - return _decodeAndAdd("00"); - } else if (publicKey.startsWith("sppk")) { - return _decodeAndAdd("01"); - } else if (publicKey.startsWith("p2pk")) { - return _decodeAndAdd("02"); - } - } - - static String writeAddress(String address) { - Uint8List uintBsList = bs58check.decode(address).sublist(3); - // List bsList = List.from(uintBsList); - String hexString = hex.encode(uintBsList); - // print("hexString ===> $hexString"); - - if (address.startsWith("tz1")) { - return "0000" + hexString; - } else if (address.startsWith("tz2")) { - return "0001" + hexString; - } else if (address.startsWith("tz3")) { - return "0002" + hexString; - } else if (address.startsWith("KT1")) { - return "01" + hexString + "00"; - } else { - throw new ErrorDescription("Unrecognized address prefix: "); - } - } - - static forgeOperations({ - String branch, - dynamic operation, - }) { - String encoded = _writeBranch(branch); - print("encoded ===> $encoded"); - encoded += encodeOperationValue(operation); - // print("encoded ===> $newEncode"); - return encoded; - } - - static encodeOperationValue(operation) { - if (operation is Activation) { - return encodeActivation(Activation( - pkh: operation.pkh, - secret: operation.secret, - )); - } else if (operation is Reveal) { - return encodeReveal(Reveal( - source: operation.source, - fee: operation.fee, - counter: operation.counter, - gasLimit: operation.gasLimit, - publicKey: operation.publicKey, - storageLimit: operation.storageLimit, - )); - } else if (operation is Transaction) { - return encodeTransaction(Transaction( - amount: operation.amount, - counter: operation.counter, - destination: operation.destination, - contractParameters: operation.contractParameters, - fee: operation.fee, - gasLimit: operation.gasLimit, - source: operation.source, - storageLimit: operation.storageLimit, - )); - } else if (operation is Origination) { - return encodeOrigination(Origination( - source: operation.source, - balance: operation.balance, - counter: operation.counter, - fee: operation.fee, - gasLimit: operation.gasLimit, - storageLimit: operation.storageLimit, - delegate: operation.delegate, - delegatable: operation.delegatable, - managerPubkey: operation.managerPubkey, - script: operation.script, - spendable: operation.spendable, - )); - } else if (operation is Delegation) { - return encodeDelegation(Delegation( - source: operation.source, - fee: operation.fee, - counter: operation.counter, - gasLimit: operation.gasLimit, - storageLimit: operation.storageLimit, - delegate: operation.delegate, - )); - } else if (operation is Ballot) { - return encodeBallot(Ballot( - source: operation.source, - period: operation.period, - proposal: operation.proposal, - vote: operation.vote, - )); - } - } - - static String _writeBranch(String branch) { - Uint8List branchUint8List = bs58check.decode(branch).sublist(2); - String branchHexString = hex.encode(branchUint8List); - return branchHexString; - } - - /// TODO : Send Transaction Operation - static sendTransactionOperation({ - String server, - KeyStore keyStore, - String to, - int amount, - int fee, - String derivationPath = '', - }) async { - dynamic counter = await TezsterNodeReader.getCounterForAccount( - server: server, accountHash: keyStore.publicKeyHash) + - 1; - Transaction transaction = Transaction( - destination: to, - amount: amount.toString(), - storageLimit: 496.toString(), - gasLimit: 10600.toString(), - counter: counter.toString(), - fee: fee.toString(), - source: keyStore.publicKeyHash, - ); - - /// [appendRevealOperation] - dynamic transactionOperation = await appendRevealOperation( - server: server, - keyStore: keyStore, - accountHash: keyStore.publicKeyHash, - accountOperationIndex: counter - 1, - transactions: transaction, - ); - print("transactionOperation ===> ${transactionOperation.source}"); - - return sendOperation( - server, transactionOperation, keyStore, derivationPath); - } - - static sendOperation(String server, dynamic operations, KeyStore keyStore, - String derivationPath) async { - var blockHead = await TezsterNodeReader.getBlockHead(server: server); - print("blockHead ===> ${blockHead['hash']}"); - var forgedOperationGroup = - forgeOperations(branch: blockHead['hash'], operation: operations); - SignedOperationGroup signedOpGroup = await signOperationGroup( - forgedOperation: forgedOperationGroup, - privateKey: keyStore.privateKey, - derivationPath: derivationPath, - ); - print("signedOpGroup ===> ${signedOpGroup.signature}"); - - var injectedOperation = - await injectOperation(server: server, signedOpGroup: signedOpGroup); - - var appliedOp = await preapplyOperation( - server: server, - branch: blockHead['hash'], - protocol: blockHead['protocol'], - keyStore: keyStore, - signedOpGroup: signedOpGroup, - ); - print("appliedOp ===> $appliedOp"); - // server, blockHead.hash, blockHead.protocol, operations, signedOpGroup); - - /// TODO : Pending Task - return {"results": appliedOp[0], "operationGroupID": injectedOperation}; - } - - static Future injectOperation({ - String server, - SignedOperationGroup signedOpGroup, - String chainid = 'main', - }) { - var signedOpByteHex = hex.encode(signedOpGroup.bytes); - print("signedOpByteHex ===> $signedOpByteHex"); - var response = performPostRequest( - server: server, - command: "injection/operation?chain=$chainid", - payload: signedOpByteHex, - ); - print("response ===> $response"); - return response; - } - - static preapplyOperation({ - String server, - String branch, - String protocol, - KeyStore keyStore, - SignedOperationGroup signedOpGroup, - String chainid = 'main', - }) async { - List payload = [ - { - "protocol": protocol, - "branch": branch, - "contents": keyStore, - "signature": signedOpGroup.signature - } - ]; - var response = await performPostRequest( - server: server, - command: "chains/$chainid/blocks/head/helpers/preapply/operations", - payload: json.encode(payload), - ); - - return response; - } - - static appendRevealOperation({ - @required String server, - @required dynamic keyStore, - @required String accountHash, - @required int accountOperationIndex, - @required dynamic transactions, - }) async { - bool isKeyRevealed = await TezsterNodeReader.isManagerKeyRevealedForAccount( - server: server, accountHash: accountHash); - int counter = accountOperationIndex + 1; - - if (!isKeyRevealed) { - Reveal revealOp = Reveal( - source: accountHash, - fee: '0', - counter: counter.toString(), - gasLimit: '10600', - storageLimit: '0', - publicKey: keyStore.publicKey, - ); - - transactions.forEach((transaction, i) { - var c = accountOperationIndex + 2 + i; - transaction.counter = c.toString(); - }); - - return [revealOp, ...transactions]; - } - return transactions; - } -} - -enum StoreType { mnemonic, fundraiser, hardware } - -class KeyStore { - String publicKey; - String privateKey; - String publicKeyHash; - String seed; - String derivationPath; - StoreType storeType = StoreType.mnemonic; - KeyStore({ - this.publicKey, - this.privateKey, - this.publicKeyHash, - this.seed, - this.derivationPath, - this.storeType, - }); - - KeyStore.fromJson(Map json) { - publicKey = json['publicKey']; - privateKey = json['privateKey']; - publicKeyHash = json['publicKeyHash']; - seed = json['seed']; - derivationPath = json['derivationPath']; - storeType = json['storeType']; - } - - Map toJson() { - final Map data = new Map(); - data['publicKey'] = this.publicKey; - data['privateKey'] = this.privateKey; - data['publicKeyHash'] = this.publicKeyHash; - data['seed'] = this.seed; - data['derivationPath'] = this.derivationPath; - data['storeType'] = this.storeType; - return data; - } -} - -class SignedOperationGroup { - List bytes; - String signature; - SignedOperationGroup({this.bytes, this.signature}); -} - -class Activation { - String pkh; - String secret; - Activation({this.pkh, this.secret}); -} - -class Ballot { - String source; - int period; - String proposal; - //Review - int vote; - Ballot({this.source, this.period, this.proposal, this.vote}); -} - -// class BallotVote { -// int yay = 0; -// int nay = 1; -// int pass = 2; -// BallotVote({this.nay,this.pass,this.yay}); -// } - -class Transaction { - String source; - String fee; - String counter; - String gasLimit; - String storageLimit; - String amount; - String destination; - ContractParameters contractParameters; - Transaction({ - this.source, - this.fee, - this.counter, - this.gasLimit, - this.storageLimit, - this.amount, - this.destination, - this.contractParameters, - }); -} - -class ContractParameters { - String entrypoint; - dynamic value; - ContractParameters({ - this.entrypoint, - this.value, - }); -} - -class Delegation { - String source; - String fee; - String counter; - String gasLimit; - String storageLimit; - String delegate; - Delegation({ - this.source, - this.fee, - this.counter, - this.gasLimit, - this.storageLimit, - this.delegate, - }); -} - -class Reveal { - String source; - String fee; - String counter; - String gasLimit; - String storageLimit; - String publicKey; - Reveal({ - this.source, - this.fee, - this.counter, - this.gasLimit, - this.storageLimit, - this.publicKey, - }); -} - -class Origination { - String source; - String fee; - String counter; - String gasLimit; - String storageLimit; - String managerPubkey; // deprecated in P005 - String balance; - bool spendable; // deprecated in P005 - bool delegatable; // deprecated in P005 - String delegate; - dynamic script; - Origination({ - this.source, - this.fee, - this.counter, - this.gasLimit, - this.storageLimit, - this.managerPubkey, - this.balance, - this.spendable, - this.delegatable, - this.delegate, - this.script, - }); -} diff --git a/lib/src/tezsterSendOperation.dart b/lib/src/tezsterSendOperation.dart deleted file mode 100644 index 3cda9df..0000000 --- a/lib/src/tezsterSendOperation.dart +++ /dev/null @@ -1,593 +0,0 @@ -import 'dart:convert'; -import 'dart:typed_data'; - -import 'package:blake2b/blake2b_hash.dart'; -import 'package:flutter/material.dart'; -import 'package:flutter_sodium/flutter_sodium.dart'; - -import '../tezster_dart.dart'; -// import 'package:blake2b/blake2b_hash.dart'; -// import 'package:flutter/material.dart'; -import 'package:bs58check/bs58check.dart' as bs58check; -// import 'package:flutter_sodium/flutter_sodium.dart'; -import 'package:convert/convert.dart'; -import 'package:http/http.dart' as http; -import 'package:tezster_dart/tezster_dart.dart'; - -class TezsterSendOperation { - static performPostRequest({ - String server, - String command, - Object payload, - }) async { - assert(server != null); - assert(command != null); - String url = '$server/$command'; - try { - String payloadString = jsonEncode(payload); - http.Response data = await http.post( - url, - body: payloadString, - headers: { - 'content-type': 'application/json', - }, - ); - return data; - } catch (e) { - return {"message": "Something went wrong"}; - } - } - - static String _writeBranch(String branch) { - Uint8List branchUint8List = bs58check.decode(branch); - branchUint8List.sublist(2); - List branchListInt = List.from(branchUint8List); - String branchHexString = hex.encode(branchListInt); - return branchHexString; - } - - static forgeOperations({ - String branch, - dynamic operation, - }) { - String encoded = _writeBranch(branch); - print("encoded ===> $encoded"); - encoded += encodeOperationValue(operation); - // print("encoded ===> $newEncode"); - return encoded; - } - - static String twoByteHex(int n) { - if (n < 128) { - String hexString = "0" + n.toRadixString(16); - return hexString.substring(hexString.length - 2); - } - - String h = ''; - - if (n > 2147483648) { - BigInt r = BigInt.from(n); - while (r > BigInt.zero) { - //Review - String data = ('0' + r.toRadixString(16) + 127.toRadixString(16)); - h = data.substring(data.length - 2) + h; - r = r >> 7; - } - } else { - int r = n; - while (r > 0) { - // Review - String data = ('0' + (r & 127).toRadixString(16)); - h = data.substring(data.length - 2) + h; - r = r >> 7; - } - } - return h; - } - - static String writeInt(int value) { - if (value < 0) { - return "Use writeSignedInt to encode negative numbers"; - } - - String twoByteHexString = twoByteHex(value); - print("twoByteHexString ==> $twoByteHexString"); - - List hexStringToList = hex.decode(twoByteHexString); - print("hexStringToList ===> $hexStringToList"); - - Uint8List twoByteUint8List = Uint8List.fromList(hexStringToList); - print("twoByteUint8List ===> $twoByteUint8List"); - - Map mapData = twoByteUint8List.asMap(); - print("mapData ===> $mapData"); - - List hexList = []; - - mapData.forEach((key, value) { - var hexValue = key == 0 ? value : value ^ 0x80; - print(key.toString() + " " + value.toString()); - print(hexValue); - hexList.add(hexValue); - }); - print("hexList ===> $hexList"); - - List reversedList = (hexList.reversed).toList(); - - Uint8List conversion = Uint8List.fromList(reversedList); - print("conversion $conversion"); - - // String reversedIntListDataToHex = hex.encode(reversedList); - String reversedIntListDataToHex = hex.encode(conversion); - print("reversedIntListDataToHex ===> $reversedIntListDataToHex"); - - return reversedIntListDataToHex; - } - - static Map sepyTnoitarepo = { - 'endorsement': 0, - 'seedNonceRevelation': 1, - 'doubleEndorsementEvidence': 2, - 'doubleBakingEvidence': 3, - 'accountActivation': 4, - 'proposal': 5, - 'ballot': 6, - 'reveal': 7, - 'transaction': 8, - 'origination': 9, - 'delegation': 10, - 'Newreveal': 107, - 'Newtransaction': 108, - 'Neworigination': 109, - 'Newdelegation': 110 - }; - - static String writeAddress(String address) { - print("address ===> $address"); - Uint8List uintBsList = bs58check.decode(address).sublist(3); - // List bsList = List.from(uintBsList); - String hexString = hex.encode(uintBsList); - // print("hexString ===> $hexString"); - - if (address.startsWith("tz1")) { - return "0000" + hexString; - } else if (address.startsWith("tz2")) { - return "0001" + hexString; - } else if (address.startsWith("tz3")) { - return "0002" + hexString; - } else if (address.startsWith("KT1")) { - return "01" + hexString + "00"; - } else { - throw new ErrorDescription("Unrecognized address prefix: "); - } - } - - static String encodeTransaction(Transaction transaction) { - String hexString = writeInt(sepyTnoitarepo['transaction']); - hexString += writeAddress(transaction.source).substring(2); - hexString += writeInt(int.parse(transaction.fee)); - hexString += writeInt(int.parse(transaction.counter)); - hexString += writeInt(int.parse(transaction.gasLimit)); - hexString += writeInt(int.parse(transaction.storageLimit)); - hexString += writeInt(int.parse(transaction.amount)); - hexString += writeAddress(transaction.destination); - - if (transaction.contractParameters != null) { - ContractParameters composite = transaction.contractParameters; - - // TODO : TranslateMichelineToHex to be done - // String code = normalizeMichelineWhiteSpace(jsonEncode(composite.value)); - // String result = translateMichelineToHex(code); - String result = ""; - - if ((composite.entrypoint == 'default' || composite.entrypoint == '') && - result == '030b') { - hexString += '00'; - } else { - hexString += 'ff'; - - if (composite.entrypoint == 'default' || composite.entrypoint == '') { - hexString += '00'; - } else if (composite.entrypoint == 'root') { - hexString += '01'; - } else if (composite.entrypoint == 'do') { - hexString += '02'; - } else if (composite.entrypoint == 'set_delegate') { - hexString += '03'; - } else if (composite.entrypoint == 'remove_delegate') { - hexString += '04'; - } else { - hexString += 'ff' + - ('0' + composite.entrypoint.length.toRadixString(16)) - .substring(2) + - composite.entrypoint - .split('') - .map((c) => c.codeUnitAt(0).toRadixString(16)) - .join(); - } - - if (result == '030b') { - hexString += '00'; - } else { - int resultLengthDiv2 = int.parse((result.length / 2).toString()); - String data = ('0000000' + resultLengthDiv2.toRadixString(16)); - hexString += data.substring(data.length - 8) + result; - } - } - } else { - hexString += '00'; - } - - return hexString; - } - - static encodeOperationValue(operation) { - if (operation is Reveal) { - return encodeReveal(Reveal( - source: operation.source, - fee: operation.fee, - counter: operation.counter, - gasLimit: operation.gasLimit, - storageLimit: operation.storageLimit, - publicKey: operation.publicKey, - )); - } else if (operation is Transaction) { - return encodeTransaction(Transaction( - amount: operation.amount, - counter: operation.counter, - destination: operation.destination, - contractParameters: operation.contractParameters, - fee: operation.fee, - gasLimit: operation.gasLimit, - source: operation.source, - storageLimit: operation.storageLimit, - )); - } - } - - static sendTransactionOperation({ - String server, - KeyStore keyStore, - String to, - int amount, - int fee, - String derivationPath = '', - }) async { - dynamic counter = await TezsterNodeReader.getCounterForAccount( - server: server, accountHash: keyStore.publicKeyHash) + - 1; - print("counter ===> $counter"); - - Transaction transaction = Transaction( - destination: to, - amount: amount.toString(), - storageLimit: 496.toString(), - gasLimit: 10600.toString(), - counter: counter.toString(), - fee: fee.toString(), - source: keyStore.publicKeyHash, - ); - - /// [appendRevealOperation] - dynamic transactionOperation = await appendRevealOperation( - server: server, - keyStore: keyStore, - // accountHash: "tz1LoKbFyYHTkCnj9mgRKFb9g8pP4Lr3zniP", - accountHash: keyStore.publicKeyHash, - accountOperationIndex: counter - 1, - transactions: transaction, - ); - - print("transactionOperation ===> ${transactionOperation.source}"); - - return sendOperation( - server, transactionOperation, keyStore, derivationPath); - } - - static sendOperation(String server, Transaction operations, KeyStore keyStore, - String derivationPath) async { - var blockHead = await TezsterNodeReader.getBlockHead(server: server); - print("blockHead ===> ${blockHead['hash']}"); - var forgedOperationGroup = - forgeOperations(branch: blockHead['hash'], operation: operations); - print("forgedOperationGroup ==> $forgedOperationGroup"); - // var revealforgedOperationGroup = - // forgeOperations(branch: blockHead['head'], operation: revealOp); - // print("revealforgedOperationGroup ===> $revealforgedOperationGroup"); - SignedOperationGroup signedOpGroup = await signOperationGroup( - forgedOperation: forgedOperationGroup, - privateKey: keyStore.privateKey, - derivationPath: derivationPath, - ); - print("signedOpGroup ===> ${signedOpGroup.signature}"); - - var appliedOp = await preapplyOperation( - server: server, - branch: blockHead['hash'], - protocol: blockHead['protocol'], - transaction: operations, - keyStore: keyStore, - signedOpGroup: signedOpGroup, - ); - print("appliedOp ===> ${appliedOp.body.toString()}"); - - var injectedOperation = - await injectOperation(server: server, signedOpGroup: signedOpGroup); - print("injectedOperation ===> $injectedOperation"); - - /// TODO : Pending Task - /// "results": appliedOp[0], - return {"operationGroupID": injectedOperation}; - } - - static Future signOperationGroup({ - String forgedOperation, - String derivationPath, - String privateKey, - }) async { - assert(forgedOperation != null); - assert(privateKey != null); - - String watermarkedForgedOperationBytesHex = '03' + forgedOperation; - - /// converting String to HexString [waterMarkHexIntList] - List waterMarkHexIntList = - hex.decode(watermarkedForgedOperationBytesHex); - - /// converting List [waterMarkHexIntList] to Uint8List [waterMarkHexUint8List] - Uint8List waterMarkHexUint8List = Uint8List.fromList(waterMarkHexIntList); - - Uint8List hashedWatermarkedOpBytes = - await _simpleHash(waterMarkHexUint8List, 256); - Uint8List privateKeyBytes = _writeKeyWithHint(privateKey, "edsk"); - print("bs58List ===> ${privateKeyBytes.length}"); - - // Uint8List hashedWatermarkedOpBytesstring = await _simpleHash(privateKeyBytes,256); - - Uint8List opSignature = await Sodium.cryptoSignDetached( - hashedWatermarkedOpBytes, privateKeyBytes); - print("opSignature ===> $opSignature"); - - String hexSignature = _readSignatureWithHint(opSignature, 'edsig'); - print("hexString ===> $hexSignature"); - - List forgedOperationListInt = hex.decode(forgedOperation); - Uint8List forgedOperationUint8List = - Uint8List.fromList(forgedOperationListInt); - - List signedOpBytes = forgedOperationUint8List + opSignature; - - return SignedOperationGroup(bytes: signedOpBytes, signature: hexSignature); - -// Trial 2 - // List hexStringToListOfInt = - // hex.decode(watermarkedForgedOperationBytesHex); - // Uint8List hashedWatermarkedOpBytes = - // Blake2bHash.hashWithDigestSize(256, hexStringToListOfInt); - // Uint8List privateKeyBytes = bs58check.decode(privateKey); - // List pkB = List.from(privateKeyBytes); - // pkB.removeRange(0, 4); - // Uint8List finalPKb = Uint8List.fromList(pkB); - // Uint8List value = await Sodium.cryptoSignDetached( - // hashedWatermarkedOpBytes, - // finalPKb, - // useBackgroundThread: false, - // ); - // String opSignatureHex = hex.encode(value); - // String hexStringToEncode = '09f5cd8612' + opSignatureHex; - // Uint8List hexDeco = hex.decode(hexStringToEncode); - // String hexSignature = bs58check.encode(hexDeco); - // String signedOpBytes = forgedOperation + opSignatureHex; - // List signedOpBytestoList = hex.decode(signedOpBytes); - // return SignedOperationGroup( - // bytes: signedOpBytestoList, signature: hexSignature); - - /// Trial 1 - // String watermarkedForgedOperationBytesHex = "03" + forgedOperation; - // String stringToHexString = - // hex.encode(watermarkedForgedOperationBytesHex.codeUnits); - // // print(stringToHexString); - // List hexStringToListOfInt = hex.decode(stringToHexString); - // // print(hexStringToListOfInt); - // Uint8List hashedWatermarkedOpBytes = _simpleHash(hexStringToListOfInt, 256); - // print("hashedWatermarkedOpBytes ===> $hashedWatermarkedOpBytes"); - // print("hashedWatermarkedOpBytes ===> ${hashedWatermarkedOpBytes.length}"); - // Uint8List privateKeyBytes = _writeKeyWithHint(privateKey, "edsk"); - // print("bs58List ===> $privateKeyBytes"); - - // Uint8List opSignature = - // await _signDetach(hashedWatermarkedOpBytes, privateKeyBytes); - // print("opSignature ===> $opSignature"); - - // String hexString = _readSignatureWithHint(opSignature, 'edsig'); - // print("hexString ===> $hexString"); - - // List listforgedOperation = hex.decode(forgedOperation); - // Uint8List uint8ListforgedOperation = - // Uint8List.fromList(listforgedOperation); - // List signedOpBytes = uint8ListforgedOperation + opSignature; - // print("signedOpBytes ===> $signedOpBytes"); - - // return SignedOperationGroup(bytes: signedOpBytes, signature: hexString); - } - - static preapplyOperation({ - String server, - String branch, - String protocol, - Transaction transaction, - KeyStore keyStore, - SignedOperationGroup signedOpGroup, - String chainid = 'main', - }) async { - // Reveal revealOp = Reveal( - // counter: transaction.counter.toString(), - // fee: "0", - // gasLimit: 10600.toString(), - // source: keyStore.publicKeyHash, - // storageLimit: "0", - // publicKey: keyStore.publicKey, - // ); - // dynamic counter = await TezsterNodeReader.getCounterForAccount( - // server: server, accountHash: keyStore.publicKeyHash) + - // 1; - // print("counter ===> $counter"); - - // var counterVal = int.parse(counter); - - List payload = [ - { - "protocol": protocol, - "branch": branch, - "contents": [ - // { - // "kind": "reveal", - // "source": keyStore.publicKeyHash, - // "fee": "0", - // "counter": counter.toString(), - // "gas_limit": 10600.toString(), - // "storage_limit": "0", - // "public_key": keyStore.publicKey - // }, - { - "kind": "transaction", - "source": transaction.source, - "fee": transaction.fee, - "counter": transaction.counter, - "gas_limit": transaction.gasLimit, - "storage_limit": transaction.storageLimit, - "amount": transaction.amount, - "destination": transaction.destination, - } - ], - "signature": signedOpGroup.signature - } - ]; - print(json.encode(payload).toString()); - var response = await performPostRequest( - server: server, - command: "chains/$chainid/blocks/head/helpers/preapply/operations", - payload: payload, - ); - - return response; - } - - /// TODO: pending - static Future injectOperation({ - String server, - SignedOperationGroup signedOpGroup, - String chainid = 'main', - }) { - String signedOpByteHex = hex.encode(signedOpGroup.bytes); - print("signedOpByteHex ===> $signedOpByteHex"); - var response = performPostRequest( - server: server, - command: "injection/operation?chain=$chainid", - payload: signedOpByteHex, - ); - print("response ===> $response"); - return response; - } - - static writePublicKey(String publicKey) { - String _decodeAndAdd(String number) { - Uint8List publicKeyList = bs58check.decode(publicKey).sublist(4); - return number + hex.encode(publicKeyList); - } - - if (publicKey.startsWith("edpk")) { - return _decodeAndAdd("00"); - } else if (publicKey.startsWith("sppk")) { - return _decodeAndAdd("01"); - } else if (publicKey.startsWith("p2pk")) { - return _decodeAndAdd("02"); - } - } - - static String encodeReveal(Reveal reveal) { - String hexString = writeInt(sepyTnoitarepo['reveal']); - hexString += writeAddress(reveal.source).substring(2); - hexString += writeInt(int.parse(reveal.fee)); - hexString += writeInt(int.parse(reveal.counter)); - hexString += writeInt(int.parse(reveal.gasLimit)); - hexString += writeInt(int.parse(reveal.storageLimit)); - hexString += writePublicKey(reveal.publicKey); - return hexString; - } - - static appendRevealOperation({ - String server, - dynamic keyStore, - String accountHash, - int accountOperationIndex, - dynamic transactions, - }) async { - bool isKeyRevealed = await TezsterNodeReader.isManagerKeyRevealedForAccount( - server: server, accountHash: accountHash); - int counter = accountOperationIndex + 1; - - if (!isKeyRevealed) { - Reveal revealOp = Reveal( - source: accountHash, - fee: '0', - counter: counter.toString(), - gasLimit: '10600', - storageLimit: '0', - publicKey: keyStore.publicKey, - ); - - transactions.forEach((transaction, i) { - var c = accountOperationIndex + 2 + i; - transaction.counter = c.toString(); - }); - - return [revealOp, ...transactions]; - } - return transactions; - } -} - -Future _simpleHash(Uint8List payload, int digestSize) async { - // return await Sodium.cryptoGenerichash(digestSize, payload, null); - return Blake2bHash.hashWithDigestSize(digestSize, payload); -} - -Uint8List _writeKeyWithHint(String key, String hint) { - if (hint == "edsk" || hint == "edpk") { - print("key ===> $key"); - var bs58CheckDecodced = bs58check.decode(key); - print("bs58CheckDecodced ===> $bs58CheckDecodced"); - print( - "bs58check.encode(bs58CheckDecodced) ===> ${bs58check.encode(bs58CheckDecodced)}"); - print( - "hex.encode(bs58CheckDecodced) ===> ${hex.encode(bs58CheckDecodced)}"); - var data = hex.encode(bs58CheckDecodced).substring(8); - print("data ===> $data"); - var decodedData = hex.decode(data); - Uint8List bs58String = Uint8List.fromList(decodedData); - print("bs58String ===> $bs58String"); - return bs58String; - } else { - throw {"message": "Unrecognized key hint, '$hint'"}; - } -} - -// static Future _signDetach(Uint8List message, Uint8List sk) async { -// return Sodium.cryptoSignDetached(message, sk); -// } - -String _readSignatureWithHint(Uint8List payload, String hint) { - if (hint == 'edsig') { - List intConversionPayload = List.from(payload); - String encodedPayoad = hex.encode(intConversionPayload); - String concatEncodedPayload = '09f5cd8612' + encodedPayoad; - List hexPayloadListInt = hex.decode(concatEncodedPayload); - Uint8List finalHexPayloadUint8ListInt = - Uint8List.fromList(hexPayloadListInt); - - return bs58check.encode(finalHexPayloadUint8ListInt); - } else { - throw {"message": "Unrecognized key hint, '$hint'"}; - } -} diff --git a/lib/src/tezster_dart.dart b/lib/src/tezster_dart.dart index 4e924ad..ed978a8 100644 --- a/lib/src/tezster_dart.dart +++ b/lib/src/tezster_dart.dart @@ -26,12 +26,7 @@ class TezsterDart { assert(mnemonic != null); Uint8List seed = bip39.mnemonicToSeed(mnemonic); Uint8List seedLength32 = seed.sublist(0, 32); - // Map keys = - // await Sodium.cryptoSignSeedKeypair(seedLength32); KeyPair keyPair = Sodium.cryptoSignSeedKeypair(seedLength32); - // keyPair.pk - // Uint8List sk = keys['sk']; - // Uint8List pk = keys['pk']; String skKey = GenerateKeys.readKeysWithHint(keyPair.sk, '2bf64e07'); String pkKey = GenerateKeys.readKeysWithHint(keyPair.pk, '0d0f25d9'); String pkKeyHash = GenerateKeys.computeKeyHash(keyPair.pk); @@ -82,7 +77,6 @@ class TezsterDart { Uint8List value = Sodium.cryptoSignDetached( hashedWatermarkedOpBytes, finalPKb, - // useBackgroundThread: false, ); String opSignatureHex = hex.encode(value); String hexStringToEncode = '09f5cd8612' + opSignatureHex; @@ -113,8 +107,6 @@ class TezsterDart { String p = "mnemonic" + normString; Uint8List seed = PBKDF2(hashAlgorithm: sha512).generateKey(m, p, 2048, 32); KeyPair keyPair = Sodium.cryptoSignSeedKeypair(seed); - // Uint8List sk = keys['sk']; - // Uint8List pk = keys['pk']; String skKey = GenerateKeys.readKeysWithHint(keyPair.sk, '2bf64e07'); String pkKey = GenerateKeys.readKeysWithHint(keyPair.pk, '0d0f25d9'); String pkKeyHash = GenerateKeys.computeKeyHash(keyPair.pk); diff --git a/lib/tezster_dart.dart b/lib/tezster_dart.dart index 60be5c1..2e4ec75 100644 --- a/lib/tezster_dart.dart +++ b/lib/tezster_dart.dart @@ -1,131 +1,3 @@ library tezster_dart; -export 'src/tezster_dart.dart'; -export 'src/tezsterNodeReader.dart'; -export 'src/tezsterNodeWriter.dart'; -export 'src/tezsterSendOperation.dart'; - -// import 'dart:async'; -// import 'dart:convert'; -// import 'dart:typed_data'; -// import 'dart:core'; -// import 'package:blake2b/blake2b_hash.dart'; -// import 'package:crypto/crypto.dart'; -// import 'package:flutter/cupertino.dart'; -// import 'package:password_hash/password_hash.dart'; -// import 'helper/generateKeys.dart'; -// import 'package:bip39/bip39.dart' as bip39; -// import 'package:bs58check/bs58check.dart' as bs58check; -// import "package:unorm_dart/unorm_dart.dart" as unorm; -// import 'package:flutter_sodium/flutter_sodium.dart'; -// import 'package:convert/convert.dart'; -// import 'package:http/http.dart' as http; -// import 'helper/tezosMessageUtil.dart'; - -// part 'tezsterNodeReader.dart'; -// part 'tezsterNodeWriter.dart'; - -// class TezsterDart { -// static String generateMnemonic({int strength = 256}) { -// return bip39.generateMnemonic(strength: strength); -// } - -// static Future> getKeysFromMnemonic({ -// String mnemonic, -// }) async { -// assert(mnemonic != null); -// Uint8List seed = bip39.mnemonicToSeed(mnemonic); -// Uint8List seedLength32 = seed.sublist(0, 32); -// Map keys = -// await Sodium.cryptoSignSeedKeypair(seedLength32); -// Uint8List sk = keys['sk']; -// Uint8List pk = keys['pk']; -// String skKey = GenerateKeys.readKeysWithHint(sk, '2bf64e07'); -// String pkKey = GenerateKeys.readKeysWithHint(pk, '0d0f25d9'); -// String pkKeyHash = GenerateKeys.computeKeyHash(pk); -// return [skKey, pkKey, pkKeyHash]; -// } - -// static Future> getKeysFromMnemonicAndPassphrase({ -// String mnemonic, -// String passphrase, -// }) async { -// assert(mnemonic != null); -// assert(passphrase != null); -// return await _unlockKeys( -// passphrase: passphrase, -// mnemonic: mnemonic, -// ); -// } - -// static Future> unlockFundraiserIdentity({ -// String mnemonic, -// String email, -// String passphrase = "", -// }) async { -// assert(mnemonic != null); -// assert(email != null); -// return await _unlockKeys( -// email: email, -// passphrase: passphrase, -// mnemonic: mnemonic, -// ); -// } - -// static Future> signOperationGroup({ -// String privateKey, -// String forgedOperation, -// }) async { -// assert(privateKey != null); -// assert(forgedOperation != null); -// String watermarkedForgedOperationBytesHex = '03' + forgedOperation; -// List hexStringToListOfInt = -// hex.decode(watermarkedForgedOperationBytesHex); -// Uint8List hashedWatermarkedOpBytes = -// Blake2bHash.hashWithDigestSize(256, hexStringToListOfInt); -// Uint8List privateKeyBytes = bs58check.decode(privateKey); -// List pkB = List.from(privateKeyBytes); -// pkB.removeRange(0, 4); -// Uint8List finalPKb = Uint8List.fromList(pkB); -// Uint8List value = await Sodium.cryptoSignDetached( -// hashedWatermarkedOpBytes, -// finalPKb, -// useBackgroundThread: false, -// ); -// String opSignatureHex = hex.encode(value); -// String hexStringToEncode = '09f5cd8612' + opSignatureHex; -// Uint8List hexDeco = hex.decode(hexStringToEncode); -// String hexSignature = bs58check.encode(hexDeco); -// String signedOpBytes = forgedOperation + opSignatureHex; -// return [hexSignature, signedOpBytes]; -// } - -// static Future> _unlockKeys({ -// String mnemonic, -// String passphrase = "", -// String email = "", -// }) async { -// assert(mnemonic != null); -// assert(passphrase != null); - -// List stringNormalize(String stringToNormalize) { -// String normalizedString = unorm.nfkd(stringToNormalize); -// List stringToBuffer = utf8.encode(normalizedString); -// return stringToBuffer; -// } - -// List mnemonicsBuffer = stringNormalize(mnemonic); -// String m = String.fromCharCodes(mnemonicsBuffer); -// List normalizedPassphrase = stringNormalize("$email" + "$passphrase"); -// String normString = String.fromCharCodes(normalizedPassphrase); -// String p = "mnemonic" + normString; -// Uint8List seed = PBKDF2(hashAlgorithm: sha512).generateKey(m, p, 2048, 32); -// Map keys = await Sodium.cryptoSignSeedKeypair(seed); -// Uint8List sk = keys['sk']; -// Uint8List pk = keys['pk']; -// String skKey = GenerateKeys.readKeysWithHint(sk, '2bf64e07'); -// String pkKey = GenerateKeys.readKeysWithHint(pk, '0d0f25d9'); -// String pkKeyHash = GenerateKeys.computeKeyHash(pk); -// return [skKey, pkKey, pkKeyHash]; -// } -// } +export 'src/tezster_dart.dart'; \ No newline at end of file diff --git a/pubspec.lock b/pubspec.lock index 3dcd354..369c852 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -77,14 +77,7 @@ packages: name: crypto url: "https://pub.dartlang.org" source: hosted - version: "2.1.4" - ed25519: - dependency: "direct main" - description: - name: ed25519 - url: "https://pub.dartlang.org" - source: hosted - version: "0.0.1" + version: "2.1.5" fake_async: dependency: transitive description: @@ -117,7 +110,7 @@ packages: name: flutter_sodium url: "https://pub.dartlang.org" source: hosted - version: "0.1.8" + version: "0.1.9" flutter_test: dependency: "direct dev" description: flutter @@ -130,27 +123,6 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "0.1.2" - http: - dependency: "direct main" - description: - name: http - url: "https://pub.dartlang.org" - source: hosted - version: "0.12.1" - http_parser: - dependency: transitive - description: - name: http_parser - url: "https://pub.dartlang.org" - source: hosted - version: "3.1.4" - js: - dependency: "direct main" - description: - name: js - url: "https://pub.dartlang.org" - source: hosted - version: "0.6.2" matcher: dependency: transitive description: @@ -179,13 +151,6 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "1.8.0-nullsafety.1" - pedantic: - dependency: transitive - description: - name: pedantic - url: "https://pub.dartlang.org" - source: hosted - version: "1.9.0" pointycastle: dependency: transitive description: diff --git a/pubspec.yaml b/pubspec.yaml index 9d3cadf..423891d 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,7 +1,7 @@ name: tezster_dart description: A flutter package which provides the functionalities to play around with tezos dApps -version: 1.0.0 +version: 1.0.1 homepage: https://github.com/Tezsure/tezster_dart repository: https://github.com/Tezsure/tezster_dart issue_tracker: https://github.com/Tezsure/tezster_dart/issues @@ -16,11 +16,8 @@ dependencies: blake2b: ^0.1.2 bs58check: ^1.0.1 convert: ^2.1.1 - crypto: ^2.1.4 - ed25519: ^0.0.1 - flutter_sodium: ^0.1.8 - http: ^0.12.1 - js: ^0.6.2 + crypto: ^2.1.5 + flutter_sodium: ^0.1.9 password_hash: ^2.0.0 unorm_dart: ^0.1.2