reorganizing because zx needs to feel special
This commit is contained in:
@@ -0,0 +1,6 @@
|
||||
*.swp
|
||||
*.swo
|
||||
src/jx_include
|
||||
dist/
|
||||
erl_crash.dump
|
||||
src/jex_include
|
||||
@@ -0,0 +1,16 @@
|
||||
ISC License
|
||||
|
||||
Copyright (c) 2022 Peter Harpending
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
|
||||
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
|
||||
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
||||
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
||||
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
all: prepare build
|
||||
|
||||
prepare:
|
||||
jx pull -f
|
||||
|
||||
build:
|
||||
jx build -f
|
||||
|
||||
serve:
|
||||
python3 -m http.server 8001
|
||||
@@ -0,0 +1,90 @@
|
||||
# sidekick examples
|
||||
|
||||
# TODO
|
||||
|
||||
- form a spend transaction
|
||||
- transfer money on testnet
|
||||
- retrieve transaction info
|
||||
|
||||
# Build Prereqs
|
||||
|
||||
Assuming Ubuntu 18.04. Adapt these instructions for your own system.
|
||||
|
||||
You need
|
||||
|
||||
- `npm` to build TypeScript
|
||||
- `tsc` to compile
|
||||
- [`jx`][jx] to orchestrate the build properly
|
||||
- [sidekick][sk] as a dependency
|
||||
- Python 3.6 or later to run `jx`
|
||||
|
||||
[jx]: https://gitlab.com/pharpend/jx/-/tree/master/#jx-secure-typescript-package-manager
|
||||
|
||||
Steps
|
||||
|
||||
# install node and tsc
|
||||
sudo snap refresh
|
||||
sudo snap install node --channel 18/stable
|
||||
npm install -g typescript
|
||||
# install dependencies
|
||||
mkdir vanillae && cd vanillae
|
||||
git clone https://gitlab.com/pharpend/jx
|
||||
git clone https://gitlab.com/pharpend/sidekick
|
||||
chmod u+x ~/.local/bin/jx
|
||||
git clone https
|
||||
|
||||
|
||||
|
||||
## Protip: avoid using `sudo npm install -g`
|
||||
|
||||
If you want to avoid using sudo
|
||||
|
||||
```
|
||||
mkdir ~/.npm-packages
|
||||
npm config set prefix "${HOME}/.npm-packages"
|
||||
```
|
||||
|
||||
Edit `~/.bashrc` or `~/.zshrc` with
|
||||
|
||||
```
|
||||
NPM_PACKAGES="${HOME}/.npm-packages"
|
||||
export PATH=$NPM_PACKAGES/bin:$PATH
|
||||
```
|
||||
|
||||
## How to build
|
||||
|
||||
You need
|
||||
|
||||
- [TypeScript compiler `tsc`](https://www.typescriptlang.org/download)
|
||||
- [HTTP logging server vlogd](https://gitlab.com/pharpend/vlogd)
|
||||
- [Build tool `jx`](https://gitlab.com/pharpend/jx)
|
||||
- Build [sidekick](https://gitlab.com/pharpend/sidekick) separately
|
||||
- Python 3.6 or later
|
||||
- `make`
|
||||
|
||||
#### Build
|
||||
|
||||
You need to build [sidekick](https://gitlab.com/pharpend/sidekick) separately
|
||||
|
||||
```
|
||||
make
|
||||
```
|
||||
|
||||
#### View
|
||||
|
||||
Many of the examples assume there is an HTTP server at `localhost:8841`
|
||||
which responds positively to POST requests at `/`
|
||||
|
||||
[vlogd](https://gitlab.com/pharpend/vlogd) is such a server, but you can roll
|
||||
your own if you want.
|
||||
|
||||
```
|
||||
make serve
|
||||
firefox localhost:8001
|
||||
```
|
||||
|
||||
|
||||
|
||||
# Build
|
||||
|
||||
make
|
||||
@@ -0,0 +1,88 @@
|
||||
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Sidekick Example: Connecting to Wallet</title>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<!-- link tree -->
|
||||
<ul><li>
|
||||
<a href="/">Examples</a>
|
||||
<ul><li>
|
||||
<b>Connecting to wallet</b>
|
||||
</li></ul>
|
||||
</li></ul>
|
||||
|
||||
<h1>Sidekick Example: Connecting to wallet</h1>
|
||||
|
||||
<h1>Page variables</h1>
|
||||
|
||||
<ol>
|
||||
<li>Wallet Address: <code class="pv-address"></code></li>
|
||||
<li>SpendTx Base58: <code class="pv-spendtx-base58"></code></li>
|
||||
</ol>
|
||||
|
||||
<!-- step 1 detect -->
|
||||
|
||||
<h1>1. Detect wallet</h1>
|
||||
<button id="detect">Detect</button>
|
||||
<h4 id="detected" style="color: red;">not detected</h4>
|
||||
<pre id="detect-info"></pre>
|
||||
|
||||
<h1>2. Connect to wallet</h1>
|
||||
<button id="connect">Connect</button>
|
||||
<h4 id="connected" style="color: red;">not connected</h4>
|
||||
<pre id="connect-info"></pre>
|
||||
|
||||
<h1>3. Get the wallet address</h1>
|
||||
<button id="address">Address</button>
|
||||
<h4 id="addressed" style="color: red;">not addressed</h4>
|
||||
<pre id="address-info"></pre>
|
||||
|
||||
<h1>4. Sign a transaction</h1>
|
||||
|
||||
<h2>4.1 Transaction info (information needed from you)</h2>
|
||||
|
||||
<ol>
|
||||
<li>Source address (step 3): <code class="pv-address"></code></li>
|
||||
<li>Target address: <input type="text" id="tx-info-target" value="ak_wM8yFU8eSETXU7VSN48HMDmevGoCMiuveQZgkPuRn1nTiRqyv"></input></li>
|
||||
<li>Amount (aettos): <input type="text" id="tx-info-amount" value="10"></input></li>
|
||||
<li>Network: (FIXME: radio buttons)</li>
|
||||
</ol>
|
||||
|
||||
|
||||
<h2>4.2 Form transaction (using parasite)</h2>
|
||||
|
||||
<p>This uses a shim JavaScript library called parasite to form the transaction
|
||||
data for the wallet to sign. In a commercial application, this should be done
|
||||
by your backend</p>
|
||||
|
||||
<button id='mk-spendtx'>Make SpendTx</button>
|
||||
|
||||
<h5>SpendTx JS object</h5>
|
||||
<pre id="spendtx-json"></pre>
|
||||
|
||||
<h5>SpendTx Base58</h5>
|
||||
<pre class="pv-spendtx-base58"></pre>
|
||||
|
||||
<h2>4.3 Sign the transaction (sidekick)</h2>
|
||||
|
||||
<ol>
|
||||
<li><pre class="pv-spendtx-base58"></pre></li>
|
||||
</ol>
|
||||
|
||||
<button id="sign-spendtx">Sign Transaction</button>
|
||||
|
||||
<h5>Result:</h5>
|
||||
<pre id="sign-spendtx-result"></pre>
|
||||
|
||||
<h2>4.4 Propagate the transaction (parasite)</h2>
|
||||
|
||||
<h2>4.5 Verify the transaction was propagated (parasite)</h2>
|
||||
|
||||
<!-- script -->
|
||||
<script type="module" src="dist/connection.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 4.1 KiB |
@@ -0,0 +1,32 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Sidekick Example: Hello World</title>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<!-- Link tree -->
|
||||
<ul><li>
|
||||
<a href="../">Examples</a>
|
||||
<ul><li>
|
||||
<b>Hello world</b>
|
||||
</li></ul>
|
||||
</li></ul>
|
||||
|
||||
|
||||
<h1>Sidekick Example: Hello World</h1>
|
||||
|
||||
<h4>Check the console</h4>
|
||||
|
||||
<p>
|
||||
This example just demonstrates how to import sidekick and call functions
|
||||
from the module. Useful for debugging purposes, or getting out of mental
|
||||
quicksand.
|
||||
</p>
|
||||
|
||||
|
||||
<!-- script -->
|
||||
<script type="module" src="./dist/hello.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,25 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Sidekick Examples: Home</title>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<!-- link tree -->
|
||||
<ul><li>
|
||||
<b>Examples</b>
|
||||
</li></ul>
|
||||
|
||||
<h1>Sidekick Examples</h1>
|
||||
<ol>
|
||||
<li><a href="./hello.html">Hello World</a></li>
|
||||
<!--
|
||||
<li><a href="./logging.html">Console Logging</a></li>
|
||||
<li><a href="./logging_http.html">HTTP Logging</a></li>
|
||||
<li><a href="./detection.html">Detecting Wallet</a></li>
|
||||
-->
|
||||
<li><a href="./connection.html">Connecting to Wallet</a></li>
|
||||
</ol>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,7 @@
|
||||
{type, site}.
|
||||
{realm, local}.
|
||||
{name, sk_examples}.
|
||||
{version, "0.1.0"}.
|
||||
{deps, ["local-awcp-0.1.0",
|
||||
"local-parasite-0.1.0",
|
||||
"local-sidekick-0.1.0"]}.
|
||||
@@ -0,0 +1,32 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Sidekick Example: console logger</title>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<!-- link tree -->
|
||||
<ul><li>
|
||||
<a href="/">Examples</a>
|
||||
<ul><li>
|
||||
<b>Logging</b>
|
||||
</li></ul>
|
||||
</li></ul>
|
||||
|
||||
<h1>Sidekick Example: console logger</h1>
|
||||
|
||||
<h4>check the console</h4>
|
||||
|
||||
<p>
|
||||
This example illustrates a debugging feature of sidekick. Sidekick
|
||||
and the wallet each communicate with the other by sending
|
||||
<code>MessageEvent</code>s to <code>window</code>. The code in this example
|
||||
adds a listener to the <code>window</code> which just
|
||||
<code>console.log</code>s each <code>MessageEvent</code>.
|
||||
</p>
|
||||
|
||||
<!-- script -->
|
||||
<script type="module" src="dist/logging.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,6 @@
|
||||
import * as sk from './jx_include/ppr-sidekick-0.1.0/dist/sidekick.js'
|
||||
|
||||
let logger = new sk.ConsoleLogger();
|
||||
logger.listen(window);
|
||||
|
||||
window.postMessage("I have questions regarding my vehicle's extended warranty.");
|
||||
@@ -0,0 +1,28 @@
|
||||
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Sidekick Example: HTTP logger</title>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<!-- link tree -->
|
||||
<ul><li>
|
||||
<a href="/">Examples</a>
|
||||
<ul><li>
|
||||
<b>HTTP Logging</b>
|
||||
</li></ul>
|
||||
</li></ul>
|
||||
|
||||
<h1>Sidekick Example: HTTP Logger</h1>
|
||||
|
||||
<p>
|
||||
You need to have an HTTP server listening on port <code>8841</code>. You
|
||||
can use <a href="https://gitlab.com/pharpend/vlogd">vlogd</a>.
|
||||
</p>
|
||||
|
||||
<!-- script -->
|
||||
<script type="module" src="dist/logging_http.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,23 @@
|
||||
import * as sk from './jx_include/ppr-sidekick-0.1.0/dist/sidekick.js'
|
||||
|
||||
//var body_count = 1;
|
||||
//
|
||||
//function
|
||||
//message_event_to_request
|
||||
// (evt : {data: object})
|
||||
//{
|
||||
// let url = 'http://localhost:8841/';
|
||||
// let body = JSON.stringify(evt.data, undefined, 4);
|
||||
// let result = new Request(url, {method: 'POST', body: body});
|
||||
// return result;
|
||||
//}
|
||||
|
||||
let cl = new sk.ConsoleLogger();
|
||||
cl.listen(window);
|
||||
|
||||
let hl = new sk.HttpLogger('http://localhost:8841/');
|
||||
hl.listen(window);
|
||||
|
||||
let logger = new sk.SeqLogger([cl, hl]);
|
||||
|
||||
window.postMessage("I have questions regarding my vehicle's extended warranty.");
|
||||
@@ -0,0 +1,219 @@
|
||||
import * as ae_node from './jex_include/local-parasite-0.1.0/dist/ae_node.js';
|
||||
import * as awcp from './jex_include/local-awcp-0.1.0/dist/awcp.js';
|
||||
import * as sk from './jex_include/local-sidekick-0.1.0/dist/sidekick.js';
|
||||
|
||||
var pv_address: string;
|
||||
var pv_spendtx_base58: string;
|
||||
|
||||
function
|
||||
set_pv_address
|
||||
(new_address: string)
|
||||
: void
|
||||
{
|
||||
pv_address = new_address;
|
||||
for (let elt of document.getElementsByClassName('pv-address'))
|
||||
{
|
||||
elt.innerHTML = new_address;
|
||||
}
|
||||
}
|
||||
|
||||
function
|
||||
set_pv_spendtx_base58
|
||||
(new_address: string)
|
||||
: void
|
||||
{
|
||||
pv_spendtx_base58 = new_address;
|
||||
for (let elt of document.getElementsByClassName('pv-spendtx-base58'))
|
||||
{
|
||||
elt.innerHTML = new_address;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
async function
|
||||
detect
|
||||
(logger: sk.Logger)
|
||||
: Promise<void>
|
||||
{
|
||||
let h4 = document.getElementById("detected")!;
|
||||
let pre = document.getElementById("detect-info")!;
|
||||
|
||||
h4.innerHTML = 'detecting...';
|
||||
h4.style.color = 'GoldenRod';
|
||||
|
||||
// try to detect the wallet
|
||||
// will fail on timeout error
|
||||
// console logger
|
||||
let maybe_wallet_info =//: sk.Safe<awcp.EventData_W2A_connection_announcePresence, sk.TimeoutError> =
|
||||
await sk.detect(sk.TIMEOUT_DEF_DETECT_MS, "failed to detect wallet", logger);
|
||||
|
||||
console.log(maybe_wallet_info);
|
||||
|
||||
// ok means wallet was detected
|
||||
if (maybe_wallet_info.ok)
|
||||
{
|
||||
h4.innerHTML = "detected";
|
||||
h4.style.color = "green";
|
||||
pre.innerHTML = JSON.stringify(maybe_wallet_info.result, undefined, 4);
|
||||
}
|
||||
else
|
||||
{
|
||||
h4.innerHTML = "error";
|
||||
h4.style.color = "crimson";
|
||||
pre.innerHTML = JSON.stringify(maybe_wallet_info.error, undefined, 4);
|
||||
}
|
||||
}
|
||||
|
||||
async function
|
||||
connect
|
||||
(logger: sk.Logger)
|
||||
: Promise<void>
|
||||
{
|
||||
// this is not working
|
||||
// I am creating and posting an identical message to the working example
|
||||
// it must be a mismatch in the extraneous properties of the MessageEvent that is causing the problem
|
||||
let h4 = document.getElementById("connected")!;
|
||||
let pre = document.getElementById("connect-info")!;
|
||||
|
||||
h4.innerHTML = 'connecting...';
|
||||
h4.style.color = 'GoldenRod';
|
||||
|
||||
// try to connect to the wallet
|
||||
// will fail on timeout error
|
||||
// console logger
|
||||
let maybe_wallet_info = await sk.connect(
|
||||
'ske-connect-1',
|
||||
{name: 'sidekick examples',
|
||||
version: 1},
|
||||
sk.TIMEOUT_DEF_CONNECT_MS,
|
||||
"failed to connect to wallet",
|
||||
logger
|
||||
);
|
||||
|
||||
console.log(maybe_wallet_info);
|
||||
|
||||
// ok means wallet was connected
|
||||
if (maybe_wallet_info.ok)
|
||||
{
|
||||
h4.innerHTML = "connected";
|
||||
h4.style.color = "green";
|
||||
pre.innerHTML = JSON.stringify(maybe_wallet_info.result, undefined, 4);
|
||||
}
|
||||
else
|
||||
{
|
||||
h4.innerHTML = "error";
|
||||
h4.style.color = "crimson";
|
||||
pre.innerHTML = JSON.stringify(maybe_wallet_info.error, undefined, 4);
|
||||
}
|
||||
}
|
||||
|
||||
async function
|
||||
address
|
||||
(logger: sk.Logger)
|
||||
: Promise<void>
|
||||
{
|
||||
// this is not working
|
||||
// I am creating and posting an identical message to the working example
|
||||
// it must be a mismatch in the extraneous properties of the MessageEvent that is causing the problem
|
||||
let h4 = document.getElementById("addressed")!;
|
||||
let pre = document.getElementById("address-info")!;
|
||||
|
||||
h4.innerHTML = 'addressing...';
|
||||
h4.style.color = 'GoldenRod';
|
||||
|
||||
// try to address to the wallet
|
||||
// will fail on timeout error
|
||||
// console logger
|
||||
let maybe_wallet_info = await sk.address(
|
||||
'ske-address-1',
|
||||
{type: 'subscribe',
|
||||
value: 'connected'},
|
||||
sk.TIMEOUT_DEF_ADDRESS_MS,
|
||||
"failed to address to wallet",
|
||||
logger
|
||||
);
|
||||
|
||||
console.log(maybe_wallet_info);
|
||||
|
||||
// ok means wallet was addressed
|
||||
if (maybe_wallet_info.ok)
|
||||
{
|
||||
h4.innerHTML = "addressed";
|
||||
h4.style.color = "green";
|
||||
pre.innerHTML = JSON.stringify(maybe_wallet_info.result, undefined, 4);
|
||||
// update global variable
|
||||
let the_address = Object.keys(maybe_wallet_info.result.address.current)[0];
|
||||
set_pv_address(the_address);
|
||||
}
|
||||
else
|
||||
{
|
||||
h4.innerHTML = "error";
|
||||
h4.style.color = "crimson";
|
||||
pre.innerHTML = JSON.stringify(maybe_wallet_info.error, undefined, 4);
|
||||
}
|
||||
}
|
||||
|
||||
async function
|
||||
form_tx
|
||||
(logger: sk.Logger)
|
||||
: Promise<void>
|
||||
{
|
||||
// @ts-ignore
|
||||
let recipient_id = document.getElementById('tx-info-target')!.value;
|
||||
// @ts-ignore
|
||||
let amount = parseInt(document.getElementById('tx-info-amount')!.value);
|
||||
let fee = ae_node.MIN_FEE;
|
||||
let sender_id = pv_address;
|
||||
let payload = 'hainana';
|
||||
let spendtx = {recipient_id : recipient_id,
|
||||
amount : amount,
|
||||
fee : fee,
|
||||
sender_id : sender_id,
|
||||
payload : payload};
|
||||
document.getElementById('spendtx-json')!.innerHTML =
|
||||
JSON.stringify(spendtx, undefined, 4);
|
||||
let tx = await ae_node.PostSpend(ae_node.URL_TESTNET, spendtx);
|
||||
// @ts-ignore
|
||||
set_pv_spendtx_base58(tx.tx);
|
||||
//document.getElementById('spendtx-base58')!.innerHTML =
|
||||
// JSON.stringify(tx, undefined, 4);
|
||||
//
|
||||
}
|
||||
|
||||
async function
|
||||
sign_tx
|
||||
(logger: sk.Logger)
|
||||
: Promise<void>
|
||||
{
|
||||
let sign_params = {
|
||||
tx: pv_spendtx_base58,
|
||||
// returnsigned: false tells it to propagate the transaction
|
||||
// returnsigned: true just signs it and returns the signed tx back
|
||||
returnSigned: true as true,
|
||||
networkId: "ae_uat"
|
||||
};
|
||||
let signedTx = await sk.tx_sign_noprop('sk-tx-sign-1', sign_params, sk.TIMEOUT_DEF_TX_SIGN_NOPROP_MS, 'sign transaction timed out', logger);
|
||||
document.getElementById("sign-spendtx-result")!.innerHTML = JSON.stringify(signedTx, undefined, 4);
|
||||
}
|
||||
|
||||
function
|
||||
main
|
||||
()
|
||||
{
|
||||
// want to create a logger down here
|
||||
let logger = sk.cl();
|
||||
// custom logger
|
||||
window.addEventListener('message', function(evt) { if("to_waellet" === evt.data.type) {console.log(evt)} });
|
||||
// the !s are typescript jizz to turn off the warning that the return value
|
||||
// of getElementById might be null
|
||||
document.getElementById('detect')!.onclick = function() { detect(logger); } ;
|
||||
document.getElementById('connect')!.onclick = function() { connect(logger); };
|
||||
document.getElementById('address')!.onclick = function() { address(logger); };
|
||||
document.getElementById('mk-spendtx')!.onclick = function() { form_tx(logger); };
|
||||
document.getElementById('sign-spendtx')!.onclick = function() { sign_tx(logger); };
|
||||
|
||||
//set_pv_address("ak_2XhCkjzTwcq1coXSSzHJoMZkUzTwnjH88zmPGkkowUsFNTo9UE");
|
||||
}
|
||||
|
||||
main();
|
||||
@@ -0,0 +1,3 @@
|
||||
import * as sk from './jex_include/local-sidekick-0.1.0/dist/sidekick.js';
|
||||
|
||||
sk.hello();
|
||||
@@ -0,0 +1,16 @@
|
||||
{"compilerOptions" : {"target" : "es2022",
|
||||
"strict" : true,
|
||||
"esModuleInterop" : true,
|
||||
"skipLibCheck" : true,
|
||||
"forceConsistentCasingInFileNames" : true,
|
||||
"noImplicitAny" : true,
|
||||
"strictNullChecks" : true,
|
||||
"strictPropertyInitialization" : true,
|
||||
"sourceMap" : true,
|
||||
"outDir" : "dist",
|
||||
"declaration" : true},
|
||||
"$schema" : "https://json.schemastore.org/tsconfig",
|
||||
"display" : "Recommended",
|
||||
"include" : ["src/**/*"],
|
||||
"exclude" : ["src/jex_include"],
|
||||
"composite" : true}
|
||||
Reference in New Issue
Block a user