diff --git a/libs/awcp/README.md b/libs/awcp/README.md index d42c369..9c53409 100644 --- a/libs/awcp/README.md +++ b/libs/awcp/README.md @@ -1,3 +1,3 @@ # awcp (package documentation) -Please click the word "(Documentation)" in the sidebar +Please click the word "Documentation" in the sidebar diff --git a/libs/awcp/src/awcp.ts b/libs/awcp/src/awcp.ts index 9b1a687..5eefa0a 100644 --- a/libs/awcp/src/awcp.ts +++ b/libs/awcp/src/awcp.ts @@ -206,7 +206,7 @@ */ // TODONE: enumerate RPC errors -// TODO: examples +// TODONE: examples // TODO: transaction.sign and propagate // TODO: constants for method names @@ -529,7 +529,6 @@ type RpcCall * and I hit "deny". This is what was sent back. Code `4` corresponds to * {@link ERROR_CODE_RpcRejectedByUserError}. * - * @example * ```ts * // layer 3: RPC * {jsonrpc : "2.0", @@ -756,7 +755,7 @@ type Params_A2W_connection_open /** * Result type of "connection.open" call * - * Same as `Params_W2A_connection_open` empirically + * Same as {@link Params_W2A_connection_announcePresence} empirically * * (layer 4) * @@ -1076,6 +1075,34 @@ type EventData_A2W_address_subscribe * } * } * ``` + * + * @example + * Case of many keypairs, the current one will be in `current`. + * ```json + * { + * "type": "to_aepp", + * "data": { + * "jsonrpc": "2.0", + * "id": "ske-address-1", + * "method": "address.subscribe", + * "result": { + * "subscription": [ + * "connected" + * ], + * "address": { + * "current": { + * "ak_2RT9RPbcX8RtjBpMWqsKtVRVKASAbj8V4c3f7cCdJfuVdihhyL": {} + * }, + * "connected": { + * "ak_sMM2sUiyeBeMiRAj8viHVCVDxevmCacALhoHdrkobyhoqnR85": {}, + * "ak_o355SAx4n1V6xbrYv4Zaxm7GAYaZwEFXwgKBVEQTSm8MPnwjn": {}, + * "ak_2Up7dDMVBbPc4xAequf41zyzBqwWpUcVTYvcGF1ApAcCy7nGfA": {} + * } + * } + * } + * } + * } + * ``` */ type EventData_W2A_address_subscribe = EventData_W2A; @@ -1092,6 +1119,15 @@ type EventData_W2A_address_subscribe * If `returnSigned` is `false`, then Superhero will propagate the transaction. * * (layer 4) + * + * @example + * ```json + * { + * "tx": "tx_+FgMAaEBuzbuuWjOzR7ecjOY8+u7HdNk0KoxTQcCDerZELEQ+UShAXtm5sMFBwg25Ol5IFI9w+pZy7/YbFi6BwPqi80KuKdsCoYPJvVhyAAAAYdoYWluYW5h9uAnNQ==", + * "returnSigned": true, + * "networkId": "ae_uat" + * } + * ``` */ type Params_A2W_tx_sign_noprop = {tx : string, @@ -1104,6 +1140,11 @@ type Params_A2W_tx_sign_noprop * Success result type for "transaction.sign" (do not propagate) * * (layer 4) + * + * @example + * { + * "signedTransaction": "tx_+KILAfhCuEDxWnvffMvyrkFWnrImYej38rh99vM9f6pORl/yWTvU97nvUcY8/ck8lgtPA8w5odGSDb9LGY/JSZXsmsXhgKkHuFr4WAwBoQG7Nu65aM7NHt5yM5jz67sd02TQqjFNBwIN6tkQsRD5RKEBe2bmwwUHCDbk6XkgUj3D6lnLv9hsWLoHA+qLzQq4p2wKhg8m9WHIAAABh2hhaW5hbmF7X54G" + * } */ type Result_W2A_tx_sign_noprop = {signedTransaction : string}; @@ -1113,6 +1154,20 @@ type Result_W2A_tx_sign_noprop * Request type for "transaction.sign" (do not propagate) * * (layer 3) + * + * @example + * ```json + * { + * "jsonrpc": "2.0", + * "id": "sk-tx-sign-1", + * "method": "transaction.sign", + * "params": { + * "tx": "tx_+FgMAaEBuzbuuWjOzR7ecjOY8+u7HdNk0KoxTQcCDerZELEQ+UShAXtm5sMFBwg25Ol5IFI9w+pZy7/YbFi6BwPqi80KuKdsCoYPJvVhyAAAAYdoYWluYW5h9uAnNQ==", + * "returnSigned": true, + * "networkId": "ae_uat" + * } + * } + * ``` */ type RpcCall_A2W_tx_sign_noprop = RpcCall<"transaction.sign", @@ -1124,6 +1179,18 @@ type RpcCall_A2W_tx_sign_noprop * Response type for "transaction.sign" (do not propagate) * * (layer 3) + * + * @example + * ```json + * { + * "jsonrpc": "2.0", + * "id": "sk-tx-sign-1", + * "method": "transaction.sign", + * "result": { + * "signedTransaction": "tx_+KILAfhCuEDxWnvffMvyrkFWnrImYej38rh99vM9f6pORl/yWTvU97nvUcY8/ck8lgtPA8w5odGSDb9LGY/JSZXsmsXhgKkHuFr4WAwBoQG7Nu65aM7NHt5yM5jz67sd02TQqjFNBwIN6tkQsRD5RKEBe2bmwwUHCDbk6XkgUj3D6lnLv9hsWLoHA+qLzQq4p2wKhg8m9WHIAAABh2hhaW5hbmF7X54G" + * } + * } + * ``` */ type RpcResp_W2A_tx_sign_noprop = RpcResp<"transaction.sign", @@ -1135,6 +1202,23 @@ type RpcResp_W2A_tx_sign_noprop * Event data for aepp-to-waellet "transaction.sign" (do not propagate) message * * (layer 2) + * + * @example + * ```json + * { + * "type": "to_waellet", + * "data": { + * "jsonrpc": "2.0", + * "id": "sk-tx-sign-1", + * "method": "transaction.sign", + * "params": { + * "tx": "tx_+FgMAaEBuzbuuWjOzR7ecjOY8+u7HdNk0KoxTQcCDerZELEQ+UShAXtm5sMFBwg25Ol5IFI9w+pZy7/YbFi6BwPqi80KuKdsCoYPJvVhyAAAAYdoYWluYW5h9uAnNQ==", + * "returnSigned": true, + * "networkId": "ae_uat" + * } + * } + * } + * ``` */ type EventData_A2W_tx_sign_noprop = EventData_A2W; @@ -1142,9 +1226,24 @@ type EventData_A2W_tx_sign_noprop /** - * Event data for aepp-to-waellet "transaction.sign" (do not propagate) response + * Event data for waellet-to-aepp "transaction.sign" (do not propagate) response * * (layer 2) + * + * @example + * ```json + * { + * "type": "to_aepp", + * "data": { + * "jsonrpc": "2.0", + * "id": "sk-tx-sign-1", + * "method": "transaction.sign", + * "result": { + * "signedTransaction": "tx_+KILAfhCuEDxWnvffMvyrkFWnrImYej38rh99vM9f6pORl/yWTvU97nvUcY8/ck8lgtPA8w5odGSDb9LGY/JSZXsmsXhgKkHuFr4WAwBoQG7Nu65aM7NHt5yM5jz67sd02TQqjFNBwIN6tkQsRD5RKEBe2bmwwUHCDbk6XkgUj3D6lnLv9hsWLoHA+qLzQq4p2wKhg8m9WHIAAABh2hhaW5hbmF7X54G" + * } + * } + * } + * ``` */ type EventData_W2A_tx_sign_noprop = EventData_W2A; @@ -1157,14 +1256,15 @@ type EventData_W2A_tx_sign_noprop /** * Parameters for "message.sign" * - * FIXME: example - * - * ```ts - * {message : 'hello world', - * onAccount : 'ak_...'} - * ``` - * * (layer 4) + * + * @example + * ```json + * { + * "onAccount": "ak_2RT9RPbcX8RtjBpMWqsKtVRVKASAbj8V4c3f7cCdJfuVdihhyL", + * "message": "MESSSSSSSSSSAGGGGGGGGGGGGGGGGGGGGGGGGGGGE" + * } + * ``` */ type Params_A2W_msg_sign = {message : string, @@ -1176,15 +1276,35 @@ type Params_A2W_msg_sign * Success result type for "message.sign" * * (layer 4) + * + * @example + * ```json + * { + * "signature": "3ec195484965a60dd4179fbb616947a85e4e9961cb468816a2a22870382954bc374f8569e4ddc729dfc1b14e09e670b7d2c70c33c592caca29ff6c212f1f8b0f" + * } + * ``` */ type Result_W2A_msg_sign = {signature : string}; /** - * Request type for "message.sign" (do not propagate) + * Request type for "message.sign" * * (layer 3) + * + * @example + * ```json + * { + * "jsonrpc": "2.0", + * "id": "sk-msg-sign-1", + * "method": "message.sign", + * "params": { + * "onAccount": "ak_2RT9RPbcX8RtjBpMWqsKtVRVKASAbj8V4c3f7cCdJfuVdihhyL", + * "message": "MESSSSSSSSSSAGGGGGGGGGGGGGGGGGGGGGGGGGGGE" + * } + * } + * ``` */ type RpcCall_A2W_msg_sign = RpcCall<"message.sign", @@ -1193,9 +1313,21 @@ type RpcCall_A2W_msg_sign /** - * Response type for "message.sign" (do not propagate) + * Response type for "message.sign" * * (layer 3) + * + * @example + * ```json + * { + * "jsonrpc": "2.0", + * "id": "sk-msg-sign-1", + * "method": "message.sign", + * "result": { + * "signature": "3ec195484965a60dd4179fbb616947a85e4e9961cb468816a2a22870382954bc374f8569e4ddc729dfc1b14e09e670b7d2c70c33c592caca29ff6c212f1f8b0f" + * } + * } + * ``` */ type RpcResp_W2A_msg_sign = RpcResp<"message.sign", @@ -1204,9 +1336,25 @@ type RpcResp_W2A_msg_sign /** - * Event data for aepp-to-waellet "message.sign" (do not propagate) message + * Event data for aepp-to-waellet "message.sign" * * (layer 2) + * + * @example + * ```json + * { + * "type": "to_waellet", + * "data": { + * "jsonrpc": "2.0", + * "id": "sk-msg-sign-1", + * "method": "message.sign", + * "params": { + * "onAccount": "ak_2RT9RPbcX8RtjBpMWqsKtVRVKASAbj8V4c3f7cCdJfuVdihhyL", + * "message": "MESSSSSSSSSSAGGGGGGGGGGGGGGGGGGGGGGGGGGGE" + * } + * } + * } + * ``` */ type EventData_A2W_msg_sign = EventData_A2W; @@ -1214,9 +1362,24 @@ type EventData_A2W_msg_sign /** - * Event data for aepp-to-waellet "message.sign" (do not propagate) response + * Event data for waellet-to-aepp "message.sign" * * (layer 2) + * + * @example + * ```json + * { + * "type": "to_aepp", + * "data": { + * "jsonrpc": "2.0", + * "id": "sk-msg-sign-1", + * "method": "message.sign", + * "result": { + * "signature": "3ec195484965a60dd4179fbb616947a85e4e9961cb468816a2a22870382954bc374f8569e4ddc729dfc1b14e09e670b7d2c70c33c592caca29ff6c212f1f8b0f" + * } + * } + * } + * ``` */ type EventData_W2A_msg_sign = EventData_W2A; diff --git a/libs/parasite/.gitignore b/libs/parasite/.gitignore index 6d324d9..50cb377 100644 --- a/libs/parasite/.gitignore +++ b/libs/parasite/.gitignore @@ -4,3 +4,4 @@ jex_mindist dist src/jex_include erl_crash.dump +docs diff --git a/libs/parasite/jex.eterms b/libs/parasite/jex.eterms index 1584815..9d84a44 100644 --- a/libs/parasite/jex.eterms +++ b/libs/parasite/jex.eterms @@ -1,5 +1,5 @@ {type, library}. {realm, local}. {name, parasite}. -{version, "0.1.0"}. +{version, "0.2.0"}. {deps, []}. diff --git a/libs/parasite/src/ae_node.ts b/libs/parasite/src/ae_node.ts index 932d540..5ecc783 100644 --- a/libs/parasite/src/ae_node.ts +++ b/libs/parasite/src/ae_node.ts @@ -26,8 +26,8 @@ import * as ae_compiler from './ae_compiler.js' export const MIN_FEE = 16660000000000; export const MIN_CONTRACT_FEE = 79080000000000; export const MIN_GAS_PRICE = 1000000000; -export const URL_MAINNET = "https://mainnet.aeternity.io/v2"; -export const URL_TESTNET = "https://testnet.aeternity.io/v2"; +export const URL_MAINNET = "https://mainnet.aeternity.io/v3"; +export const URL_TESTNET = "https://testnet.aeternity.io/v3"; //------------------------------------------------------------------- diff --git a/sidekick/examples/connection.html b/sidekick/examples/connection.html index 6b2dfd4..e48ad9e 100644 --- a/sidekick/examples/connection.html +++ b/sidekick/examples/connection.html @@ -70,6 +70,8 @@

5. Sign a message

+ +
diff --git a/sidekick/examples/jex.eterms b/sidekick/examples/jex.eterms index aca9cd7..45ff01a 100644 --- a/sidekick/examples/jex.eterms +++ b/sidekick/examples/jex.eterms @@ -2,6 +2,6 @@ {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"]}. +{deps, ["local-awcp-0.2.0", + "local-parasite-0.2.0", + "local-sidekick-0.2.0"]}. diff --git a/sidekick/examples/src/connection.ts b/sidekick/examples/src/connection.ts index 189c882..6dd3000 100644 --- a/sidekick/examples/src/connection.ts +++ b/sidekick/examples/src/connection.ts @@ -1,6 +1,6 @@ -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'; +import * as ae_node from './jex_include/local-parasite-0.2.0/dist/ae_node.js'; +import * as awcp from './jex_include/local-awcp-0.2.0/dist/awcp.js'; +import * as sk from './jex_include/local-sidekick-0.2.0/dist/sidekick.js'; var pv_address: string; var pv_spendtx_base64: string; @@ -197,10 +197,15 @@ sign_tx document.getElementById("sign-spendtx-result")!.innerHTML = JSON.stringify(signedTx, undefined, 4); } -async function sign_msg(logger: sk.Logger): Promise { - console.log('poop'); +async function +sign_msg + (logger: sk.Logger) + : Promise +{ let acc_pubkey : string = pv_address; - let signed_msg = await sk.msg_sign('sk-msg-sign-1', acc_pubkey, 'I make stinky poo poo', sk.TIMEOUT_DEF_TX_SIGN_NOPROP_MS, 'stinky poo poo too long', logger); + // @ts-ignore value property exists because i say so + let msg_text : string = document.getElementById('message-text').value; + let signed_msg = await sk.msg_sign('sk-msg-sign-1', acc_pubkey, msg_text, sk.TIMEOUT_DEF_MSG_SIGN_MS, 'message signing took too long', logger); console.log('signed message:', signed_msg); } diff --git a/sidekick/examples/src/hello.ts b/sidekick/examples/src/hello.ts index d833f41..a56669f 100644 --- a/sidekick/examples/src/hello.ts +++ b/sidekick/examples/src/hello.ts @@ -1,3 +1,3 @@ -import * as sk from './jex_include/local-sidekick-0.1.0/dist/sidekick.js'; +import * as sk from './jex_include/local-sidekick-0.2.0/dist/sidekick.js'; sk.hello(); diff --git a/sidekick/src/sidekick.ts b/sidekick/src/sidekick.ts index c61e586..d6c7fa9 100644 --- a/sidekick/src/sidekick.ts +++ b/sidekick/src/sidekick.ts @@ -44,6 +44,8 @@ export { unsafe, ok, error, + Ok, + Error, // timeout errors ERROR_CODE_SkTimeoutError, SkTimeoutError, @@ -69,6 +71,7 @@ export { TIMEOUT_DEF_CONNECT_MS, TIMEOUT_DEF_ADDRESS_MS, TIMEOUT_DEF_TX_SIGN_NOPROP_MS, + TIMEOUT_DEF_MSG_SIGN_MS, // API // detect detect, @@ -89,7 +92,7 @@ export { // IMPORTS //----------------------------------------------------------------------------- -import * as awcp from './jex_include/local-awcp-0.1.0/dist/awcp.js'; +import * as awcp from './jex_include/local-awcp-0.2.0/dist/awcp.js'; //----------------------------------------------------------------------------- @@ -97,20 +100,104 @@ import * as awcp from './jex_include/local-awcp-0.1.0/dist/awcp.js'; //----------------------------------------------------------------------------- /** - * Use for debugging/to check if import worked correctly + * Just `console.log`s `hello`. Use for debugging/to check if import worked correctly */ function hello () : void { - console.log('hællo'); + console.log('hello'); } /** - * Type that catches positive errors + * The idea behind this type is that some errors are known to be likely (e.g. + * the user rejects a transaction request, or something times out, etc). These + * errors (called "positive errors") should not generate exceptions. Exceptions + * should occur when exceptional behavior occurs (e.g. hardware faults, + * dividing by zero). Exceptions should not occur on events that are known to + * be likely. Instead, branching is the correct idiom. + * + * Furthermore, there are often many possible sources of errors. What this + * provides is a single "did it work or not" branch point. + * + * Further, in practice, all errors (either {@link SkTimeoutError} or {@link + * awcp.RpcError}) have a field called `code` which uniquely identifies the + * error, so it's easy to algorithmically respond to specific positive errors. + * For instance, if the user rejects a request in a popup, that is `code: 4` + * (see {@link awcp.ERROR_CODE_RpcRejectedByUserError}). If the user does not + * do anything within the timeout parameter you specify, that generates a + * {@link SkTimeoutError} which has `code: 420`. + * + * There are two branches: {@link Ok} and {@link Error} + * + * ```ts + * type Ok + * = {ok : true, + * result : ok_t}; + * + * type Error + * = {ok : false, + * error : err_t}; + * + * type Safe + * = Ok + * | Error; + * ``` + * + * @example + * Suppose you are trying to get the user's {@link address}. This pops up a + * confirmation dialog asking the user if he wants to connect to your + * application. There's a good chance the user says no. There's also a + * possibility he just doesn't do anything and things just time out. + * + * ```ts + * // there is a button in the document that when pressed triggers this function + * async function address(logger: sk.Logger): Promise + * { + * 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 + * 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); + * } + * } + * ``` + * + * The important part is the `if/else`. That branch point corresponds to "did + * it work or not?" The `else` branch corresponds to the subset of "not" that + * you know is likely: timeouts, rejections, etc. */ type Safe = Ok @@ -119,7 +206,25 @@ type Safe /** - * Ok type + * See {@link Safe} for context + * + * @example + * ```json + * { + * "ok": true, + * "result": { + * "type": "to_aepp", + * "data": { + * "jsonrpc": "2.0", + * "id": "sk-msg-sign-1", + * "method": "message.sign", + * "result": { + * "signature": "3ec195484965a60dd4179fbb616947a85e4e9961cb468816a2a22870382954bc374f8569e4ddc729dfc1b14e09e670b7d2c70c33c592caca29ff6c212f1f8b0f" + * } + * } + * } + * } + * ``` */ type Ok = {ok : true, @@ -128,7 +233,19 @@ type Ok /** - * Err type + * See {@link Safe} for context + * + * @example + * ```json + * { + * "ok": false, + * "error": { + * "code": 4, + * "data": {}, + * "message": "Operation rejected by user" + * } + * } + * ``` */ type Error = {ok : false, @@ -399,6 +516,14 @@ const TIMEOUT_DEF_ADDRESS_MS = 5*MIN; const TIMEOUT_DEF_TX_SIGN_NOPROP_MS = 5*MIN; +/** + * In the general case, this pops up the modal that requires the user to + * manually confirm, so is set to 5 minutes. This is an instance where you as + * the developer need to exercise some discretion. + */ +const TIMEOUT_DEF_MSG_SIGN_MS = 5*MIN; + + // Ah ok // // so for connection.announcePresence, we just listen and recieve, unwrap, send back @@ -421,41 +546,42 @@ const TIMEOUT_DEF_TX_SIGN_NOPROP_MS = 5*MIN; * * Wait for wallet to announce itself, and then return. * - * Example message data: + * @example + * ```ts + * // document has a button with id=detect + * // this is the function that is triggered when the button is clicked + * async function detect(logger: sk.Logger): Promise { + * let h4 = document.getElementById("detected")!; + * let pre = document.getElementById("detect-info")!; * - * ```json - * { - * "type": "to_aepp", - * "data": { - * "jsonrpc": "2.0", - * "method": "connection.announcePresence", - * "params": { - * "id": "{aee9e933-52b6-410a-8c3f-99c6be596b4e}", - * "name": "Superhero", - * "networkId": "ae_mainnet", - * "origin": "moz-extension://ee425d81-d5b2-44b6-9406-4da31b019e7c", - * "type": "extension" - * } + * 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 = + * 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); * } * } - * ``` * - * Example return data: - * - * ```json - * { - * "id": "{aee9e933-52b6-410a-8c3f-99c6be596b4e}", - * "name": "Superhero", - * "networkId": "ae_mainnet", - * "origin": "moz-extension://ee425d81-d5b2-44b6-9406-4da31b019e7c", - * "type": "extension" - * } - * ``` - * - * Example usage: - * - * ```typescript - * let wallet_info = await sk.detect(sk.TIMEOUT_DEF_DETECT_MS, "wallet timed out", sk.cl()); + * // want to create a logger down here + * let logger = sk.cl(); + * // detect button + * document.getElementById('detect')!.onclick = function() { detect(logger); } ; * ``` */ async function @@ -617,6 +743,58 @@ class CAPListener +/** + * Connect to the wallet. This is a necessary step if you want {@link address} + * to work. You **must** wait for Superhero to announce itself (see {@link + * detect}) before attempting to connect. This has the same return data as + * {@link detect}. This does not pop up the confirmation dialog for the user. + * Superhero never rejects the connection request. This call is instantaneous + * in practice. + * + * @example + * ```ts + * // document has a button with id=connect + * // this is the function that is triggered when the button is clicked + * // you want your user to do the detect sequence first + * async function connect (logger: sk.Logger) : Promise { + * 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 + * 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); + * } + * } + * + * let logger = sk.cl(); + * document.getElementById('connect')!.onclick = function() { connect(logger); }; + * ``` + */ async function connect (id : number | string, @@ -639,13 +817,16 @@ connect return result; } + + //----------------------------------------------------------------------------- // API: get address //----------------------------------------------------------------------------- - - +/** + * + */ async function address (id : number | string, @@ -669,12 +850,10 @@ address } + //----------------------------------------------------------------------------- // API: message sign //----------------------------------------------------------------------------- - - - async function msg_sign (id : number | string, @@ -683,9 +862,9 @@ msg_sign timeout_ms : number, timeout_msg : string, logger : Logger) - : Promise> + : Promise> { - logger.debug('address', {id:id, account_pubkey:account_pubkey, message:message, timeout_ms:timeout_ms, timeout_msg:timeout_msg}); + logger.debug('msg_sign', {id:id, account_pubkey:account_pubkey, message:message, timeout_ms:timeout_ms, timeout_msg:timeout_msg}); let msgr = new MsgR(logger); // FIXME: for type purposes, making the correct RPC message should be up here // this way we can enforce that it's a correct RPC call with typescript @@ -693,17 +872,16 @@ msg_sign // let result = await msgr.send_raseev(id, awcp.METHOD_CONNECTION_OPEN, params, target, timeout_ms, timeout_msg); let result = await msgr.send_raseev - + <"message.sign", awcp.Params_A2W_msg_sign, awcp.Result_W2A_msg_sign> (id, "message.sign", {onAccount: account_pubkey, message: message}, timeout_ms, timeout_msg); return result; } + + //----------------------------------------------------------------------------- // API: tx sign (no prop) //----------------------------------------------------------------------------- - - - async function tx_sign_noprop (id : number | string, diff --git a/utils/jex/src/jex.erl b/utils/jex/src/jex.erl index 3e5a492..48fab47 100644 --- a/utils/jex/src/jex.erl +++ b/utils/jex/src/jex.erl @@ -37,26 +37,31 @@ help() -> % TODONE: jex viewdocs PKG [port] % TODONE: jex fulldist % TODONE: jex install -% TODO: jex get_mindist PKG -% TODO: jex dwim++ = install -% TODO: --name option for docs +% TODONE: jex get_mindist PKG +% TODONE: jex dwim++ = install % TODO: use less than full qualified names (not priority) +% TODO: --name option for docs (not priority) % TODO: make fulldist for arbitrary installed package (requires storing jex.eterms, not hard but also not a priority) % TODO: be smart about creating jex_include % TODO: tarball shas % TODO: tarball signatures -% TODO: jex install help_screen() -> ["Jex: simple JavaScript packaging system\n" "\n" - "If you have never run jex before, you need to run `jex init` first\n" + "QUICK REFERENCE\n" + " You have a package tarball and want to install it ->\n" + " jex install foo-bar-X.Y.Z.tar.gz\n" + " You are in the current directory of a project and want to build it ->\n" + " jex install\n" + " There is a package installed and you need its mindist to put on a server or something ->\n" + " jex get_mindist foo-bar-X.Y.Z # must use fully qualified package name\n" "\n" "PORCELAIN COMMANDS:\n" - " dwim- build project but don't make a release (init, pull, build)\n" - " dwim+ build and make a minimal release (init, pull, build, mindist, push)\n" - " dwim++ build and make a full release (init, pull, build, mindist, push, mkdocs, pushdocs)\n" + " dwim- build project but don't make a release (init, clean, pull, build)\n" + " dwim+ build and make a minimal release (init, clean, pull, build, mindist, push)\n" + " dwim++ build and make a full release (init, clean, pull, build, mindist, push, mkdocs, pushdocs)\n" " install synonym for dwim++\n" " install [TARBALL_PATH] install the given package\n" " ls list installed packages\n" @@ -65,6 +70,7 @@ help_screen() -> "\n" "PLUMBING COMMANDS:\n" " init mkdir -p $HOME/.jex/{dev,docs,tmp}\n" + " clean rm -r ./src/jex_include && rm -r dist\n" " build tsc && cp -r ./src/jex_include ./dist/\n" " -w, --weak continue building even if tsc fails\n" " -f, --force use cp -rf instead of cp -r\n" @@ -111,6 +117,7 @@ dispatch(["viewdocs", Pkg, Port]) -> viewdocs(Pkg, Port); dispatch(["get_mindist", Pkg]) -> get_mindist(Pkg); %% plumbing dispatch(["init"]) -> init(); +dispatch(["clean"]) -> clean(); dispatch(["build" | Opts]) -> build(Opts); dispatch(["mindist" | Opts]) -> mindist(Opts); dispatch(["push"]) -> push(); @@ -158,6 +165,7 @@ man() -> dwim(minus) -> init(), + clean(), pull(), build([]); dwim(plus) -> @@ -641,6 +649,15 @@ get_mindist2(PkgName) -> ok. +%%----------------------------------------------------------------------------- +%% jex clean +%%----------------------------------------------------------------------------- + +clean() -> + _ = cmdf("rm -r ./src/jex_include", []), + _ = cmdf("rm -r ./dist", []), + ok. + %%----------------------------------------------------------------------------- %% INTERNALS