[broken] jr: add spend feature
It does not work right now, and the blocker right now is that the public node has debug endpoints turned off. No idea if it would work if said endpoints were turned on.
This commit is contained in:
@@ -141,6 +141,30 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- spend -->
|
||||||
|
<div class="psection">
|
||||||
|
<table >
|
||||||
|
<tr>
|
||||||
|
<td><img src="../art/keypair.svg" style="width: 32px; height: 32px;"></td>
|
||||||
|
<td style="justify-content: center; font-size: 28px; text-align: center; font-weight: bold">
|
||||||
|
SEND SOMEONE MONEY
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
<form id="spend-params">
|
||||||
|
<label for="spend-recipient">Recipient Address:</label>
|
||||||
|
<input id="spend-recipient"></input>
|
||||||
|
<br>
|
||||||
|
<label for="spend-amount">Amount (gattos):</label>
|
||||||
|
<input id="spend-amount"></input>
|
||||||
|
<br>
|
||||||
|
<button type="button" id="spend-btn">Send</button>
|
||||||
|
</form>
|
||||||
|
|
||||||
|
<p id='spend-result'></p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<pre id="scratch"></pre>
|
<pre id="scratch"></pre>
|
||||||
|
|||||||
+218
-17
@@ -6,6 +6,10 @@ import * as b_lib from './b_lib.js';
|
|||||||
|
|
||||||
p_main();
|
p_main();
|
||||||
|
|
||||||
|
let EXPLORER_URL = 'https://explorer.qpq.swiss';
|
||||||
|
|
||||||
|
let active_account_next_nonce = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* runs whenever the popup opens
|
* runs whenever the popup opens
|
||||||
*
|
*
|
||||||
@@ -33,6 +37,8 @@ p_main
|
|||||||
console.log('popup main');
|
console.log('popup main');
|
||||||
await pi_repop();
|
await pi_repop();
|
||||||
|
|
||||||
|
let pdata = await b_lib.p_get_data();
|
||||||
|
|
||||||
|
|
||||||
// add unique name for default
|
// add unique name for default
|
||||||
let unique_name: string = await b_lib.p_get_unique_name();
|
let unique_name: string = await b_lib.p_get_unique_name();
|
||||||
@@ -70,6 +76,73 @@ p_main
|
|||||||
document
|
document
|
||||||
.getElementById('faert-btn')!
|
.getElementById('faert-btn')!
|
||||||
.addEventListener('click', onclick_gphrase);
|
.addEventListener('click', onclick_gphrase);
|
||||||
|
|
||||||
|
// spend
|
||||||
|
let onclick_spend =
|
||||||
|
async function () {
|
||||||
|
console.log('onclick_spend');
|
||||||
|
// grab recipient address
|
||||||
|
// @ts-ignore fuck off it's my website
|
||||||
|
let recip_address = document.getElementById('spend-recipient').value;
|
||||||
|
// grab recipient amount and parse
|
||||||
|
// @ts-ignore fuck off it's my website
|
||||||
|
let amount = parseInt(document.getElementById('spend-amount').value);
|
||||||
|
let source = active_account(pdata);
|
||||||
|
|
||||||
|
console.log('onclick_spend params', {recipient: recip_address, amount: amount, source: source});
|
||||||
|
|
||||||
|
// hack
|
||||||
|
if ('' === source) {
|
||||||
|
console.log('onclick_spend no active key');
|
||||||
|
// HACK: otherwise populate field with no key
|
||||||
|
let spend_result_p = document.getElementById('spend-result')!;
|
||||||
|
spend_result_p.innerHTML = 'ERROR: no active key';
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
let maybe_hash = await do_spend(source, recip_address, amount);
|
||||||
|
console.log('onclick_spend maybe_hash', maybe_hash);
|
||||||
|
if (maybe_hash.ok) {
|
||||||
|
// @ts-ignore fuck off
|
||||||
|
let tx_hash = maybe_hash.tx_hash;
|
||||||
|
// @ts-ignore fuck off
|
||||||
|
let spend_result_p = document.getElementById('spend-result')!;
|
||||||
|
let spend_result_a = document.createElement('a')!;
|
||||||
|
spend_result_a.href = EXPLORER_URL + '/transactions/' + tx_hash;
|
||||||
|
spend_result_a.innerHTML = tx_hash;
|
||||||
|
spend_result_p.appendChild(spend_result_a);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// @ts-ignore fuck off
|
||||||
|
let reason = maybe_hash.reason;
|
||||||
|
let spend_result_p = document.getElementById('spend-result')!;
|
||||||
|
spend_result_p.innerHTML = 'ERROR: ' + reason;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
document
|
||||||
|
.getElementById('spend-btn')!
|
||||||
|
.addEventListener('click', onclick_spend);
|
||||||
|
}
|
||||||
|
|
||||||
|
function
|
||||||
|
active_account
|
||||||
|
(pdata: b_lib.p_data)
|
||||||
|
: string
|
||||||
|
{
|
||||||
|
// type p_data
|
||||||
|
// = {rich_pubkeys: Array<p_rich_pubkey>,
|
||||||
|
// netid_cur : string,
|
||||||
|
// netids_alt : Array<string>};
|
||||||
|
// type p_rich_pubkey
|
||||||
|
// = {akstr : string,
|
||||||
|
// active : boolean,
|
||||||
|
// name : string};
|
||||||
|
for (let rkp of pdata.rich_pubkeys) {
|
||||||
|
if (rkp.active)
|
||||||
|
return rkp.akstr;
|
||||||
|
}
|
||||||
|
|
||||||
|
return '';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -216,8 +289,17 @@ pi_repop
|
|||||||
pi_balance(this_rkp.akstr).then(
|
pi_balance(this_rkp.akstr).then(
|
||||||
function(maybe_balance) {
|
function(maybe_balance) {
|
||||||
// if there is a balance, show it in green
|
// if there is a balance, show it in green
|
||||||
|
// also make nonce nonce if account is active
|
||||||
if (maybe_balance.ok)
|
if (maybe_balance.ok)
|
||||||
{
|
{
|
||||||
|
if (this_rkp.active) {
|
||||||
|
// @ts-ignore fuck off i know what i'm doing
|
||||||
|
let nonce = maybe_balance.nonce;
|
||||||
|
active_account_next_nonce = nonce;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
let greentext = document.createElement('span');
|
let greentext = document.createElement('span');
|
||||||
greentext.classList.add('balance-found');
|
greentext.classList.add('balance-found');
|
||||||
// @ts-ignore fuck off i know what i'm doing
|
// @ts-ignore fuck off i know what i'm doing
|
||||||
@@ -226,8 +308,12 @@ pi_repop
|
|||||||
bal_li.appendChild(greentext);
|
bal_li.appendChild(greentext);
|
||||||
}
|
}
|
||||||
// if not, show reason and make it red
|
// if not, show reason and make it red
|
||||||
|
// also make nonce 0 if account is active
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
if (this_rkp.active) {
|
||||||
|
active_account_next_nonce = 0;
|
||||||
|
}
|
||||||
let redtext = document.createElement('span');
|
let redtext = document.createElement('span');
|
||||||
redtext.classList.add('balance-not-found');
|
redtext.classList.add('balance-not-found');
|
||||||
// @ts-ignore fuck off i know what i'm doing
|
// @ts-ignore fuck off i know what i'm doing
|
||||||
@@ -313,20 +399,134 @@ pi_repop
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//async function
|
async function
|
||||||
//mk_spend
|
do_spend
|
||||||
// (source : string,
|
(source : string,
|
||||||
// recipient : string,
|
recipient : string,
|
||||||
// amount : number)
|
amount : number)
|
||||||
//{
|
: Promise< {ok : true,
|
||||||
// let nonce: number = await get_nonce(source);
|
tx_hash : string}
|
||||||
//}
|
| {ok : false,
|
||||||
//
|
reason : string}
|
||||||
//async function
|
>
|
||||||
//get_nonce
|
{
|
||||||
// (source: string)
|
console.log('popup do_spend', {source: source, recipient: recipient, amount: amount});
|
||||||
//{
|
let maybe_spendtx = await mk_spend(source, recipient, amount);
|
||||||
//}
|
if (maybe_spendtx.ok) {
|
||||||
|
return await post_spend(maybe_spendtx.tx);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// @ts-ignore fuck off
|
||||||
|
return maybe_spendtx;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function
|
||||||
|
post_spend
|
||||||
|
(tx: string)
|
||||||
|
: Promise< {ok : true,
|
||||||
|
tx_hash : string}
|
||||||
|
| {ok : false,
|
||||||
|
reason : string}
|
||||||
|
>
|
||||||
|
{
|
||||||
|
console.log('popup post_spend', tx);
|
||||||
|
let req_obj = {tx: tx};
|
||||||
|
let req_body = JSON.stringify(req_obj, undefined, 4);
|
||||||
|
let endpoint_init_url = 'https://demonet.qpq.swiss/v2';
|
||||||
|
let this_endpoint = endpoint_init_url + '/transactions';
|
||||||
|
// fetch: https://developer.mozilla.org/en-US/docs/Web/API/fetch
|
||||||
|
let response = await fetch(this_endpoint, {method: 'POST', body: req_body});
|
||||||
|
let return_data = await response.json();
|
||||||
|
console.log('popup post_spend return data', return_data);
|
||||||
|
// 200 = ok
|
||||||
|
// 400 = bad tx
|
||||||
|
switch (response.status) {
|
||||||
|
case 200:
|
||||||
|
// get the hash
|
||||||
|
// @ts-ignore talking to foreign api
|
||||||
|
return {ok: true, tx_hash: return_data.tx_hash};
|
||||||
|
// wtf
|
||||||
|
default:
|
||||||
|
// @ts-ignore talking to foreign api
|
||||||
|
return {ok: false, reason: return_data.reason};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let MIN_FEE = 17000;
|
||||||
|
|
||||||
|
async function
|
||||||
|
mk_spend
|
||||||
|
(source : string,
|
||||||
|
recipient : string,
|
||||||
|
amount : number)
|
||||||
|
: Promise< {ok : true,
|
||||||
|
tx : string}
|
||||||
|
| {ok : false,
|
||||||
|
reason : string}
|
||||||
|
>
|
||||||
|
{
|
||||||
|
console.log('popup mk_spend', {source: source, recipient: recipient, amount: amount});
|
||||||
|
let nonce: number = active_account_next_nonce;
|
||||||
|
let req_obj = {recipient_id : recipient,
|
||||||
|
amount : amount,
|
||||||
|
fee : MIN_FEE,
|
||||||
|
ttl : 0,
|
||||||
|
sender_id : source,
|
||||||
|
nonce : nonce,
|
||||||
|
payload : ''};
|
||||||
|
console.log('popup mk_spend req_obj', req_obj);
|
||||||
|
let req_body = JSON.stringify(req_obj, undefined, 4);
|
||||||
|
console.log('popup mk_spend req_body', req_body);
|
||||||
|
|
||||||
|
let endpoint_init_url = 'https://demonet.qpq.swiss/v2';
|
||||||
|
let this_endpoint = endpoint_init_url + '/debug/transactions/spend';
|
||||||
|
|
||||||
|
// fetch: https://developer.mozilla.org/en-US/docs/Web/API/fetch
|
||||||
|
let response = await fetch(this_endpoint, {method: 'POST', body: req_body, headers: [['Content-Type', 'application/json']]});
|
||||||
|
let return_data = await response.json();
|
||||||
|
console.log('popup mk_spend return data', return_data);
|
||||||
|
|
||||||
|
// 200 = ok
|
||||||
|
// 400 = pubkey malformed
|
||||||
|
// 404 = account dne
|
||||||
|
switch (response.status) {
|
||||||
|
case 200:
|
||||||
|
// get the nonce
|
||||||
|
// @ts-ignore talking to foreign api
|
||||||
|
return {ok: true, tx: return_data.tx};
|
||||||
|
// wtf
|
||||||
|
default:
|
||||||
|
// @ts-ignore talking to foreign api
|
||||||
|
return {ok: false, reason: return_data.reason};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function
|
||||||
|
get_nonce
|
||||||
|
(source: string)
|
||||||
|
: Promise<number>
|
||||||
|
{
|
||||||
|
console.log('popup get_nonce', source);
|
||||||
|
let endpoint_init_url = 'https://demonet.qpq.swiss/v2';
|
||||||
|
let this_endpoint = endpoint_init_url + '/accounts/' + source;
|
||||||
|
// fetch: https://developer.mozilla.org/en-US/docs/Web/API/fetch
|
||||||
|
let response = await fetch(this_endpoint);
|
||||||
|
// 200 = ok
|
||||||
|
// 400 = pubkey malformed
|
||||||
|
// 404 = account dne
|
||||||
|
switch (response.status) {
|
||||||
|
case 200:
|
||||||
|
// unstringify the body
|
||||||
|
let return_data = await response.json();
|
||||||
|
console.log('popup get_nonce return data', return_data);
|
||||||
|
// get the nonce
|
||||||
|
// @ts-ignore talking to foreign api
|
||||||
|
return return_data.nonce;
|
||||||
|
// wtf
|
||||||
|
default:
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* get account balance of ak_... str
|
* get account balance of ak_... str
|
||||||
@@ -335,14 +535,14 @@ async function
|
|||||||
pi_balance
|
pi_balance
|
||||||
(akstr : string)
|
(akstr : string)
|
||||||
: Promise< {ok : true,
|
: Promise< {ok : true,
|
||||||
balance : string}
|
balance : string,
|
||||||
|
nonce : number}
|
||||||
| {ok : false,
|
| {ok : false,
|
||||||
reason : string}
|
reason : string}
|
||||||
>
|
>
|
||||||
{
|
{
|
||||||
let endpoint_init_url = 'https://demonet.qpq.swiss/v2';
|
let endpoint_init_url = 'https://demonet.qpq.swiss/v2';
|
||||||
let this_endpoint = endpoint_init_url + '/accounts/' + akstr;
|
let this_endpoint = endpoint_init_url + '/accounts/' + akstr;
|
||||||
let input_params = {pubkey: akstr};
|
|
||||||
// fetch: https://developer.mozilla.org/en-US/docs/Web/API/fetch
|
// fetch: https://developer.mozilla.org/en-US/docs/Web/API/fetch
|
||||||
let response = await fetch(this_endpoint);
|
let response = await fetch(this_endpoint);
|
||||||
// 200 = ok
|
// 200 = ok
|
||||||
@@ -357,7 +557,8 @@ pi_balance
|
|||||||
// @ts-ignore talking to foreign api
|
// @ts-ignore talking to foreign api
|
||||||
let balance = return_data.balance.toString();
|
let balance = return_data.balance.toString();
|
||||||
return {ok : true,
|
return {ok : true,
|
||||||
balance : balance};
|
balance : balance,
|
||||||
|
nonce : return_data.nonce};
|
||||||
// pubkey malformed
|
// pubkey malformed
|
||||||
case 400:
|
case 400:
|
||||||
return {ok : false,
|
return {ok : false,
|
||||||
|
|||||||
Reference in New Issue
Block a user