mirror of
https://github.com/cypherstack/stack_wallet.git
synced 2025-02-02 03:06:29 +00:00
receive nano transactions
This commit is contained in:
parent
97ecb72ecf
commit
c5f2480634
2 changed files with 43 additions and 60 deletions
|
@ -1 +1 @@
|
||||||
Subproject commit 73d257ed2fe5b204cf3589822e226301b187b86d
|
Subproject commit 81659ce57952c5ab54ffe6bacfbf43da159fff3e
|
|
@ -206,7 +206,7 @@ class NanoWallet extends CoinServiceAPI
|
||||||
final String linkAsAccount = txData["address"].toString();
|
final String linkAsAccount = txData["address"].toString();
|
||||||
|
|
||||||
// construct the send block:
|
// construct the send block:
|
||||||
final Map<String, String> sendBlock = {
|
Map<String, String> sendBlock = {
|
||||||
"type": "state",
|
"type": "state",
|
||||||
"account": publicAddress,
|
"account": publicAddress,
|
||||||
"previous": frontier,
|
"previous": frontier,
|
||||||
|
@ -233,24 +233,15 @@ class NanoWallet extends CoinServiceAPI
|
||||||
throw Exception("Failed to get PoW for send block");
|
throw Exception("Failed to get PoW for send block");
|
||||||
}
|
}
|
||||||
|
|
||||||
// process the send block:
|
sendBlock["link_as_account"] = linkAsAccount;
|
||||||
final Map<String, String> finalSendBlock = {
|
sendBlock["signature"] = signature;
|
||||||
"type": "state",
|
sendBlock["work"] = work;
|
||||||
"account": publicAddress,
|
|
||||||
"previous": frontier,
|
|
||||||
"representative": representative,
|
|
||||||
"balance": balanceAfterTx.toString(),
|
|
||||||
"link": link,
|
|
||||||
"link_as_account": linkAsAccount,
|
|
||||||
"signature": signature,
|
|
||||||
"work": work,
|
|
||||||
};
|
|
||||||
|
|
||||||
final processBody = jsonEncode({
|
final processBody = jsonEncode({
|
||||||
"action": "process",
|
"action": "process",
|
||||||
"json_block": "true",
|
"json_block": "true",
|
||||||
"subtype": "send",
|
"subtype": "send",
|
||||||
"block": finalSendBlock,
|
"block": sendBlock,
|
||||||
});
|
});
|
||||||
final processResponse = await http.post(
|
final processResponse = await http.post(
|
||||||
Uri.parse(getCurrentNode().host),
|
Uri.parse(getCurrentNode().host),
|
||||||
|
@ -323,6 +314,9 @@ class NanoWallet extends CoinServiceAPI
|
||||||
|
|
||||||
Future<void> receiveBlock(
|
Future<void> receiveBlock(
|
||||||
String blockHash, String source, String amountRaw) async {
|
String blockHash, String source, String amountRaw) async {
|
||||||
|
// TODO: the opening block of an account is a special case
|
||||||
|
bool openBlock = false;
|
||||||
|
|
||||||
// our address:
|
// our address:
|
||||||
final String publicAddress = await getAddressFromMnemonic();
|
final String publicAddress = await getAddressFromMnemonic();
|
||||||
|
|
||||||
|
@ -358,79 +352,62 @@ class NanoWallet extends CoinServiceAPI
|
||||||
body: infoBody,
|
body: infoBody,
|
||||||
);
|
);
|
||||||
|
|
||||||
final String frontier =
|
String frontier = jsonDecode(infoResponse.body)["frontier"].toString();
|
||||||
jsonDecode(infoResponse.body)["frontier"].toString();
|
|
||||||
final String representative =
|
final String representative =
|
||||||
jsonDecode(infoResponse.body)["representative"].toString();
|
jsonDecode(infoResponse.body)["representative"].toString();
|
||||||
|
|
||||||
// link = destination address:
|
// link = send block hash:
|
||||||
final String link =
|
final String link = blockHash;
|
||||||
NanoAccounts.extractPublicKey(source);
|
// this "linkAsAccount" is meaningless:
|
||||||
final String linkAsAccount = source;
|
final String linkAsAccount =
|
||||||
|
NanoAccounts.createAccount(NanoAccountType.NANO, blockHash);
|
||||||
// construct the send block:
|
|
||||||
final Map<String, String> sendBlock = {
|
|
||||||
"type": "state",
|
|
||||||
"account": publicAddress,
|
|
||||||
"previous": frontier,
|
|
||||||
"representative": representative,
|
|
||||||
"balance": balanceAfterTx.toString(),
|
|
||||||
"link": link,
|
|
||||||
};
|
|
||||||
|
|
||||||
// sign the send block:
|
|
||||||
final String hash = NanoBlocks.computeStateHash(
|
|
||||||
NanoAccountType.NANO,
|
|
||||||
sendBlock["account"]!,
|
|
||||||
sendBlock["previous"]!,
|
|
||||||
sendBlock["representative"]!,
|
|
||||||
BigInt.parse(sendBlock["balance"]!),
|
|
||||||
sendBlock["link"]!,
|
|
||||||
);
|
|
||||||
final String privateKey = await getPrivateKeyFromMnemonic();
|
|
||||||
final String signature = NanoSignatures.signBlock(hash, privateKey);
|
|
||||||
|
|
||||||
// construct the receive block:
|
// construct the receive block:
|
||||||
Map<String, String> receiveBlock = {
|
Map<String, String> receiveBlock = {
|
||||||
"type": "state",
|
"type": "state",
|
||||||
"account": publicAddress,
|
"account": publicAddress,
|
||||||
"previous": frontier,
|
"previous": openBlock
|
||||||
|
? "0000000000000000000000000000000000000000000000000000000000000000"
|
||||||
|
: frontier,
|
||||||
"representative": representative,
|
"representative": representative,
|
||||||
"balance": balanceAfterTx.toString(),
|
"balance": balanceAfterTx.toString(),
|
||||||
"link": link,
|
"link": link,
|
||||||
"link_as_account": linkAsAccount,
|
"link_as_account": linkAsAccount,
|
||||||
"signature": signature,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// sign the receive block:
|
// sign the receive block:
|
||||||
|
final String hash = NanoBlocks.computeStateHash(
|
||||||
|
NanoAccountType.NANO,
|
||||||
|
receiveBlock["account"]!,
|
||||||
|
receiveBlock["previous"]!,
|
||||||
|
receiveBlock["representative"]!,
|
||||||
|
BigInt.parse(receiveBlock["balance"]!),
|
||||||
|
receiveBlock["link"]!,
|
||||||
|
);
|
||||||
|
final String privateKey = await getPrivateKeyFromMnemonic();
|
||||||
|
final String signature = NanoSignatures.signBlock(hash, privateKey);
|
||||||
|
|
||||||
// get PoW for the receive block:
|
// get PoW for the receive block:
|
||||||
final String? work = await requestWork(frontier);
|
String? work;
|
||||||
|
if (openBlock) {
|
||||||
|
work = await requestWork(NanoAccounts.extractPublicKey(publicAddress));
|
||||||
|
} else {
|
||||||
|
work = await requestWork(frontier);
|
||||||
|
}
|
||||||
if (work == null) {
|
if (work == null) {
|
||||||
throw Exception("Failed to get PoW for receive block");
|
throw Exception("Failed to get PoW for receive block");
|
||||||
}
|
}
|
||||||
|
receiveBlock["link_as_account"] = linkAsAccount;
|
||||||
|
receiveBlock["signature"] = signature;
|
||||||
receiveBlock["work"] = work;
|
receiveBlock["work"] = work;
|
||||||
|
|
||||||
// process the receive block:
|
// process the receive block:
|
||||||
|
|
||||||
final Map<String, String> finalReceiveBlock = {
|
|
||||||
"type": "state",
|
|
||||||
"account": publicAddress,
|
|
||||||
"previous": frontier,
|
|
||||||
"representative": representative,
|
|
||||||
"balance": balanceAfterTx.toString(),
|
|
||||||
"link": link,
|
|
||||||
"link_as_account": linkAsAccount,
|
|
||||||
"signature": signature,
|
|
||||||
"work": work,
|
|
||||||
};
|
|
||||||
|
|
||||||
final processBody = jsonEncode({
|
final processBody = jsonEncode({
|
||||||
"action": "process",
|
"action": "process",
|
||||||
"json_block": "true",
|
"json_block": "true",
|
||||||
"subtype": "receive",
|
"subtype": "receive",
|
||||||
"block": finalReceiveBlock,
|
"block": receiveBlock,
|
||||||
});
|
});
|
||||||
final processResponse = await http.post(
|
final processResponse = await http.post(
|
||||||
Uri.parse(getCurrentNode().host),
|
Uri.parse(getCurrentNode().host),
|
||||||
|
@ -450,11 +427,15 @@ class NanoWallet extends CoinServiceAPI
|
||||||
headers: {"Content-Type": "application/json"},
|
headers: {"Content-Type": "application/json"},
|
||||||
body: jsonEncode({
|
body: jsonEncode({
|
||||||
"action": "receivable",
|
"action": "receivable",
|
||||||
|
"source": "true",
|
||||||
"account": await getAddressFromMnemonic(),
|
"account": await getAddressFromMnemonic(),
|
||||||
"count": "-1",
|
"count": "-1",
|
||||||
}));
|
}));
|
||||||
|
|
||||||
final receivableData = await jsonDecode(receivableResponse.body);
|
final receivableData = await jsonDecode(receivableResponse.body);
|
||||||
|
if (receivableData["blocks"] == "") {
|
||||||
|
return;
|
||||||
|
}
|
||||||
final blocks = receivableData["blocks"] as Map<String, dynamic>;
|
final blocks = receivableData["blocks"] as Map<String, dynamic>;
|
||||||
// confirm all receivable blocks:
|
// confirm all receivable blocks:
|
||||||
for (final blockHash in blocks.keys) {
|
for (final blockHash in blocks.keys) {
|
||||||
|
@ -462,6 +443,8 @@ class NanoWallet extends CoinServiceAPI
|
||||||
final String amountRaw = block["amount"] as String;
|
final String amountRaw = block["amount"] as String;
|
||||||
final String source = block["source"] as String;
|
final String source = block["source"] as String;
|
||||||
await receiveBlock(blockHash, source, amountRaw);
|
await receiveBlock(blockHash, source, amountRaw);
|
||||||
|
// a bit of a hack:
|
||||||
|
await Future<void>.delayed(const Duration(seconds: 1));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue